qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/1] Allow passing BlockdevOptions to blockdev-snapshot-sync
@ 2015-08-31 10:00 Alberto Garcia
  2015-08-31 10:00 ` [Qemu-devel] [PATCH 1/1] block: " Alberto Garcia
  0 siblings, 1 reply; 12+ messages in thread
From: Alberto Garcia @ 2015-08-31 10:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Alberto Garcia, Stefan Hajnoczi, qemu-block,
	Max Reitz

Here's my first attempt to solve the problem explained here:

   https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02847.html

In short: there's no way to pass options to snapshots created using
blockdev-snapshot-sync.

This patch simply allows passing a BlockdevOptions structure to that
command. I'm not 100% happy with the API because there's some overlap
with a couple of parameters, but it's the simplest I could think of.

This need to be applied on top of this series from Max Reitz:

   https://lists.gnu.org/archive/html/qemu-block/2015-08/msg00189.html

Regards,

Berto

Alberto Garcia (1):
  block: Allow passing BlockdevOptions to blockdev-snapshot-sync

 blockdev.c           | 59 ++++++++++++++++++++++++++++++++++++++++++++++------
 hmp.c                |  2 +-
 qapi/block-core.json |  9 +++++++-
 qmp-commands.hx      |  3 ++-
 4 files changed, 64 insertions(+), 9 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-08-31 10:00 [Qemu-devel] [PATCH 0/1] Allow passing BlockdevOptions to blockdev-snapshot-sync Alberto Garcia
@ 2015-08-31 10:00 ` Alberto Garcia
  2015-08-31 19:53   ` Max Reitz
  0 siblings, 1 reply; 12+ messages in thread
From: Alberto Garcia @ 2015-08-31 10:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Alberto Garcia, Stefan Hajnoczi, qemu-block,
	Max Reitz

Snapshots created using blockdev-snapshot-sync are currently opened
using their default options, not even inheriting those from the images
they are based on.

This patch extends the command by adding an 'options' parameter that
takes a BlockdevOptions structure. Since some of the options that can
be specified overlap with the parameters of blockdev-snapshot-sync,
the following checks are made:

- The 'driver' field must match the format specified for the snapshot.
- The 'node-name' field and the 'snapshot-node-name' parameters cannot
  be specified at the same time.
- The 'file' field can only contain an empty string, since it overlaps
  with the 'snapshot-file' parameter.

Signed-off-by: Alberto Garcia <berto@igalia.com>
---
 blockdev.c           | 59 ++++++++++++++++++++++++++++++++++++++++++++++------
 hmp.c                |  2 +-
 qapi/block-core.json |  9 +++++++-
 qmp-commands.hx      |  3 ++-
 4 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 4a1fc2e..7e904f3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1070,7 +1070,9 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device,
                                 bool has_snapshot_node_name,
                                 const char *snapshot_node_name,
                                 bool has_format, const char *format,
-                                bool has_mode, NewImageMode mode, Error **errp)
+                                bool has_mode, NewImageMode mode,
+                                bool has_options, BlockdevOptions *options,
+                                Error **errp)
 {
     BlockdevSnapshot snapshot = {
         .has_device = has_device,
@@ -1084,6 +1086,8 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device,
         .format = (char *) format,
         .has_mode = has_mode,
         .mode = mode,
+        .has_options = has_options,
+        .options = options,
     };
     blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
                        &snapshot, errp);
@@ -1504,6 +1508,48 @@ static void external_snapshot_prepare(BlkTransactionState *common,
 
     flags = state->old_bs->open_flags;
 
+    if (action->blockdev_snapshot_sync->has_options) {
+        QObject *obj;
+        QmpOutputVisitor *ov = qmp_output_visitor_new();
+        visit_type_BlockdevOptions(qmp_output_get_visitor(ov),
+                                   &action->blockdev_snapshot_sync->options,
+                                   NULL, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            qmp_output_visitor_cleanup(ov);
+            return;
+        }
+
+        obj = qmp_output_get_qobject(ov);
+        options = qobject_to_qdict(obj);
+        qmp_output_visitor_cleanup(ov);
+
+        if (strcmp(format, qdict_get_str(options, "driver"))) {
+            error_setg(errp, "Can't specify two different image formats");
+            goto fail;
+        }
+
+        if (has_snapshot_node_name && qdict_haskey(options, "node-name")) {
+            error_setg(errp, "Can't specify a node name twice");
+            goto fail;
+        }
+
+        obj = qdict_get(options, "file");
+        if (obj != NULL) {
+            QString *str = qobject_to_qstring(obj);
+            if (!str || strcmp(qstring_get_str(str), "")) {
+                error_setg(errp, "The 'file' field must be empty");
+                goto fail;
+            }
+            qdict_del(options, "file");
+        }
+
+        qdict_flatten(options);
+    } else {
+        options = qdict_new();
+        qdict_put(options, "driver", qstring_from_str(format));
+    }
+
     /* create new image w/backing file */
     if (mode != NEW_IMAGE_MODE_EXISTING) {
         bdrv_img_create(new_image_file, format,
@@ -1512,19 +1558,15 @@ static void external_snapshot_prepare(BlkTransactionState *common,
                         NULL, -1, flags, &local_err, false);
         if (local_err) {
             error_propagate(errp, local_err);
-            return;
+            goto fail;
         }
     }
 
-    options = qdict_new();
     if (has_snapshot_node_name) {
         qdict_put(options, "node-name",
                   qstring_from_str(snapshot_node_name));
     }
-    qdict_put(options, "driver", qstring_from_str(format));
 
-    /* TODO Inherit bs->options or only take explicit options with an
-     * extended QMP command? */
     assert(state->new_bs == NULL);
     ret = bdrv_open(&state->new_bs, new_image_file, NULL, options,
                     flags | BDRV_O_NO_BACKING, &local_err);
@@ -1532,6 +1574,11 @@ static void external_snapshot_prepare(BlkTransactionState *common,
     if (ret != 0) {
         error_propagate(errp, local_err);
     }
+
+    return;
+
+fail:
+    QDECREF(options);
 }
 
 static void external_snapshot_commit(BlkTransactionState *common)
diff --git a/hmp.c b/hmp.c
index dcc66f1..180a7f6 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1115,7 +1115,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
     qmp_blockdev_snapshot_sync(true, device, false, NULL,
                                filename, false, NULL,
                                !!format, format,
-                               true, mode, &err);
+                               true, mode, false, NULL, &err);
     hmp_handle_error(mon, &err);
 }
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 7b2efb8..5eb111e 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -697,11 +697,18 @@
 #
 # @mode: #optional whether and how QEMU should create a new image, default is
 #        'absolute-paths'.
+#
+# @options: #optional options for the new device, with the following
+#           restrictions for the fields: 'driver' must match the value
+#           of @format, 'node-name' and @snapshot-node-name cannot be
+#           specified at the same time, and 'file' can only contain an
+#           empty string (Since 2.5)
 ##
 { 'struct': 'BlockdevSnapshot',
   'data': { '*device': 'str', '*node-name': 'str',
             'snapshot-file': 'str', '*snapshot-node-name': 'str',
-            '*format': 'str', '*mode': 'NewImageMode' } }
+            '*format': 'str', '*mode': 'NewImageMode',
+            '*options': 'BlockdevOptions' } }
 
 ##
 # @DriveBackup
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ba630b1..bf45e31 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1394,7 +1394,7 @@ EQMP
 
     {
         .name       = "blockdev-snapshot-sync",
-        .args_type  = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
+        .args_type  = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?,options:q?",
         .mhandler.cmd_new = qmp_marshal_input_blockdev_snapshot_sync,
     },
 
@@ -1417,6 +1417,7 @@ Arguments:
 - "mode": whether and how QEMU should create the snapshot file
   (NewImageMode, optional, default "absolute-paths")
 - "format": format of new image (json-string, optional)
+- "options": options for the new image (json-dict)
 
 Example:
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-08-31 10:00 ` [Qemu-devel] [PATCH 1/1] block: " Alberto Garcia
@ 2015-08-31 19:53   ` Max Reitz
  2015-08-31 20:05     ` Eric Blake
  0 siblings, 1 reply; 12+ messages in thread
