From: Eric Blake <eblake@redhat.com>
To: Max Reitz <mreitz@redhat.com>, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, qemu-block@nongnu.org
Subject: Re: [PATCH v2 3/6] qemu-img: Add bitmap sub-command
Date: Thu, 30 Apr 2020 10:21:46 -0500 [thread overview]
Message-ID: <9d4769d4-09ea-dced-d4bd-9ceb33044202@redhat.com> (raw)
In-Reply-To: <1dcf85b6-d9e6-b952-537c-791daec34ad9@redhat.com>
On 4/30/20 9:55 AM, Max Reitz wrote:
> On 21.04.20 23:20, Eric Blake wrote:
>> Include actions for --add, --remove, --clear, --enable, --disable, and
>> --merge (note that --clear is a bit of fluff, because the same can be
>> accomplished by removing a bitmap and then adding a new one in its
>> place,
>
> Well, ideally, all of qemu-img is just fluff because “the same can be
> accomplished by launching qemu and issuing the equivalent QMP commands”. :)
>
>> but it matches what QMP commands exist). Listing is omitted,
>> because it does not require a bitmap name and because it was already
>> possible with 'qemu-img info'.
>
> Fair enough, although it can be said that qemu-img info’s output is
> qcow2-specific. It might be nice to have some definitely
> format-independent output. (But we don’t have persistent bitmaps in
> anything but qcow2 yet (or do we in NBD?), so I don’t expect anyone to
> care much.)
We can add a list subcommand later if it is still desired. I agree that
a tabular format:
name enabled granularity
bitmap1 false 65536
bitmap2 true 512
in isolation is easier to read than:
bitmaps:
[0]:
flags:
name: bitmap1
granularity: 65536
[1]:
flags:
[0]: auto
name: bitmap2
granularity: 512
embedded inside even more information.
>
>> Merge can work either from another
>> bitmap in the same image, or from a bitmap in a distinct image.
>>
>> While this supports --image-opts for the file being modified, I did
>> not think it worth the extra complexity to support that for the source
>> file in a cross-file bitmap merge. Likewise, I chose to have --merge
>> only take a single source rather than following the QMP support for
>> multiple merges in one go; in part to simplify the command line, and
>> in part because an offline image can achieve the same effect by
>> multiple qemu-img bitmap --merge calls. We can enhance that if needed
>> in the future (the same way that 'qemu-img convert' has a mode that
>> concatenates multiple sources into one destination).
>>
>> Upcoming patches will add iotest coverage of these commands while
>> also testing other features.
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>> ---
>> docs/tools/qemu-img.rst | 24 +++++
>> qemu-img.c | 198 ++++++++++++++++++++++++++++++++++++++++
>> qemu-img-cmds.hx | 7 ++
>> 3 files changed, 229 insertions(+)
>>
>> diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
>> index 7d08c48d308f..4f3b0e2c9ace 100644
>> --- a/docs/tools/qemu-img.rst
>> +++ b/docs/tools/qemu-img.rst
>> @@ -281,6 +281,30 @@ Command description:
>> For write tests, by default a buffer filled with zeros is written. This can be
>> overridden with a pattern byte specified by *PATTERN*.
>>
>> +.. option:: bitmap {--add [-g GRANULARITY] [--disabled] | --remove | --clear | --enable | --disable | --merge SOURCE_BITMAP [-b SOURCE_FILE [-F SOURCE_FMT]]} [--object OBJECTDEF] [--image-opts] [-f FMT] FILENAME BITMAP
>
> So I can do multiple operations in one roll, but they all use the same
> BITMAP? Sounds a bit weird. It actually took me a while to understands
> this, because I thought for sure that each command would take a bitmap
> name. (And was ready to complain that it looked like they don’t, but,
> well, that’s because they don’t.)
All of the operations take one bitmap name (the final BITMAP).
Additionally, the --merge operation takes a second bitmap name
(SOURCE_BITMAP). None of the other operations need a second bitmap
name, so only --merge requires an option argument. As written, the { a
| b | c } implies that operations are mutually exclusive: you can only
request one operation per qemu-img invocation.
>
> Although I suppose some practical example like
>
> $ qemu-img bitmap --add --merge sbmap --disable foo.qcow2 nbmap
>
> does make sense.[1]
>
>
> Would
>
> $ qemu-img bitmap --add nbmap --merge nbmap sbmap --enable nbmap \
> foo.qcow2
>
> make more sense?
That would be more transactional, and more effort to implement. My
argument is that you should instead write:
$ qemu-img bitmap --add foo.qcow2 nbmap
$ qemu-img bitmap --merge sbmap foo.qcow2 nbmap
$ qemu-img bitmap --enable foo.qcow2 nbmap
where I only have to implement one operation per qemu-img.
> Doesn’t really look like it, because at that point you
> just have to ask why not just call qemu-img bitmap multiple times.
>
> *shrug*
>
>
> [1] However, that leads me to ask: Why does --add need a --disabled
> option? Isn’t that equivalent to --add --disable?
The QMP command for add has an optional 'disabled' parameter, which I
exposed here. Alternatively, we could indeed NOT expose that parameter
through qemu-img, but require two separate qemu-img bitmap commands to
add and then disable things. Atomicity is not a concern here like it
was in QMP. Removing that sugar does simplify things slightly.
>> +static int img_bitmap(int argc, char **argv)
>> +{
>> + Error *err = NULL;
>> + int c, ret = -1;
>> + QemuOpts *opts = NULL;
>> + const char *fmt = NULL, *src_fmt = NULL, *src_filename = NULL;
>> + const char *filename, *bitmap;
>> + BlockBackend *blk = NULL, *src = NULL;
>> + BlockDriverState *bs = NULL, *src_bs = NULL;
>> + bool image_opts = false;
>> + unsigned long granularity = 0;
>> + bool add = false, remove = false, clear = false;
>> + bool enable = false, disable = false, add_disabled = false;
>> + const char *merge = NULL;
>
> So actually we can’t do one operation multiple times in one roll.
Correct. At least, not as I wrote it.
>
>> +
>> + for (;;) {
>> + static const struct option long_options[] = {
>> + {"help", no_argument, 0, 'h'},
>> + {"object", required_argument, 0, OPTION_OBJECT},
>> + {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
>> + {"add", no_argument, 0, OPTION_ADD},
>> + {"remove", no_argument, 0, OPTION_REMOVE},
>> + {"clear", no_argument, 0, OPTION_CLEAR},
>> + {"enable", no_argument, 0, OPTION_ENABLE},
>> + {"disable", no_argument, 0, OPTION_DISABLE},
>> + {"disabled", no_argument, 0, OPTION_DISABLE},
>
> So if --disable and --disabled are exactly the same, I really don’t know
> why --disabled even exists.
Logically, '--add --disabled' matches the name of the QMP command with
its optional 'disabled' parameter, while --disable matches the name of
the QMP command. We don't have to have the alias; and in fact, if you
agree that supporting '--add --disabled' is too much sugar (since we
don't care about atomicity the way QMP did), then life gets simpler to
drop --disabled altogether.
>> + if (add && disable) {
>> + disable = false;
>> + add_disabled = true;
>> + }
>> + if (add + remove + clear + enable + disable + !!merge != 1) {
>> + error_report("Need exactly one mode of --add, --remove, --clear, "
>> + "--enable, --disable, or --merge");
>
> Aha. So you can actually only do a single operation.
>
> That means the doc shouldn’t use {}, in my opinion, because that to me
> means repetition (thanks to EBNF). It definitely served to confuse me
> greatly until this point.
In command line syntax, I'm most used to seeing repetition as '...',
optional as [], and mutually-exclusive choice as {|}. Yes, that's
different than EBNF.
>
> I also don’t see why we would disallow multiple operations in one go.
> The --add --merge combination seems useful to me, and I don’t see a
> problem in implementing it.
>
> I don’t know why we don’t just create a list of operations to execute,
> based on the order given in the argument list, and then execute them in
> order. That would even allow multiple --merge operations.
If I understand, you're asking why we can't do:
qemu-img bitmap foo.qcow2 --add b1 --merge sb b1
in one operation.
That changes the syntax entirely, compared to what I implemented. You'd
have to have an argument to every option, AND figure out how to specify
TWO arguments to the --merge option. Might be doable, but seems hairy.
>
> If we don’t want that (because we don’t want argument order to matter),
> we could still allow all operations to be done at least once and always
> execute them in the same order, e.g.:
> (1) add
> (2) clear
> (3) merge
> (4) disable
> (5) enable
> (6) remove
I still find it simpler to do exactly one operation per invocation.
>
>> + goto out;
>> + }
>> + if (granularity && !add) {
>> + error_report("granularity only supported with --add");
>> + goto out;
>> + }
>> + if (src_fmt && !src_filename) {
>> + error_report("-F only supported with -b");
>> + goto out;
>> + }
>> + if (src_filename && !merge) {
>> + error_report("alternate source file only supported with --merge");
>
> “alternate” sounds strange. Why not be more precise and call it a
> “Merge bitmap source file” or “File to source merge bitmap from”?
"Merge bitmap source file" sounds fine.
>> +
>> + if (err) {
>> + error_reportf_err(err, "Bitmap %s operation failed", bitmap);
>
> Wouldn’t “Operation on bitmap %s failed” work better?
Yes.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
next prev parent reply other threads:[~2020-04-30 15:28 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-21 21:20 [PATCH v2 0/6] qemu-img: Add convert --bitmaps Eric Blake
2020-04-21 21:20 ` [PATCH v2 1/6] docs: Sort sections on qemu-img subcommand parameters Eric Blake
2020-04-30 12:50 ` Max Reitz
2020-04-21 21:20 ` [PATCH v2 2/6] blockdev: Split off basic bitmap operations for qemu-img Eric Blake
2020-04-30 13:59 ` Max Reitz
2020-04-30 14:50 ` Eric Blake
2020-05-08 11:37 ` Kevin Wolf
2020-05-08 13:48 ` Eric Blake
2020-04-21 21:20 ` [PATCH v2 3/6] qemu-img: Add bitmap sub-command Eric Blake
2020-04-30 14:55 ` Max Reitz
2020-04-30 15:21 ` Eric Blake [this message]
2020-05-04 10:01 ` Max Reitz
2020-05-04 13:28 ` Eric Blake
2020-04-21 21:20 ` [PATCH v2 4/6] qcow2: Expose bitmaps' size during measure Eric Blake
2020-05-04 11:36 ` Max Reitz
2020-05-04 13:44 ` Eric Blake
2020-04-21 21:20 ` [PATCH v2 5/6] qemu-img: Add convert --bitmaps option Eric Blake
2020-05-04 12:14 ` Max Reitz
2020-04-21 21:20 ` [PATCH v2 6/6] iotests: Add test 291 to for qemu-img bitmap coverage Eric Blake
2020-05-04 13:05 ` Max Reitz
2020-05-05 21:22 ` Eric Blake
2020-04-21 22:22 ` [PATCH v2 0/6] qemu-img: Add convert --bitmaps no-reply
2020-04-21 22:49 ` [PATCH] fixup! qemu-img: Add bitmap sub-command Eric Blake
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9d4769d4-09ea-dced-d4bd-9ceb33044202@redhat.com \
--to=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).