On 01/14/2016 02:28 PM, Denis V. Lunev wrote:
This patch does 2 things:
- it merges all snapshot validity checks for load_vmstate into one function
- it now selects BDS to load VM state by availability of the state in the
snapshot
This commit is preparatory to allow to select BDS to save snapshot for QMP.
Signed-off-by: Denis V. Lunev <d...@openvz.org>
CC: Kevin Wolf <kw...@redhat.com>
CC: Juan Quintela <quint...@redhat.com>
CC: Amit Shah <amit.s...@redhat.com>
CC: Markus Armbruster <arm...@redhat.com>
CC: Eric Blake <ebl...@redhat.com>
---
block/snapshot.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
include/block/snapshot.h | 1 +
migration/savevm.c | 33 ++------------------------
3 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/block/snapshot.c b/block/snapshot.c
index 2d86b88..77affbc 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -489,3 +489,64 @@ BlockDriverState *bdrv_all_find_vmstate_bs(void)
}
return bs;
}
+
+
+static bool validate_bs(BlockDriverState *bs, BlockDriverState **vmstate_bs,
+ const char *name, Error **errp)
+{
+ QEMUSnapshotInfo sn;
+
+ if (!bdrv_can_snapshot(bs)) {
+ if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
+ return true;
+ }
+ error_setg(errp,
+ "Device '%s' is writable but does not support snapshots",
+ bdrv_get_device_name(bs));
+ return false;
+ }
+
+ if (bdrv_snapshot_find(bs, &sn, name) < 0) {
+ error_setg(errp,
+ "Device '%s' does not have the requested snapshot '%s'",
+ bdrv_get_device_name(bs), name);
+ return false;
+ }
+
+ if (sn.vm_state_size == 0) {
+ return true;
+ }
+ if (*vmstate_bs != NULL) {
+ error_setg(errp, "Devices '%s' and '%s' both has vmstate with the "
+ "requested snapshot '%s'", bdrv_get_device_name(bs),
+ bdrv_get_device_name(*vmstate_bs), name);
+ return false;
+ }
+ *vmstate_bs = bs;
+
+ return true;
+}
+
+BlockDriverState *bdrv_all_validate_snapshot(const char *name, Error **errp)
+{
+ BlockDriverState *bs = NULL;
+ BlockDriverState *vmstate_bs = NULL;
+
+ while ((bs = bdrv_next(bs))) {
+ AioContext *ctx = bdrv_get_aio_context(bs);
+ bool ok;
+
+ aio_context_acquire(ctx);
+ ok = validate_bs(bs, &vmstate_bs, name, errp);
+ aio_context_release(ctx);
+
+ if (!ok) {
+ return NULL;
+ }
+ }
+
+ if (vmstate_bs == NULL) {
+ error_setg(errp, "VM state for the snapshot '%s' not found", name);
+ }
+ return vmstate_bs;
+}
diff --git a/include/block/snapshot.h b/include/block/snapshot.h
index c6910da6..a8506e9 100644
--- a/include/block/snapshot.h
+++ b/include/block/snapshot.h
@@ -92,5 +92,6 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
BlockDriverState **first_bad_bs);
BlockDriverState *bdrv_all_find_vmstate_bs(void);
+BlockDriverState *bdrv_all_validate_snapshot(const char *name, Error **errp);
#endif
diff --git a/migration/savevm.c b/migration/savevm.c
index 6b34017..fed8664 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2022,45 +2022,16 @@ void qmp_xen_save_devices_state(const char *filename,
Error **errp)
int load_vmstate(const char *name, Error **errp)
{
BlockDriverState *bs, *bs_vm_state;
- QEMUSnapshotInfo sn;
QEMUFile *f;
int ret;
AioContext *aio_context;
- if (!bdrv_all_can_snapshot(&bs)) {
- error_setg(errp,
- "Device '%s' is writable but does not support snapshots",
- bdrv_get_device_name(bs));
- return -ENOTSUP;
- }
- ret = bdrv_all_find_snapshot(name, &bs);
- if (ret < 0) {
- error_setg(errp,
- "Device '%s' does not have the requested snapshot '%s'",
- bdrv_get_device_name(bs), name);
- return ret;
- }
-
- bs_vm_state = bdrv_all_find_vmstate_bs();
- if (!bs_vm_state) {
- error_setg(errp, "No block device supports snapshots");
+ bs_vm_state = bdrv_all_validate_snapshot(name, errp);
+ if (bs == NULL) {
we should have bs_vm_state here checked...