From: Max Reitz @ 2015-08-31 19:53 UTC (permalink / raw)
  To: Alberto Garcia, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, qemu-block

[-- Attachment #1: Type: text/plain, Size: 8695 bytes --]

On 31.08.2015 12:00, Alberto Garcia wrote:
> Snapshots created using blockdev-snapshot-sync are currently opened
> using their default options, not even inheriting those from the images
> they are based on.
> 
> This patch extends the command by adding an 'options' parameter that
> takes a BlockdevOptions structure. Since some of the options that can
> be specified overlap with the parameters of blockdev-snapshot-sync,
> the following checks are made:
> 
> - The 'driver' field must match the format specified for the snapshot.
> - The 'node-name' field and the 'snapshot-node-name' parameters cannot
>   be specified at the same time.
> - The 'file' field can only contain an empty string, since it overlaps
>   with the 'snapshot-file' parameter.
> 
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> ---
>  blockdev.c           | 59 ++++++++++++++++++++++++++++++++++++++++++++++------
>  hmp.c                |  2 +-
>  qapi/block-core.json |  9 +++++++-
>  qmp-commands.hx      |  3 ++-
>  4 files changed, 64 insertions(+), 9 deletions(-)

Design question: Would it make sense to instead add a "reference" mode
to blockdev-snapshot-sync where you can specify a BDS's node-name
instead of snapshot-file to use an existing BDS as the new top layer,
ideally an empty one?

What we'd then need is a QMP command for creating images. But as far as
I know we'll need that anyway sooner or later...


Comments on the patch itself below.

> diff --git a/blockdev.c b/blockdev.c
> index 4a1fc2e..7e904f3 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1070,7 +1070,9 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device,
>                                  bool has_snapshot_node_name,
>                                  const char *snapshot_node_name,
>                                  bool has_format, const char *format,
> -                                bool has_mode, NewImageMode mode, Error **errp)
> +                                bool has_mode, NewImageMode mode,
> +                                bool has_options, BlockdevOptions *options,
> +                                Error **errp)
>  {
>      BlockdevSnapshot snapshot = {
>          .has_device = has_device,
> @@ -1084,6 +1086,8 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device,
>          .format = (char *) format,
>          .has_mode = has_mode,
>          .mode = mode,
> +        .has_options = has_options,
> +        .options = options,
>      };
>      blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
>                         &snapshot, errp);
> @@ -1504,6 +1508,48 @@ static void external_snapshot_prepare(BlkTransactionState *common,
>  
>      flags = state->old_bs->open_flags;
>  
> +    if (action->blockdev_snapshot_sync->has_options) {
> +        QObject *obj;
> +        QmpOutputVisitor *ov = qmp_output_visitor_new();
> +        visit_type_BlockdevOptions(qmp_output_get_visitor(ov),
> +                                   &action->blockdev_snapshot_sync->options,
> +                                   NULL, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            qmp_output_visitor_cleanup(ov);
> +            return;
> +        }
> +
> +        obj = qmp_output_get_qobject(ov);
> +        options = qobject_to_qdict(obj);
> +        qmp_output_visitor_cleanup(ov);
> +
> +        if (strcmp(format, qdict_get_str(options, "driver"))) {

With has_format == false, format will be set to "qcow2" by default. So,
if the user does not specify the format explicitly, the "driver" field
has to be set to "qcow2".

I'd rather make specifying @format and @options exclusive, and if
@options has been specified, its "driver" field should override the
"format" default.

> +            error_setg(errp, "Can't specify two different image formats");
> +            goto fail;
> +        }
> +
> +        if (has_snapshot_node_name && qdict_haskey(options, "node-name")) {
> +            error_setg(errp, "Can't specify a node name twice");
> +            goto fail;
> +        }
> +
> +        obj = qdict_get(options, "file");
> +        if (obj != NULL) {
> +            QString *str = qobject_to_qstring(obj);
> +            if (!str || strcmp(qstring_get_str(str), "")) {
> +                error_setg(errp, "The 'file' field must be empty");
> +                goto fail;
> +            }
> +            qdict_del(options, "file");
> +        }

And the "backing" field must be NULL.

> +
> +        qdict_flatten(options);
> +    } else {
> +        options = qdict_new();
> +        qdict_put(options, "driver", qstring_from_str(format));
> +    }
> +
>      /* create new image w/backing file */
>      if (mode != NEW_IMAGE_MODE_EXISTING) {
>          bdrv_img_create(new_image_file, format,
> @@ -1512,19 +1558,15 @@ static void external_snapshot_prepare(BlkTransactionState *common,
>                          NULL, -1, flags, &local_err, false);
>          if (local_err) {
>              error_propagate(errp, local_err);
> -            return;
> +            goto fail;
>          }
>      }
>  
> -    options = qdict_new();
>      if (has_snapshot_node_name) {
>          qdict_put(options, "node-name",
>                    qstring_from_str(snapshot_node_name));
>      }
> -    qdict_put(options, "driver", qstring_from_str(format));
>  
> -    /* TODO Inherit bs->options or only take explicit options with an
> -     * extended QMP command? */
>      assert(state->new_bs == NULL);
>      ret = bdrv_open(&state->new_bs, new_image_file, NULL, options,
>                      flags | BDRV_O_NO_BACKING, &local_err);
> @@ -1532,6 +1574,11 @@ static void external_snapshot_prepare(BlkTransactionState *common,
>      if (ret != 0) {
>          error_propagate(errp, local_err);
>      }
> +
> +    return;
> +
> +fail:
> +    QDECREF(options);
>  }
>  
>  static void external_snapshot_commit(BlkTransactionState *common)
> diff --git a/hmp.c b/hmp.c
> index dcc66f1..180a7f6 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1115,7 +1115,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
>      qmp_blockdev_snapshot_sync(true, device, false, NULL,
>                                 filename, false, NULL,
>                                 !!format, format,
> -                               true, mode, &err);
> +                               true, mode, false, NULL, &err);
>      hmp_handle_error(mon, &err);
>  }
>  
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 7b2efb8..5eb111e 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -697,11 +697,18 @@
>  #
>  # @mode: #optional whether and how QEMU should create a new image, default is
>  #        'absolute-paths'.
> +#
> +# @options: #optional options for the new device, with the following
> +#           restrictions for the fields: 'driver' must match the value
> +#           of @format,

As said above, I'd rather make specifying both @options and @format
exclusive.

Maybe there is even some QAPI magic to enforce that (and for
'node-name', too), I don't know...

Max

>                          'node-name' and @snapshot-node-name cannot be
> +#           specified at the same time, and 'file' can only contain an
> +#           empty string (Since 2.5)
>  ##
>  { 'struct': 'BlockdevSnapshot',
>    'data': { '*device': 'str', '*node-name': 'str',
>              'snapshot-file': 'str', '*snapshot-node-name': 'str',
> -            '*format': 'str', '*mode': 'NewImageMode' } }
> +            '*format': 'str', '*mode': 'NewImageMode',
> +            '*options': 'BlockdevOptions' } }
>  
>  ##
>  # @DriveBackup
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index ba630b1..bf45e31 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -1394,7 +1394,7 @@ EQMP
>  
>      {
>          .name       = "blockdev-snapshot-sync",
> -        .args_type  = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
> +        .args_type  = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?,options:q?",
>          .mhandler.cmd_new = qmp_marshal_input_blockdev_snapshot_sync,
>      },
>  
> @@ -1417,6 +1417,7 @@ Arguments:
>  - "mode": whether and how QEMU should create the snapshot file
>    (NewImageMode, optional, default "absolute-paths")
>  - "format": format of new image (json-string, optional)
> +- "options": options for the new image (json-dict)
>  
>  Example:
>  
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-08-31 19:53   ` Max Reitz
@ 2015-08-31 20:05     ` Eric Blake
  2015-08-31 20:12       ` Max Reitz
  2015-09-01 11:31       ` Kevin Wolf
  0 siblings, 2 replies; 12+ messages in thread
