diff mbox

[6/8] migration, block: better select BDS for VM state loading

Message ID 1452770941-21582-7-git-send-email-den@openvz.org
State New
Headers show

Commit Message

Denis V. Lunev Jan. 14, 2016, 11:28 a.m. UTC
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 <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Juan Quintela <quintela@redhat.com>
CC: Amit Shah <amit.shah@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
CC: Eric Blake <eblake@redhat.com>
---
 block/snapshot.c         | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/block/snapshot.h |  1 +
 migration/savevm.c       | 33 ++------------------------
 3 files changed, 64 insertions(+), 31 deletions(-)

Comments

Denis V. Lunev May 7, 2016, 10:45 a.m. UTC | #1
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 <den@openvz.org>
> CC: Kevin Wolf <kwolf@redhat.com>
> CC: Juan Quintela <quintela@redhat.com>
> CC: Amit Shah <amit.shah@redhat.com>
> CC: Markus Armbruster <armbru@redhat.com>
> CC: Eric Blake <eblake@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...
diff mbox

Patch

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) {
         return -ENOTSUP;
     }
     aio_context = bdrv_get_aio_context(bs_vm_state);
 
-    /* Don't even try to load empty VM states */
-    aio_context_acquire(aio_context);
-    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);
-    aio_context_release(aio_context);
-    if (ret < 0) {
-        error_setg_errno(errp, -ret, "Snapshot '%s' not found", name);
-        return ret;
-    } else if (sn.vm_state_size == 0) {
-        error_setg(errp, "Snapshot '%s' is a disk-only snapshot and must be "
-                   "reverted offline using qemu-img", name);
-        return -EINVAL;
-    }
-
     /* Flush all IO requests so they don't interfere with the new state.  */
     bdrv_drain_all();