qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [Qemu-devel] Options for 4.0


From: Markus Armbruster
Subject: Re: [Qemu-block] [Qemu-devel] Options for 4.0
Date: Tue, 02 Apr 2019 11:09:57 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)

If in a hurry, skip ahead to "bottom line".

Kevin Wolf <address@hidden> writes:

> Am 01.04.2019 um 22:02 hat Markus Armbruster geschrieben:
>> Markus Armbruster <address@hidden> writes:
>> 
>> > Let's review our options for 4.0.
>> >
>> > Please note my analysis is handicapped by incomplete information, in
>> > particular on libvirt's needs.
>> >
>> > Terminology:
>> >
>> > * "Hard read-write" semantics: open read/write.
>> >
>> > * "Hard read-only" semantics: open read-only.
>> >
>> > * "Dynamic read-only" semantics: open read-only, reopen read/write when
>> >   a writer attaches, reopen read-only when the last writer detaches.
>> >
>> > * "Fallback read-only" semantics:. try to open read/write, fall back to
>> >   read-only.
>> >
>> > We have a use case for dynamic read-only: libvirt.  I'm not aware of a
>> > use case for fallback read-only.
>> >
>> > Behavior before 3.1:
>> >
>> > * read-only=on: hard read-only
>> >
>> > * read-only=off: hard read-write
>> >
>> > Behavior in 3.1: new parameter auto-read-only, default off.
>> >
>> > * read-only=on: hard read-only (no change)
>> >
>> > * read-only=on,auto-read-only=on: hard read-only (auto-read-only=on
>> >   silently ignored)
>> >
>> > * read-only=off: hard read-write
>> >
>> > * read-only=off,auto-read-only=on: depends on the driver
>> >
>> >   - file-posix.c's drivers: fallback read-only
>> >   - some other drivers: fallback read-only
>> >   - remaining drivers: hard read/write
>> >
>> > Behavior in 4.0 so far:
>> >
>> > * read-only=on: hard read-only (no change)
>> >
>> > * read-only=on,auto-read-only=on: hard read-only (no change)
>> >
>> > * read-only=off: hard read-write (no change)
>> >
>> > * read-only=off,auto-read-only=on: depends on the driver
>> >
>> >   - file-posix.c's drivers: dynamic read-only
>> >   - some other drivers: fallback read-only (no change)
>> >   - remaining drivers: hard read/write (no change)
>> >
>> >
>> > Option 1: Rename @auto-read-only.
>> >
>> > Rationale: we released auto-read-only in v3.1 with unproven fallback
>> > read-only semantics.  It turned out not to be useful.  Admit the
>> > mistake, retract it.  Release our next attempt in 4.0 under a suitable
>> > new name with fallback read-only semantics.
>> >
>> > CON:
>> >
>> > * Compatibility break.  No-go if there are users.  Users seem quite
>> >   unlikely, though.
>> >
>> > * Still unproven, albeit less so: this time we have some unreleased
>> >   (unfinished?) libvirt code.
>> >
>> > * Semantics are still largely left to drivers, and the schema can't tell
>> >   which one does what.  Awkward.
>> >
>> > * Unless we're fairly confident we won't upgrade drivers from "hard" to
>> >   "fallback" to "dynamic", this merely kicks the can down the road:
>> >   we'll face the exact same "how can libvirt find out" problem on every
>> >   upgrade.
>> >
>> > PRO:
>> >
>> > * When libvirt sees the new name, it can rely on file-posix.c's drivers
>> >   providing dynamic read-only semantics.
>> >
>> >
>> > Option 2: Add query-qemu-features command, return
>> > file-dynamic-auto-read-only #ifdef CONFIG_POSIX.
>> >
>> > Rationale: we released auto-read-only in v3.1 with unproven fallback
>> > read-only semantics.  It turned out not to be useful.  Admit the
>> > mistake, and patch it up in 4.0.  Libirt needs to know whether it's
>> > patche up, and this is a simple way to tell it.
>> >
>> > CON:
>> >
>> > * All of option 1's, except for the compatibility break
>> >
>> > * Uses query-qemu-features to expose a property of the build.  I
>> >   consider that a mistake.
>> >
>> > PRO
>> >
>> > * Libvirt can use either query-qmp-schema or query-qemu-features to find
>> >   out whether it can can rely on file-posix.c's drivers providing
>> >   dynamic read-only semantics.  To make query-qemu-features usable, we
>> >   need to promise query-qemu-features never returns false for it.  To
>> >   make query-qemu-features usable, we need to promise the value will
>> >   remain valid for the remainder of the QEMU run (defeats caching) or
>> >   for any future run of the same QEMU binary (enables caching).
>> >
>> >
>> > Option 3: Add @dynamic-read-only to the drivers that provide dynamic
>> > read-only, default to value of auto-read-only, promise we'll never add
>> > it to drivers that don't.
>> >
>> > Rationale: give users explicit control over dynamic vs. fallback for all
>> > drivers that can provide dynamic.  This makes some sense as an
>> > interface, as long as you ignore the fact that no driver implements both
>> > dynamic and fallback.  I can't see why a driver couldn't implement both.
>> > It also makes dynamic support visible in the schema.
>> >
>> > Behavior (three bools -> eight cases):
>> >
>> > * read-only=on: hard read-only (no change)
>> >
>> >   Shorthand for read-only=on,auto-read-only=off,dynamic-read-only=off
>> >
>> > * read-only=on,auto-read-only=on: hard read-only (no change)
>> >
>> >   Shorthand for read-only=on,auto-read-only=on,dynamic-read-only=on
>> >
>> > * read-only=off: hard read-write (no change)
>> >
>> >   Shorthand for read-only=off,auto-read-only=off,dynamic-read-only=off
>> >
>> > * read-only=off,auto-read-only=on:
>> >
>> >   Shorthand for read-only=off,auto-read-only=on,dynamic-read-only=on
>> >
>> >   - file-posix.c's drivers: dynamic read-only (no change,
>> >     dynamic-read-only=on is the default)
>> >   - some other drivers: fallback read-only (no change)
>> >   - remaining drivers: hard read/write (no change)
>> >
>> > * read-only=off,auto-read-only=on,dynamic-read-only=off
>> >
>> >   - file-posix.c's drivers: error
>> >   - all other drivers: N/A
>> >
>> > * read-only=off,auto-read-only=off,dynamic-read-only=on
>> >
>> >   - file-posix.c's drivers: error
>> >   - all other drivers: N/A
>> >
>> > * read-only=on,dynamic-read-only=on
>> >
>> >   Shorthand for read-only=on,auto-read-only=off,dynamic-read-only=on
>> >
>> >   - file-posix.c's drivers: error
>> >   - all other drivers: N/A
>> >
>> > * read-only=on,auto-read-only=on,dynamic-read-only=off
>> >
>> >   Shorthand for read-only=on,auto-read-only=on,dynamic-read-only=off
>> >
>> >   - file-posix.c's drivers: error
>> >   - all other drivers: N/A
>> >
>> > CON:
>> >
>> > * Two bools (read-only and auto-read-only) to select from three choices
>> >   was already ugly.  Three bools (the same plus dynamic-read-only) to
>> >   select from four choices is even uglier.
>> >
>> > * The explicit control is just a facade so far: since only the default
>> >   setting is implemented, it doesn't actually control anything.
>> >
>> > PRO:
>> >
>> > * When libvirt sees a driver providing a dynamic-read-only parameter, it
>> >   knows it can rely on the driver providing dynamic read-only semantics.
>> >
>> > * Adding dynamic read-only capability to drivers creates no
>> >   introspection problems: we simply add dynamic-read-only to their
>> >   parameters.
>> >
>> > Code sketch appended
>> 
>> Option 4 [Kevin]: Add a dummy option to BlockdevOptionsFile.
>> Message-ID: <address@hidden>
>> 
>> A variation of option 3, code is almost identical.  Where option 3 tries
>> to evolve what we have into the least bad permanent interface, option 4
>> only wants to serve as a stop gap until we get a better solution, such
>> as option 5.
>
> I think code-wise, this is actually very different from option 3. We
> need to actually process the dynamic-read-only option with option 3, and
> I can see things go wrong easily, which is not something to do for -rc2.
>
> Option 4, in contrast, is purely a minimal schema change without
> touching any C source file.

