Skip to content

Commit

Permalink
snapshot: create bdrv_all_find_snapshot helper
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Denis V. Lunev authored and Juan Quintela committed Nov 19, 2015
1 parent 849f96e commit 723ccda
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 33 deletions.
20 changes: 20 additions & 0 deletions block/snapshot.c
Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions include/block/snapshot.h
Expand Up @@ -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
42 changes: 9 additions & 33 deletions migration/savevm.c
Expand Up @@ -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) {
Expand All @@ -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();

Expand Down Expand Up @@ -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;

Expand All @@ -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++;
}
Expand Down

0 comments on commit 723ccda

Please sign in to comment.