From: Eric Blake @ 2015-08-31 20:05 UTC (permalink / raw)
  To: Max Reitz, Alberto Garcia, qemu-devel
  Cc: Kevin Wolf, qemu-block, Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 3255 bytes --]

On 08/31/2015 01:53 PM, Max Reitz wrote:

> Design question: Would it make sense to instead add a "reference" mode
> to blockdev-snapshot-sync where you can specify a BDS's node-name
> instead of snapshot-file to use an existing BDS as the new top layer,
> ideally an empty one?

Indeed - then blockdev-add can be used to create an unattached BDS (with
all appropriate options), and blockdev-snapshot-sync would then attach
that BDS as the snapshot-file that wraps an existing BDS (without
needing to worry about options).

> 
> What we'd then need is a QMP command for creating images. But as far as
> I know we'll need that anyway sooner or later...

Can't blockdev-add already be used for that (at least, for supported
file types)? If not, what would it take to get it there?

> 
> 
> Comments on the patch itself below.
> 

> 
> With has_format == false, format will be set to "qcow2" by default. So,
> if the user does not specify the format explicitly, the "driver" field
> has to be set to "qcow2".
> 
> I'd rather make specifying @format and @options exclusive, and if
> @options has been specified, its "driver" field should override the
> "format" default.
> 

>> +++ b/qapi/block-core.json
>> @@ -697,11 +697,18 @@
>>  #
>>  # @mode: #optional whether and how QEMU should create a new image, default is
>>  #        'absolute-paths'.
>> +#
>> +# @options: #optional options for the new device, with the following
>> +#           restrictions for the fields: 'driver' must match the value
>> +#           of @format,
> 
> As said above, I'd rather make specifying both @options and @format
> exclusive.
> 
> Maybe there is even some QAPI magic to enforce that (and for
> 'node-name', too), I don't know...

Not that I know of at the moment, but not to say we can't add some.  The
closest we can get is with a flat union, but that requires a
non-optional discriminator field.  Maybe we can tweak qapi to make the
discriminator optional (with a default value).  Thankfully, it sounds
like Markus' work on introspection would at least let management apps
learn about a new 'options' argument.

>>                          'node-name' and @snapshot-node-name cannot be
>> +#           specified at the same time, and 'file' can only contain an
>> +#           empty string (Since 2.5)

I really don't like the idea of requiring the user to pass in an empty
string. Can we make the field optional instead, and require it to be
omitted in the context where it would otherwise need to be empty, while
still requiring it to be present in existing clients that weren't
prepared for it to be optional?  It also feels a bit ad hoc that you
describe that driver/format must be identical, but that other fields
must be mutually exclusive or the empty string; consistency would argue
that since you already handle duplication of driver/format by requiring
them to be the same, that you should also allow duplication and
validation of identical other fields that overlap.  (But even better
would be finding a way to not allow overlapping fields to appear in the
first place).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-08-31 20:05     ` Eric Blake
@ 2015-08-31 20:12       ` Max Reitz
  2015-09-01 11:33         ` Kevin Wolf
  2015-09-01 11:31       ` Kevin Wolf
  1 sibling, 1 reply; 12+ messages in thread
From: Max Reitz @ 2015-08-31 20:12 UTC (permalink / raw)
  To: Eric Blake, Alberto Garcia, qemu-devel
  Cc: Kevin Wolf, qemu-block, Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 1403 bytes --]

On 31.08.2015 22:05, Eric Blake wrote:
> On 08/31/2015 01:53 PM, Max Reitz wrote:
> 
>> Design question: Would it make sense to instead add a "reference" mode
>> to blockdev-snapshot-sync where you can specify a BDS's node-name
>> instead of snapshot-file to use an existing BDS as the new top layer,
>> ideally an empty one?
> 
> Indeed - then blockdev-add can be used to create an unattached BDS (with
> all appropriate options), and blockdev-snapshot-sync would then attach
> that BDS as the snapshot-file that wraps an existing BDS (without
> needing to worry about options).
> 
>>
>> What we'd then need is a QMP command for creating images. But as far as
>> I know we'll need that anyway sooner or later...
> 
> Can't blockdev-add already be used for that (at least, for supported
> file types)? If not, what would it take to get it there?

It would take a blockdev-create-image QMP command. :-)

blockdev-add only opens existing images, blockdev-create-image would
then create these so they can be opened using blockdev-add.

Similar to blockdev-add, it would probably have a single parameter, but
it'd be of a different type, called e.g. BlockdevCreateOptions, since it
has to reflect the creation options instead of the runtime options for
opening existing images. For instance, for qcow2 you could set the
refcount-bits value, but not the L2 cache size.

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-08-31 20:05     ` Eric Blake
  2015-08-31 20:12       ` Max Reitz
@ 2015-09-01 11:31       ` Kevin Wolf
  2015-09-01 14:22         ` Alberto Garcia
  1 sibling, 1 reply; 12+ messages in thread
From: Kevin Wolf @ 2015-09-01 11:31 UTC (permalink / raw)
  To: Eric Blake
  Cc: qemu-block, Alberto Garcia, qemu-devel, Stefan Hajnoczi,
	Max Reitz

[-- Attachment #1: Type: text/plain, Size: 2152 bytes --]

Am 31.08.2015 um 22:05 hat Eric Blake geschrieben:
> On 08/31/2015 01:53 PM, Max Reitz wrote:
> 
> > Design question: Would it make sense to instead add a "reference" mode
> > to blockdev-snapshot-sync where you can specify a BDS's node-name
> > instead of snapshot-file to use an existing BDS as the new top layer,
> > ideally an empty one?
> 
> Indeed - then blockdev-add can be used to create an unattached BDS (with
> all appropriate options), and blockdev-snapshot-sync would then attach
> that BDS as the snapshot-file that wraps an existing BDS (without
> needing to worry about options).

Yes, this is what we should do.

The existing blockdev-snapshot-sync should really have been called
something like drive-snapshot, it doesn't belong in the blockdev-*
family of commands which works only with existing nodes.

> >> +++ b/qapi/block-core.json
> >> @@ -697,11 +697,18 @@
> >>  #
> >>  # @mode: #optional whether and how QEMU should create a new image, default is
> >>  #        'absolute-paths'.
> >> +#
> >> +# @options: #optional options for the new device, with the following
> >> +#           restrictions for the fields: 'driver' must match the value
> >> +#           of @format,
> > 
> > As said above, I'd rather make specifying both @options and @format
> > exclusive.
> > 
> > Maybe there is even some QAPI magic to enforce that (and for
> > 'node-name', too), I don't know...
> 
> Not that I know of at the moment, but not to say we can't add some.  The
> closest we can get is with a flat union, but that requires a
> non-optional discriminator field.  Maybe we can tweak qapi to make the
> discriminator optional (with a default value).  Thankfully, it sounds
> like Markus' work on introspection would at least let management apps
> learn about a new 'options' argument.

Let's avoid such magic and instead add a new, clean blockdev-* style
command. Maybe call it simply blockdev-snapshot; the -sync part was
added because we knew it wouldn't be the final version of the command.
Now we don't have any bdrv_open() in it any more that could by
synchronous or asynchronous.

Kevin

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-08-31 20:12       ` Max Reitz
@ 2015-09-01 11:33         ` Kevin Wolf
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Wolf @ 2015-09-01 11:33 UTC (permalink / raw)
  To: Max Reitz; +Cc: Alberto Garcia, qemu-block, qemu-devel, Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 1769 bytes --]

