Browse Source

block: Add option to create inactive nodes

In QEMU, nodes are automatically created inactive while expecting an
incoming migration (i.e. RUN_STATE_INMIGRATE). In qemu-storage-daemon,
the notion of runstates doesn't exist. It also wouldn't necessarily make
sense to introduce it because a single daemon can serve multiple VMs
that can be in different states.

Therefore, allow the user to explicitly open images as inactive with a
new option. The default is as before: Nodes are usually active, except
when created during RUN_STATE_INMIGRATE.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-8-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Kevin Wolf 6 months ago
parent
commit
faecd16fe5
3 changed files with 16 additions and 0 deletions
  1. 9 0
      block.c
  2. 1 0
      include/block/block-common.h
  3. 6 0
      qapi/block-core.json

+ 9 - 0
block.c

@@ -1573,6 +1573,10 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
     if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
     if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
         *flags |= BDRV_O_AUTO_RDONLY;
         *flags |= BDRV_O_AUTO_RDONLY;
     }
     }
+
+    if (!qemu_opt_get_bool_del(opts, BDRV_OPT_ACTIVE, true)) {
+        *flags |= BDRV_O_INACTIVE;
+    }
 }
 }
 
 
 static void update_options_from_flags(QDict *options, int flags)
 static void update_options_from_flags(QDict *options, int flags)
@@ -1799,6 +1803,11 @@ QemuOptsList bdrv_runtime_opts = {
             .type = QEMU_OPT_BOOL,
             .type = QEMU_OPT_BOOL,
             .help = "Ignore flush requests",
             .help = "Ignore flush requests",
         },
         },
+        {
+            .name = BDRV_OPT_ACTIVE,
+            .type = QEMU_OPT_BOOL,
+            .help = "Node is activated",
+        },
         {
         {
             .name = BDRV_OPT_READ_ONLY,
             .name = BDRV_OPT_READ_ONLY,
             .type = QEMU_OPT_BOOL,
             .type = QEMU_OPT_BOOL,

+ 1 - 0
include/block/block-common.h

@@ -257,6 +257,7 @@ typedef enum {
 #define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
 #define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
 #define BDRV_OPT_DISCARD        "discard"
 #define BDRV_OPT_DISCARD        "discard"
 #define BDRV_OPT_FORCE_SHARE    "force-share"
 #define BDRV_OPT_FORCE_SHARE    "force-share"
+#define BDRV_OPT_ACTIVE         "active"
 
 
 
 
 #define BDRV_SECTOR_BITS   9
 #define BDRV_SECTOR_BITS   9

+ 6 - 0
qapi/block-core.json

@@ -4683,6 +4683,11 @@
 #
 #
 # @cache: cache-related options
 # @cache: cache-related options
 #
 #
+# @active: whether the block node should be activated (default: true).
+#     Having inactive block nodes is useful primarily for migration because it
+#     allows opening an image on the destination while the source is still
+#     holding locks for it. (Since 10.0)
+#
 # @read-only: whether the block device should be read-only (default:
 # @read-only: whether the block device should be read-only (default:
 #     false).  Note that some block drivers support only read-only
 #     false).  Note that some block drivers support only read-only
 #     access, either generally or in certain configurations.  In this
 #     access, either generally or in certain configurations.  In this
@@ -4709,6 +4714,7 @@
             '*node-name': 'str',
             '*node-name': 'str',
             '*discard': 'BlockdevDiscardOptions',
             '*discard': 'BlockdevDiscardOptions',
             '*cache': 'BlockdevCacheOptions',
             '*cache': 'BlockdevCacheOptions',
+            '*active': 'bool',
             '*read-only': 'bool',
             '*read-only': 'bool',
             '*auto-read-only': 'bool',
             '*auto-read-only': 'bool',
             '*force-share': 'bool',
             '*force-share': 'bool',