mirror of https://gitee.com/openkylin/qemu.git
snapshot: create bdrv_all_find_snapshot helper
to check that snapshot is available for all loaded block drivers. The check bs != bs1 in hmp_info_snapshots is an optimization. The check for availability of this snapshot will return always true as the list of snapshots was collected from that image. The patch also ensures proper locking. Signed-off-by: Denis V. Lunev <den@openvz.org> Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> CC: Stefan Hajnoczi <stefanha@redhat.com> CC: Kevin Wolf <kwolf@redhat.com> Tested-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
parent
849f96e2f7
commit
723ccda1a0
|
@ -423,3 +423,23 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
|
|||
*first_bad_bs = bs;
|
||||
return err;
|
||||
}
|
||||
|
||||
int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
|
||||
{
|
||||
QEMUSnapshotInfo sn;
|
||||
int err = 0;
|
||||
BlockDriverState *bs = NULL;
|
||||
|
||||
while (err == 0 && (bs = bdrv_next(bs))) {
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
if (bdrv_can_snapshot(bs)) {
|
||||
err = bdrv_snapshot_find(bs, &sn, name);
|
||||
}
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
*first_bad_bs = bs;
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -85,5 +85,6 @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs);
|
|||
int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bsd_bs,
|
||||
Error **err);
|
||||
int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bsd_bs);
|
||||
int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2056,6 +2056,12 @@ int load_vmstate(const char *name)
|
|||
bdrv_get_device_name(bs));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
ret = bdrv_all_find_snapshot(name, &bs);
|
||||
if (ret < 0) {
|
||||
error_report("Device '%s' does not have the requested snapshot '%s'",
|
||||
bdrv_get_device_name(bs), name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bs_vm_state = find_vmstate_bs();
|
||||
if (!bs_vm_state) {
|
||||
|
@ -2073,22 +2079,6 @@ int load_vmstate(const char *name)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Verify if there is any device that doesn't support snapshots and is
|
||||
writable and check if the requested snapshot is available too. */
|
||||
bs = NULL;
|
||||
while ((bs = bdrv_next(bs))) {
|
||||
if (!bdrv_can_snapshot(bs)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = bdrv_snapshot_find(bs, &sn, name);
|
||||
if (ret < 0) {
|
||||
error_report("Device '%s' does not have the requested snapshot '%s'",
|
||||
bdrv_get_device_name(bs), name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush all IO requests so they don't interfere with the new state. */
|
||||
bdrv_drain_all();
|
||||
|
||||
|
@ -2142,8 +2132,8 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
|
|||
void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockDriverState *bs, *bs1;
|
||||
QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
|
||||
int nb_sns, i, ret, available;
|
||||
QEMUSnapshotInfo *sn_tab, *sn;
|
||||
int nb_sns, i;
|
||||
int total;
|
||||
int *available_snapshots;
|
||||
|
||||
|
@ -2167,21 +2157,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||
available_snapshots = g_new0(int, nb_sns);
|
||||
total = 0;
|
||||
for (i = 0; i < nb_sns; i++) {
|
||||
sn = &sn_tab[i];
|
||||
available = 1;
|
||||
bs1 = NULL;
|
||||
|
||||
while ((bs1 = bdrv_next(bs1))) {
|
||||
if (bdrv_can_snapshot(bs1) && bs1 != bs) {
|
||||
ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
|
||||
if (ret < 0) {
|
||||
available = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (available) {
|
||||
if (bdrv_all_find_snapshot(sn_tab[i].id_str, &bs1) == 0) {
|
||||
available_snapshots[total] = i;
|
||||
total++;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue