qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>,
	qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [PATCH v7 14/47] stream: Deal with filters
Date: Mon, 10 Aug 2020 10:12:50 +0200	[thread overview]
Message-ID: <9f8b1eb5-2039-b2c5-6330-7f39f2c21464@redhat.com> (raw)
In-Reply-To: <f61033e0-92be-0b9a-7a14-e1c56372b671@virtuozzo.com>


[-- Attachment #1.1: Type: text/plain, Size: 13019 bytes --]

On 07.08.20 12:29, Vladimir Sementsov-Ogievskiy wrote:
> 16.07.2020 17:59, Max Reitz wrote:
>> On 10.07.20 19:41, Andrey Shinkevich wrote:
>>> On 10.07.2020 18:24, Max Reitz wrote:
>>>> On 09.07.20 16:52, Andrey Shinkevich wrote:
>>>>> On 25.06.2020 18:21, Max Reitz wrote:
>>>>>> Because of the (not so recent anymore) changes that make the
>>>>>> stream job
>>>>>> independent of the base node and instead track the node above it, we
>>>>>> have to split that "bottom" node into two cases: The bottom COW node,
>>>>>> and the node directly above the base node (which may be an R/W filter
>>>>>> or the bottom COW node).
>>>>>>
>>>>>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>>>>>> ---
>>>>>>     qapi/block-core.json |  4 +++
>>>>>>     block/stream.c       | 63
>>>>>> ++++++++++++++++++++++++++++++++------------
>>>>>>     blockdev.c           |  4 ++-
>>>>>>     3 files changed, 53 insertions(+), 18 deletions(-)
>>>>>>
>>>>>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>>>>>> index b20332e592..df87855429 100644
>>>>>> --- a/qapi/block-core.json
>>>>>> +++ b/qapi/block-core.json
>>>>>> @@ -2486,6 +2486,10 @@
>>>>>>     # On successful completion the image file is updated to drop the
>>>>>> backing file
>>>>>>     # and the BLOCK_JOB_COMPLETED event is emitted.
>>>>>>     #
>>>>>> +# In case @device is a filter node, block-stream modifies the first
>>>>>> non-filter
>>>>>> +# overlay node below it to point to base's backing node (or NULL if
>>>>>> @base was
>>>>>> +# not specified) instead of modifying @device itself.
>>>>>> +#
>>>>>>     # @job-id: identifier for the newly-created block job. If
>>>>>>     #          omitted, the device name will be used. (Since 2.7)
>>>>>>     #
>>>>>> diff --git a/block/stream.c b/block/stream.c
>>>>>> index aa2e7af98e..b9c1141656 100644
>>>>>> --- a/block/stream.c
>>>>>> +++ b/block/stream.c
>>>>>> @@ -31,7 +31,8 @@ enum {
>>>>>>       typedef struct StreamBlockJob {
>>>>>>         BlockJob common;
>>>>>> -    BlockDriverState *bottom;
>>>>>> +    BlockDriverState *base_overlay; /* COW overlay (stream from
>>>>>> this) */
>>>>>> +    BlockDriverState *above_base;   /* Node directly above the
>>>>>> base */
>>>>> Keeping the base_overlay is enough to complete the stream job.
>>>> Depends on the definition.  If we decide it isn’t enough, then it isn’t
>>>> enough.
>>>>
>>>>> The above_base may disappear during the job and we can't rely on it.
>>>> In this version of this series, it may not, because the chain is
>>>> frozen.
>>>>    So the above_base cannot disappear.
>>>
>>> Once we insert a filter above the top bs of the stream job, the parallel
>>> jobs in
>>>
>>> the iotests #030 will fail with 'frozen link error'. It is because of
>>> the
>>>
>>> independent parallel stream or commit jobs that insert/remove their
>>> filters
>>>
>>> asynchroniously.
>>
>> I’m not sure whether that’s a problem with this series specifically.
>>
>>>> We can discuss whether we should allow it to disappear, but I think
>>>> not.
>>>>
>>>> The problem is, we need something to set as the backing file after
>>>> streaming.  How do we figure out what that should be?  My proposal
>>>> is we
>>>> keep above_base and use its immediate child.
>>>
>>> We can do the same with the base_overlay.
>>>
>>> If the backing node turns out to be a filter, the proper backing
>>> child will
>>>
>>> be set after the filter is removed. So, we shouldn't care.
>>
>> And what if the user manually added some filter above the base (i.e.
>> below base_overlay) that they want to keep after the job?
> 
> 
> It's automatically kept, if we use base_overlay->backing->bs as final
> backing node.
> 
> You mean, that they want it to be dropped?

Er, yes.  Point is, the graph structure below with @base at the root may
be different than the one right below @base_overlay.

> so, assuming the following:
> 
> top -(backing)-> manually-inserted-filter -(file)-> base
> 
> and user do stream with base=base, and expects filter to be removed by
> stream job?
> 
> Hmm, yes, such use-case is broken with our proposed way...
> 
> ====
> 
> Let me now clarify the problem we'll have with your way.
> 
> When stream don't have any filter, we can easily imagine two parallel
> stream jobs:
> 
> top -(backing)-> mid1 -(backing)-> mid2 -(backing)-> base
> 
> stream1: top=top, base=mid2
> stream2: top=mid2, base=NULL
> 
> final picture is obvious:
> 
> top (merged with mid1) -(backing)-> mid2 (merged with base)

Yes, and I don’t think this currently working case is broken by this series.

> But we want stream job has own filter, like mirror.

Which it does not have yet, right?  Which is why I was saying that I
don’t think this is a problem with this series.  We could try to address
it later.

Or do you think we can’t address it later because right now all filter
cases are broken anyway so now would be the time to make a breaking
change (which the suggestion to not use @base as the final backing node is)?

> So the picture becomes more complex.
> 
> Assume stream2 starts first.
> 
> top -(backing)-> mid1 -(backing)-> stream2-filter -(backing)-> mid2
> -(backing)-> base

stream2-filter would be on top of mid2, right?

> Now, when we run stream1, with your solution, stream1 will freeze
> stream2-filter
> (wrong thing, stream2 will fail to remove it if it finished first), and
> stream1 will
> remove stream2-filter on finish (which is wrong as well, stream2 is not
> prepared to
> removing of its filter)..

Note that the user first needs to pass “mid2” as the base to the stream
job stream1.  Why don’t they just pass “stream2-filter”?  In my model,
the user should specify exactly which node they want not to be touched
by this stream job, and so that would be stream2-filter, not mid1.

I feel like the answer to this question has to do with implicit nodes.
AFAIU you wanted to remove them, so I don’t think we’d want to
special-case them here.

If you think that we can’t expect users to pass “stream2-filter” because
currently it should work with “mid2”, then that’s a case of implicit
nodes and it means we should ascend from @base up to the first
non-implicit node to get the @above_base we want.

> But, with our proposed way (freeze only chain up to base_overlay
> inclusively, and use backing(base_overlay) as final backing), all will
> work as expected, and two parallel jobs will work..

I don’t think it will work as expected because users can no longer
specify which node should be the base node after streaming.  And the
QAPI schema says that base-node is to become the backing file of the top
node after streaming.

I suppose you’re arguing that streaming through filters basically just
doesn’t work at all right now, so we’re free to do whatever?

Well, that still leaves the problem that users should be able to specify
which node is to become the base after streaming, and that that node
maybe shouldn’t be restricted to immediate children of COW images.

> ====
> 
> So, these are two mutually exclusive cases.. I vote for freezing up to
> base_overlay, and use backing(base_overlay) as final backing, because:
> 
> 1. I can't imaging other way to fix the case with parallel streams with
> filters (it's not a problem of current master, but we have pending
> series which will introduce stream job filter, and the problem will
> appear and even break iotest 30)

Besides the question of whether the top job could just use the bottom
job’s filter node as the base, there’s also the alternative of admitting
defeat and declaring that you just cannot use a single node in two
streams, because we didn’t find a way to make it work after all.

You could still create a temporary overlay in between that’s never used
and then drop it with a trivial stream afterwards.

(But that just in case specifying the bottom job’s stream node somehow
wouldn’t work.)

> 2. I don't think that removing filters above base node by stream job is
> so important case to break parallel stream jobs in future:
> 
>  - Stream job is not intended to remove filters, but to stream data.
> Filters between base_overlay and base don't contain any data and
> unrelated to stream process

Well, it is intended to remove nodes.  You can only remove data-bearing
nodes by moving data around.  I suspect if there was a way to get the
to-be-removed nodes removed without having to move their data around,
that would be popular.

>  - I think, that filters are "more related" to their children than to
> their parents. So, removing filters related to base node, when we just
> remove all data-containing nodes between top and base (and are not going
> to remove base node) is at least questionable.

Yes.

Although it could be argued that it is a handy way to remove filters, in
a backing chain at least.  (Thanks to bdrv_find_overlay(), @base and
@top still need to refer to different levels of the backing chain, but
if we lifted that restriction, I suppose it could work for any filter
chain.)

*shrug*

> On the contrary, removing
> all intermediate data containing nodes _together_ with their filters is
> absolutely correct thing to do.

I don’t think so, actually.  Like, you have a throttle node somewhere in
the chain, shouldn’t you maybe want to move it down below the chain?  Or
a COR node, shouldn’t that go above the chain after streaming?

I’m not making an argument here, I just don’t quite understand why you’d
bring up what happens with intermediate filters here.  The only reason
to drop them is because that’s what I expect users to expect of the
stream job.

> Next, with your way, what about filters, inserted above base during
> stream job? They will be between above_base and base, and will not be
> removed. So with your way, filters above base, existing before job start
> will be frozen during the job and removed after it, but filters appended
> above base during the job will be untouched. With our way, just all base
> node related filters are untouched by the job. It seems simpler
> definition for me and simpler to document.

Hm.  The documentation seems the same to me.  Either it’s “The backing
node (at the end of the job) of @base’s parent node (when starting the
job)” or “The backing node (at the end of the job) of the next
non-filter node above @base (when starting the job)”.

The problem you describe (that @above_base at the end of the job isn’t
necessarily above @base anymore) also exists with your suggestion,
namely that you can add overlays above @base after the job has started,
so @base_overlay at the end of the job isn’t necessarily the first
non-filter node above @base anymore.


OK, so after all this text, maybe some more original problem searching.
 I think it the root of the problem is that the stream job takes a @base
parameter, but as of c624b015bf14fe01, it doesn’t really matter anymore.
 Maybe c624b015bf14fe01 should have introduced a new parameter for users
to specify the bottom node instead of @base.

Well, that would have made everything a parameter mess, but it would
have saved us the trouble now.

In any case, the problem we have now is that we want a way to
automagically find out which node the bottom node should be, because the
user can’t specify it.  So the documentation is always going to be
written as “The backing node (at the end of the job) of $bottom”, where
“$bottom” is what we’re interested in figuring out.

I thought it would be best if we stick as close as possible to the
spirit of the current documentation, which basically requires @base-node
to be the backing node of the top after streaming.  (If you do graph
modifications during the job, that’s on you, because since
c624b015bf14fe01 we can’t keep the base frozen.)

Your suggestion to do basically what you consider to be right, which
comes at the caveat of being untruthful to the current documentation
even if there are no graph modifications during the job.  Luckily, the
stream job right now doesn’t work in the cases we’re looking at, so it
wouldn’t be a breaking change.  The problem I have with it is that
you’re assuming what is right and what isn’t (i.e. “Who would want to
remove filter nodes directly above @base”) without giving the user a
chance to specify.


I think it would be nice if we could have something that remains
truthful to the current documentation.  If just ignoring implicit
filters above @base would work, then I’d find that nice.  If it doesn’t,
I suppose there’s indeed little we can do but to indeed forego
@above_base and just use @base_overlay for all cases.

Max


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

  reply	other threads:[~2020-08-10  8:13 UTC|newest]

Thread overview: 173+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-25 15:21 [PATCH v7 00/47] block: Deal with filters Max Reitz
2020-06-25 15:21 ` [PATCH v7 01/47] block: Add child access functions Max Reitz
2020-07-08 17:22   ` Andrey Shinkevich
2020-07-13  9:06   ` Vladimir Sementsov-Ogievskiy
2020-07-16 14:46     ` Max Reitz
2020-07-28 16:09     ` Christophe de Dinechin
2020-08-07  9:33       ` Vladimir Sementsov-Ogievskiy
2020-07-13  9:57   ` Vladimir Sementsov-Ogievskiy
2020-06-25 15:21 ` [PATCH v7 02/47] block: Add chain helper functions Max Reitz
2020-07-08 17:20   ` Andrey Shinkevich
2020-07-09  8:24     ` Max Reitz
2020-07-09  9:07       ` Andrey Shinkevich
2020-07-13 10:18   ` Vladimir Sementsov-Ogievskiy
2020-07-16 14:50     ` Max Reitz
2020-07-16 15:24       ` Vladimir Sementsov-Ogievskiy
2020-06-25 15:21 ` [PATCH v7 03/47] block: bdrv_cow_child() for bdrv_has_zero_init() Max Reitz
2020-07-08 17:23   ` Andrey Shinkevich
2020-08-07  9:37   ` Vladimir Sementsov-Ogievskiy
2020-06-25 15:21 ` [PATCH v7 04/47] block: bdrv_set_backing_hd() is about bs->backing Max Reitz
2020-07-08 17:24   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 05/47] block: Include filters when freezing backing chain Max Reitz
2020-07-08 17:25   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 06/47] block: Drop bdrv_is_encrypted() Max Reitz
2020-07-08 17:41   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 07/47] block: Add bdrv_supports_compressed_writes() Max Reitz
2020-07-08 17:48   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 08/47] throttle: Support compressed writes Max Reitz
2020-07-08 17:52   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 09/47] copy-on-read: " Max Reitz
2020-07-08 17:54   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 10/47] mirror-top: " Max Reitz
2020-07-08 17:58   ` Andrey Shinkevich
2020-08-18 10:27   ` Kevin Wolf
2020-08-19 15:35     ` Max Reitz
2020-08-19 16:00       ` Kevin Wolf
2020-06-25 15:21 ` [PATCH v7 11/47] backup-top: " Max Reitz
2020-07-08 17:59   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 12/47] block: Use bdrv_filter_(bs|child) where obvious Max Reitz
2020-07-08 18:24   ` Andrey Shinkevich
2020-07-09  8:59     ` Max Reitz
2020-07-09  9:11       ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 13/47] block: Use CAFs in block status functions Max Reitz
2020-07-08 19:13   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 14/47] stream: Deal with filters Max Reitz
2020-07-09 14:52   ` Andrey Shinkevich
2020-07-09 15:27     ` Andrey Shinkevich
2020-07-10 15:24     ` Max Reitz
2020-07-10 17:41       ` Andrey Shinkevich
2020-07-16 14:59         ` Max Reitz
2020-08-07 10:29           ` Vladimir Sementsov-Ogievskiy
2020-08-10  8:12             ` Max Reitz [this message]
2020-08-10 11:04               ` Vladimir Sementsov-Ogievskiy
2020-08-14 15:18                 ` Andrey Shinkevich
2020-08-18 20:45                 ` Andrey Shinkevich
2020-08-19 12:39                 ` Max Reitz
2020-08-19 13:18                   ` Vladimir Sementsov-Ogievskiy
2020-07-09 15:13   ` Andrey Shinkevich
2020-07-10 15:27     ` Max Reitz
2020-08-18 14:28   ` Kevin Wolf
2020-08-19 14:47     ` Max Reitz
2020-08-19 15:16       ` Kevin Wolf
2020-08-20  8:31         ` Max Reitz
2020-08-20  9:22           ` Max Reitz
2020-08-20 10:49             ` Vladimir Sementsov-Ogievskiy
2020-08-20 11:43               ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 15/47] block: Use CAFs when working with backing chains Max Reitz
2020-07-10 15:28   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 16/47] block: Use bdrv_cow_child() in bdrv_co_truncate() Max Reitz
2020-07-10 15:54   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 17/47] block: Re-evaluate backing file handling in reopen Max Reitz
2020-07-10 19:42   ` Andrey Shinkevich
2020-07-16 15:04     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 18/47] block: Flush all children in generic code Max Reitz
2020-07-14 12:52   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 19/47] vmdk: Drop vmdk_co_flush() Max Reitz
2020-07-14 14:52   ` Andrey Shinkevich
2020-07-16 15:08     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 20/47] block: Iterate over children in refresh_limits Max Reitz
2020-07-14 18:37   ` Andrey Shinkevich
2020-07-16 15:14     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 21/47] block: Use CAFs in bdrv_refresh_filename() Max Reitz
2020-07-15 12:52   ` Andrey Shinkevich
2020-07-15 12:58     ` Andrey Shinkevich
2020-07-16 15:21     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 22/47] block: Use CAF in bdrv_co_rw_vmstate() Max Reitz
2020-07-15 13:39   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 23/47] block/snapshot: Fix fallback Max Reitz
2020-07-15 21:22   ` Andrey Shinkevich
2020-07-15 22:18     ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 24/47] block: Use CAFs for debug breakpoints Max Reitz
2020-07-15 21:43   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 25/47] block: Def. impl.s for get_allocated_file_size Max Reitz
2020-07-15 22:56   ` Andrey Shinkevich
2020-08-19 10:57   ` Kevin Wolf
2020-08-19 15:53     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 26/47] block: Improve get_allocated_file_size's default Max Reitz
2020-07-20 15:12   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 27/47] blkverify: Use bdrv_sum_allocated_file_size() Max Reitz
2020-07-20 15:10   ` Andrey Shinkevich
2020-08-19 10:46   ` Kevin Wolf
2020-08-19 15:50     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 28/47] block/null: Implement bdrv_get_allocated_file_size Max Reitz
2020-07-20 15:10   ` Andrey Shinkevich
2020-07-24  8:58     ` Max Reitz
2020-07-24  9:49       ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 29/47] blockdev: Use CAF in external_snapshot_prepare() Max Reitz
2020-07-20 16:08   ` Andrey Shinkevich
2020-07-24  9:23     ` Max Reitz
2020-07-24 10:37       ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 30/47] block: Report data child for query-blockstats Max Reitz
2020-07-21 11:48   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 31/47] block: Use child access functions for QAPI queries Max Reitz
2020-07-21 12:30   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 32/47] block-copy: Use CAF to find sync=top base Max Reitz
2020-07-21 12:42   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 33/47] mirror: Deal with filters Max Reitz
2020-07-22 18:31   ` Andrey Shinkevich
2020-07-24  9:49     ` Max Reitz
2020-07-24 10:27       ` Andrey Shinkevich
2020-08-19 16:50   ` Kevin Wolf
2020-08-20 10:28     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 34/47] backup: " Max Reitz
2020-07-23 15:51   ` Andrey Shinkevich
2020-07-24  9:55     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 35/47] commit: " Max Reitz
2020-07-23 17:15   ` Andrey Shinkevich
2020-07-24 10:36     ` Andrey Shinkevich
2020-08-19 17:58   ` Kevin Wolf
2020-08-20 11:27     ` Max Reitz
2020-08-20 13:47       ` Kevin Wolf
2020-06-25 15:22 ` [PATCH v7 36/47] nbd: Use CAF when looking for dirty bitmap Max Reitz
2020-07-23 17:21   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 37/47] qemu-img: Use child access functions Max Reitz
2020-07-24 15:51   ` Andrey Shinkevich
2020-08-21 15:29   ` Kevin Wolf
2020-08-24 12:42     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 38/47] block: Drop backing_bs() Max Reitz
2020-07-24 15:55   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 39/47] blockdev: Fix active commit choice Max Reitz
2020-08-21 15:50   ` Kevin Wolf
2020-08-24 13:18     ` Max Reitz
2020-08-24 14:07       ` Kevin Wolf
2020-08-24 14:41         ` Max Reitz
2020-08-24 15:06           ` Kevin Wolf
2020-06-25 15:22 ` [PATCH v7 40/47] block: Inline bdrv_co_block_status_from_*() Max Reitz
2020-07-24 18:00   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 41/47] block: Leave BDS.backing_file constant Max Reitz
2020-07-27 12:27   ` Andrey Shinkevich
2020-07-28 14:10     ` Max Reitz
2020-08-24 13:14   ` Kevin Wolf
2020-08-24 14:29     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 42/47] iotests: Test that qcow2's data-file is flushed Max Reitz
2020-07-27 13:28   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 43/47] iotests: Let complete_and_wait() work with commit Max Reitz
2020-07-27 13:35   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 44/47] iotests: Add filter commit test cases Max Reitz
2020-07-27 17:45   ` Andrey Shinkevich
2020-07-28 14:00     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 45/47] iotests: Add filter mirror " Max Reitz
2020-08-02 11:05   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 46/47] iotests: Add test for commit in sub directory Max Reitz
2020-08-02 12:13   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 47/47] iotests: Test committing to overridden backing Max Reitz
2020-08-02 11:43   ` Andrey Shinkevich
2020-07-08 17:20 ` [PATCH v7 00/47] block: Deal with filters Andrey Shinkevich
2020-07-08 17:32   ` Eric Blake
2020-07-08 19:46     ` Andrey Shinkevich
2020-07-08 20:37       ` Eric Blake
2020-07-09  8:19         ` Max Reitz
2020-07-08 20:47   ` Eric Blake
2020-07-09  8:20     ` Max Reitz
2020-07-09  9:04       ` Andrey Shinkevich
2020-08-24 15:15 ` Kevin Wolf

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=9f8b1eb5-2039-b2c5-6330-7f39f2c21464@redhat.com \
    --to=mreitz@redhat.com \
    --cc=andrey.shinkevich@virtuozzo.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /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).