Am 31.08.2015 um 22:12 hat Max Reitz geschrieben:
> On 31.08.2015 22:05, Eric Blake wrote:
> > On 08/31/2015 01:53 PM, Max Reitz wrote:
> > 
> >> Design question: Would it make sense to instead add a "reference" mode
> >> to blockdev-snapshot-sync where you can specify a BDS's node-name
> >> instead of snapshot-file to use an existing BDS as the new top layer,
> >> ideally an empty one?
> > 
> > Indeed - then blockdev-add can be used to create an unattached BDS (with
> > all appropriate options), and blockdev-snapshot-sync would then attach
> > that BDS as the snapshot-file that wraps an existing BDS (without
> > needing to worry about options).
> > 
> >>
> >> What we'd then need is a QMP command for creating images. But as far as
> >> I know we'll need that anyway sooner or later...
> > 
> > Can't blockdev-add already be used for that (at least, for supported
> > file types)? If not, what would it take to get it there?
> 
> It would take a blockdev-create-image QMP command. :-)
> 
> blockdev-add only opens existing images, blockdev-create-image would
> then create these so they can be opened using blockdev-add.
> 
> Similar to blockdev-add, it would probably have a single parameter, but
> it'd be of a different type, called e.g. BlockdevCreateOptions, since it
> has to reflect the creation options instead of the runtime options for
> opening existing images. For instance, for qcow2 you could set the
> refcount-bits value, but not the L2 cache size.

Would be nice to have (especially because we would get a schema of the
create options), but not absolutely necessary for a blockdev-* style
snapshotting command. libvirt seems to cope just fine with calling
qemu-img before going to the QMP monitor.