While I reject your "is very different" claim, I accept your "option 4
is less risky than option 3" claim.

Common part modulo naming:

    diff --git a/qapi/block-core.json b/qapi/block-core.json
    index 7ccbfff9d0..0cf15477ce 100644
    --- a/qapi/block-core.json
    +++ b/qapi/block-core.json
    @@ -2827,6 +2827,7 @@
     # Driver specific block device options for the file backend.
     #
     # @filename:    path to the image file
    +# @dynamic-read-only: FIXME document (since 4.0)
     # @pr-manager:  the id for the object that will handle persistent 
reservations
     #               for this device (default: none, forward the commands via 
SG_IO;
     #               since 2.11)
    @@ -2847,6 +2848,8 @@
     ##
     { 'struct': 'BlockdevOptionsFile',
       'data': { 'filename': 'str',
    +            '*dynamic-read-only': {'type': 'bool',
    +                                   'if': 'defined(CONFIG_POSIX)'},
                 '*pr-manager': 'str',
                 '*locking': 'OnOffAuto',
                 '*aio': 'BlockdevAioOptions',

Option 3 only:

    diff --git a/block/file-posix.c b/block/file-posix.c
    index db4cccbe51..d62681df14 100644
    --- a/block/file-posix.c
    +++ b/block/file-posix.c
    @@ -420,6 +420,11 @@ static QemuOptsList raw_runtime_opts = {
                 .type = QEMU_OPT_STRING,
                 .help = "File name of the image",
             },
    +        {
    +            .name = "dynamic-read-only",
    +            .type = QEMU_OPT_BOOL,
    +            .help = "FIXME",
    +        },
             {
                 .name = "aio",
                 .type = QEMU_OPT_STRING,
    @@ -540,6 +545,13 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
         s->open_flags = open_flags;
         raw_parse_flags(bdrv_flags, &s->open_flags, false);

    +    if (qemu_opt_get_bool(opts, "dynamic-read-only",
    +                          bdrv_flags & BDRV_O_AUTO_RDONLY)
    +        == !(bdrv_flags & BDRV_O_AUTO_RDONLY)) {
    +        error_setg(errp, "FIXME");
    +        ret = - EINVAL;
    +    }
    +
         s->fd = -1;
         fd = qemu_open(filename, s->open_flags, 0644);
         ret = fd < 0 ? -errno : 0;

Yes, this is more code, and yes, things could conceivably go wrong here.

>> Option 5 [Kevin]: Add feature flags to the QAPI language, use one to say
>> "this block driver provides dynamic read-only".
>> Message-ID: <address@hidden>
>
> More complex than option 4, but the advantage here is that none of the
> new code is actually externally visible, so if the implementation turns
> out buggy, we can fix it without having to maintain compatibility with
> the broken state.
>
> The actually visible change, the query-qmp-schema output, is almost as
> minimal as option 4 and can manually be verified.
>
> A bit more invasive than option 4, but I'd consider it still doable for
> -rc2 if we decide quickly.

It's a good option given the mess we made with auto-read-only in 3.1.
It's just three weeks late.

>> Option 6 [Peter]: Trigger reopen explicitly via QMP.
>> Message-ID: <address@hidden>
>> [Me] This leaves auto-read-only without a use case; deprecate?
>
> We have made some progress there with the new x-blockdev-reopen command.
> There are a few things that we know must be addressed before we can
> declare it stable, and probably there are more such things that we don't
> know of.
>
> x-blockdev-reopen takes the same options as blockdev-add and as such has
> a similar complexity. The experience with blockdev-add makes me doubt
> that we can mark it stable even for 4.1. So this might be a long-term
> solution, but we'd have to do something else for the meantime.

Understand.

>> Given that the libvirt code isn't ready, why do we need this done and
>> declared stable in 4.0?  We're going to tag -rc2 tomorrow...
>
> The next libvirt release will be long before the next QEMU release. If

Libvirt releases roughly monthly.

QEMU releases roughly April, August, December.

> we don't have it in 4.0, enabling -blockdev will have to wait until the
> first libvirt release after the QEMU 4.1 release (so maybe September)
> and we'll still be stuck with -drive and unable to start deprecating it
> until then.

Unless libvirt does yet another version check.

I talked this over with Peter.

libvirt 5.2 is expected today.  Peter is trying to get his work merged
in time for the next libvirt release (but he was trying that a month
ago, too).  So we're talking about 5.3 (May) or 5.4 (June).  Leaves a
gap of 2-3 month to 4.1 (August).

I offered option 4 "Add a dummy option to BlockdevOptionsFile".  He said
he'd advise against ugly hacks at this point, but going forward, QEMU
really needs a way to let libvirt detect code fixes, such as QAPI schema
feature flags.

> Also, we don't want to give Peter the excuse that the qemu code isn't
> ready. ;-)

Ah, you'd never do that to us, Peter, would you?


Bottom line:

* I can't bring myself to do QAPI schema language changes (option 5)
  this late in the game.  Sorry.

* I'm okay with option 4 if Kevin believes it could be useful.  Even if
  Peter won't actually use it, we're fairly unlikely to regret it.

* A more complete respin of the proposed QAPI schema language changes
  would be fair game for 4.1.

* QEMU and libvirt need to get better at co-developing features.  QEMU
  doesn't want to release stable interfaces without a user, and libvirt
  doesn't want to release a user without QEMU releasing first.  When we
  break this cycle by having QEMU releases stable interfaces completely
  unproven, we unsurprisingly get to regret it later.

Does this make sense?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]