Kevin

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-09-01 11:31       ` Kevin Wolf
@ 2015-09-01 14:22         ` Alberto Garcia
  2015-09-01 14:40           ` Kevin Wolf
  0 siblings, 1 reply; 12+ messages in thread
From: Alberto Garcia @ 2015-09-01 14:22 UTC (permalink / raw)
  To: Kevin Wolf, Eric Blake; +Cc: qemu-block, qemu-devel, Stefan Hajnoczi, Max Reitz

On Tue 01 Sep 2015 01:31:11 PM CEST, Kevin Wolf <kwolf@redhat.com> wrote:

>> > Design question: Would it make sense to instead add a "reference"
>> > mode to blockdev-snapshot-sync where you can specify a BDS's
>> > node-name instead of snapshot-file to use an existing BDS as the
>> > new top layer, ideally an empty one?
>> 
>> Indeed - then blockdev-add can be used to create an unattached BDS
>> (with all appropriate options), and blockdev-snapshot-sync would then
>> attach that BDS as the snapshot-file that wraps an existing BDS
>> (without needing to worry about options).
>
> Yes, this is what we should do.

Sounds like a good idea, thanks for the feedback !

>> >> +# @options: #optional options for the new device, with the following
>> >> +#           restrictions for the fields: 'driver' must match the value
>> >> +#           of @format,
>> > 
>> > As said above, I'd rather make specifying both @options and @format
>> > exclusive.
>> > 
>> > Maybe there is even some QAPI magic to enforce that (and for
>> > 'node-name', too), I don't know...
>> 
>> Not that I know of at the moment, but not to say we can't add some.  The
>> closest we can get is with a flat union, but that requires a
>> non-optional discriminator field.  Maybe we can tweak qapi to make the
>> discriminator optional (with a default value).  Thankfully, it sounds
>> like Markus' work on introspection would at least let management apps
>> learn about a new 'options' argument.

This is not necessary if we go for the "reference" mode proposed by
Markus, since the "options" parameter would disappear.

> Let's avoid such magic and instead add a new, clean blockdev-* style
> command. Maybe call it simply blockdev-snapshot; the -sync part was
> added because we knew it wouldn't be the final version of the command.
> Now we don't have any bdrv_open() in it any more that could by
> synchronous or asynchronous.

Would you then prefer me to create a new command instead of extending
the existing one? What would be the benefit (other than a better name)?

Berto

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-09-01 14:22         ` Alberto Garcia
@ 2015-09-01 14:40           ` Kevin Wolf
  2015-09-02  7:04             ` Markus Armbruster
  2015-09-02 14:23             ` Alberto Garcia
  0 siblings, 2 replies; 12+ messages in thread
From: Kevin Wolf @ 2015-09-01 14:40 UTC (permalink / raw)
  To: Alberto Garcia; +Cc: qemu-block, qemu-devel, Stefan Hajnoczi, Max Reitz

Am 01.09.2015 um 16:22 hat Alberto Garcia geschrieben:
> On Tue 01 Sep 2015 01:31:11 PM CEST, Kevin Wolf <kwolf@redhat.com> wrote:
> 
> >> > Design question: Would it make sense to instead add a "reference"
> >> > mode to blockdev-snapshot-sync where you can specify a BDS's
> >> > node-name instead of snapshot-file to use an existing BDS as the
> >> > new top layer, ideally an empty one?
> >> 
> >> Indeed - then blockdev-add can be used to create an unattached BDS
> >> (with all appropriate options), and blockdev-snapshot-sync would then
> >> attach that BDS as the snapshot-file that wraps an existing BDS
> >> (without needing to worry about options).
> >
> > Yes, this is what we should do.
> 
> Sounds like a good idea, thanks for the feedback !
> 
> >> >> +# @options: #optional options for the new device, with the following
> >> >> +#           restrictions for the fields: 'driver' must match the value
> >> >> +#           of @format,
> >> > 
> >> > As said above, I'd rather make specifying both @options and @format
> >> > exclusive.
> >> > 
> >> > Maybe there is even some QAPI magic to enforce that (and for
> >> > 'node-name', too), I don't know...
> >> 
> >> Not that I know of at the moment, but not to say we can't add some.  The
> >> closest we can get is with a flat union, but that requires a
> >> non-optional discriminator field.  Maybe we can tweak qapi to make the
> >> discriminator optional (with a default value).  Thankfully, it sounds
> >> like Markus' work on introspection would at least let management apps
> >> learn about a new 'options' argument.
> 
> This is not necessary if we go for the "reference" mode proposed by
> Markus, since the "options" parameter would disappear.
> 
> > Let's avoid such magic and instead add a new, clean blockdev-* style
> > command. Maybe call it simply blockdev-snapshot; the -sync part was
> > added because we knew it wouldn't be the final version of the command.
> > Now we don't have any bdrv_open() in it any more that could by
> > synchronous or asynchronous.
> 
> Would you then prefer me to create a new command instead of extending
> the existing one? What would be the benefit (other than a better name)?

A clean interface. There is really little overlap with what we have:

{ 'struct': 'BlockdevSnapshot',
  'data': { '*device': 'str', '*node-name': 'str',
            'snapshot-file': 'str', '*snapshot-node-name': 'str',
            '*format': 'str', '*mode': 'NewImageMode' } }

When you add an existing node which has been created with blockdev-add
as a snapshot, you won't use snapshot-file, snapshot-node-name, format
and mode. We would either have to make all of them optional and actually
forbid them when a reference is given, or to ensure that they are
consistent with the already existing node. That we have both device and
node-name (and both marked as optional, while one of them is required) is
also not in line with our current practise.

If we went further that way, the schema wouldn't really be expressive
any more because there would be too many hidden rules of which
combinations are allowed and which aren't.

What you really need for the version with a reference is just:

{ 'struct': 'BlockdevSnapshot',
  'data': { 'device': 'str', 'snapshot': 'str' } }

Where both arguments refer to a node by node-name or backend name.

Kevin

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-09-01 14:40           ` Kevin Wolf
@ 2015-09-02  7:04             ` Markus Armbruster
  2015-09-02 14:23             ` Alberto Garcia
  1 sibling, 0 replies; 12+ messages in thread
From: Markus Armbruster @ 2015-09-02  7:04 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Stefan Hajnoczi, Alberto Garcia, qemu-devel, qemu-block,
	Max Reitz

Kevin Wolf <kwolf@redhat.com> writes:

> Am 01.09.2015 um 16:22 hat Alberto Garcia geschrieben:
[...]
>> Would you then prefer me to create a new command instead of extending
>> the existing one? What would be the benefit (other than a better name)?
>
> A clean interface. There is really little overlap with what we have:
>
> { 'struct': 'BlockdevSnapshot',
>   'data': { '*device': 'str', '*node-name': 'str',
>             'snapshot-file': 'str', '*snapshot-node-name': 'str',
>             '*format': 'str', '*mode': 'NewImageMode' } }
>
> When you add an existing node which has been created with blockdev-add
> as a snapshot, you won't use snapshot-file, snapshot-node-name, format
> and mode. We would either have to make all of them optional and actually
> forbid them when a reference is given, or to ensure that they are
> consistent with the already existing node. That we have both device and
> node-name (and both marked as optional, while one of them is required) is
> also not in line with our current practise.
>
> If we went further that way, the schema wouldn't really be expressive
> any more because there would be too many hidden rules of which
> combinations are allowed and which aren't.

Yes, and let me elaborate a bit.

QMP permits evolving stuff compatibly.  We use this capability to keep
things simple and short when we add functionality: we extend existing
stuff instead of duplicating and modifying it.  Say, add detail to a
query result, or add an optional command parameter that modifies
behavior.

The question to ask is whether the single, extended interface is still
simpler than a new interface plus the unchanged old one.

I expect introspection to influence our understanding of "simple
interface" going forward.  Stuff visible in introspection is usually
simple.  Rules of use introspection can't show are often problematic.

[...]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-09-01 14:40           ` Kevin Wolf
  2015-09-02  7:04             ` Markus Armbruster
@ 2015-09-02 14:23             ` Alberto Garcia
  2015-09-02 15:43               ` Eric Blake
  1 sibling, 1 reply; 12+ messages in thread
From: Alberto Garcia @ 2015-09-02 14:23 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-block, qemu-devel, Stefan Hajnoczi, Max Reitz

On Tue 01 Sep 2015 04:40:02 PM CEST, Kevin Wolf wrote:

>> > Let's avoid such magic and instead add a new, clean blockdev-*
>> > style command. Maybe call it simply blockdev-snapshot; the -sync
>> > part was added because we knew it wouldn't be the final version of
>> > the command.  Now we don't have any bdrv_open() in it any more that
>> > could by synchronous or asynchronous.

Ok, I have a first working prototype of the new command using
references as suggested.

> { 'struct': 'BlockdevSnapshot',
>   'data': { '*device': 'str', '*node-name': 'str',
>             'snapshot-file': 'str', '*snapshot-node-name': 'str',
>             '*format': 'str', '*mode': 'NewImageMode' } }
  [...]
>
> What you really need for the version with a reference is just:
>
> { 'struct': 'BlockdevSnapshot',
>   'data': { 'device': 'str', 'snapshot': 'str' } }

And what do I do with the old BlockdevSnapshot? I guess it can just be
renamed to BlockdevSnapshotSync or something like that?

Berto

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/1] block: Allow passing BlockdevOptions to blockdev-snapshot-sync
  2015-09-02 14:23             ` Alberto Garcia
@ 2015-09-02 15:43               ` Eric Blake
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Blake @ 2015-09-02 15:43 UTC (permalink / raw)
  To: Alberto Garcia, Kevin Wolf
  Cc: qemu-block, qemu-devel, Stefan Hajnoczi, Max Reitz

[-- Attachment #1: Type: text/plain, Size: 1451 bytes --]

On 09/02/2015 08:23 AM, Alberto Garcia wrote:
> On Tue 01 Sep 2015 04:40:02 PM CEST, Kevin Wolf wrote:
> 
>>>> Let's avoid such magic and instead add a new, clean blockdev-*
>>>> style command. Maybe call it simply blockdev-snapshot; the -sync
>>>> part was added because we knew it wouldn't be the final version of
>>>> the command.  Now we don't have any bdrv_open() in it any more that
>>>> could by synchronous or asynchronous.
> 
> Ok, I have a first working prototype of the new command using
> references as suggested.
> 
>> { 'struct': 'BlockdevSnapshot',
>>   'data': { '*device': 'str', '*node-name': 'str',
>>             'snapshot-file': 'str', '*snapshot-node-name': 'str',
>>             '*format': 'str', '*mode': 'NewImageMode' } }
>   [...]
>>
>> What you really need for the version with a reference is just:
>>
>> { 'struct': 'BlockdevSnapshot',
>>   'data': { 'device': 'str', 'snapshot': 'str' } }
> 
> And what do I do with the old BlockdevSnapshot? I guess it can just be
> renamed to BlockdevSnapshotSync or something like that?

Sure. And one of the nice things with the ongoing introspection work is
that qapi type names are NOT exposed as ABI (changing the name of a type
affects the generated C code, but does not affect what a QMP client
sends over the wire), so it is safe to do.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-09-02 15:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-31 10:00 [Qemu-devel] [PATCH 0/1] Allow passing BlockdevOptions to blockdev-snapshot-sync Alberto Garcia
2015-08-31 10:00 ` [Qemu-devel] [PATCH 1/1] block: " Alberto Garcia
2015-08-31 19:53   ` Max Reitz
2015-08-31 20:05     ` Eric Blake
2015-08-31 20:12       ` Max Reitz
2015-09-01 11:33         ` Kevin Wolf
2015-09-01 11:31       ` Kevin Wolf
2015-09-01 14:22         ` Alberto Garcia
2015-09-01 14:40           ` Kevin Wolf
2015-09-02  7:04             ` Markus Armbruster
2015-09-02 14:23             ` Alberto Garcia
2015-09-02 15:43               ` Eric Blake

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).