From: John Snow <jsnow@redhat.com>
To: Eric Blake <eblake@redhat.com>, Fam Zheng <famz@redhat.com>,
qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Jeff Cody <jcody@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Max Reitz <mreitz@redhat.com>,
vsementsov@parallels.com, stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH v7 11/14] block/backup: support block job transactions
Date: Tue, 22 Sep 2015 19:27:12 -0400 [thread overview]
Message-ID: <5601E3D0.90301@redhat.com> (raw)
In-Reply-To: <5601D763.7010701@redhat.com>
On 09/22/2015 06:34 PM, Eric Blake wrote:
> On 09/22/2015 03:08 PM, John Snow wrote:
>> Eric, Markus: I've CC'd you for some crazy what-if QAPI questions
>> after my R-B on this patch.
>>
>
>> The current design of this patch is such that the blockdev-backup
>> and drive-backup QMP commands are extended for use in the
>> transaction action. This means that as part of the arguments for
>> the action, we can specify "transactional-cancel" as on/off,
>> defaulting to off. This maintains backwards compatible behavior.
>>
>>
>> As an example of a lone command (for simplicity...)
>>
>> { "execute": "transaction", "arguments": { "actions": [ {"type":
>> "drive-backup", "data": {"device": "drive0", "target":
>> "/path/to/new_full_backup.img", "sync": "full", "format":
>> "qcow2", "transactional-cancel": true } } ] } }
>>
>> This means that this command should fail if any of the other
>> block jobs in the transaction (that have also set
>> transactional-cancel(!)) fail.
>
> Just wondering - is there ever a case where someone would want to
> create a transaction with multiple sub-groups? That is, I want
> actions A, B, C, D to all occur at the same point in time, but with
> grouping [A,B] and [C, D] (so that if A fails B gets cancelled, but
> C and D can still
Only two sub-groups:
(A) actions that live and die together
(B) actions that proceed no matter what.
The only reason we even allow these two is because the default
behavior has been B historically, so we need to allow that to continue on.
I don't think we need to architect multiple subgroups of "live and die
together" semantics.
> continue)? Worse, is there a series of actions to accomplish
> something that cannot happen unless it is interleaved across
> multiple such subgroups?
>
Not sure we'll need to address this.
> Here's hoping that, for design simplicity, we only ever need one
> subgroup per 'transaction' (auto-cancel semantics applies to all
> commands in the group that opted in, with no way to further refine
> into sub-groups of commands).
>
I think this is correct.
>>
>> This is nice because it allows us to specify per-action which
>> actions should live or die on the success of the transaction as a
>> whole.
>>
>> What I was wondering is if we wanted to pidgeon-hole ourselves
>> like this by adding arguments per-action and instead opt for a
>> more generic, transaction-wide setting.
>>
>> In my mind, the transactional cancel has nothing to do with each
>> /specific/ action, but has more to do with a property of
>> transactions and actions in general.
>>
>>
>> So I was thinking of two things:
>>
>> (1) Transactional cancel, while false by default, could be
>> toggled to true by default for an entire transaction all-at-once
>>
>> { "execute": "transaction", "arguments": { "actions": [ ... ],
>> "transactional-cancel": true } }
>>
>> This would toggle the default state for all actions to "fail if
>> anything else in the transaction does."
>
> Or worded in another way - what is the use case for having a batch
> of actions where some commands are grouped-cancel, but the
> remaining actions are independent? Is there ever a case where you
> would supply "transactional-cancel":true to one action, but not all
> of them? If not, then this idea of hoisting the bool to the
> transaction arguments level makes more sense (it's an all-or-none
> switch, not a per-action switch).
>
> Qapi-wise, here's how you would do this:
>
> { 'command': 'transaction', 'data': { 'actions': [
> 'TransactionAction' ], '*transactional-cancel': 'bool' } }
>
Right. If there's no need for us to specify per-action settings at
all, this becomes the obvious "correct" solution.
If we do want to be able to specify this sub-grouping per-action (for
whatever reason), this might still be nice as a convenience feature.
>>
>> Of course, as of right now, not all actions actually support
>> this feature, but they might need to in the future -- and as more
>> and more actions use this feature, it might be nice to have the
>> global setting.
>>
>> If "transactional-cancel" was specified and is true (i.e. not
>> the default) and actions are provided that do not support the
>> argument explicitly, the transaction command itself should fail
>> up-front.
>
> This actually makes sense to me, and might be simpler to
> implement.
>
I'm not sure how to implement this, per-se, but in my mind it's
something like:
- A property of the transaction gets set (transactional-cancel) in
qmp_transaction.
- Each action has to prove that it has retrieved this value
- drive-backup of course actually uses it,
- other commands might fetch it to intentionally ignore it
(i.e. if cancel y/n would have no effect)
- If an action does not fetch this property, the transactional setup
flags an error and aborts the transaction with an error
- e.g. "Attempted to use property unsupported by action ..."
With perhaps an allowance that, as long as the property is set to
default, actions aren't required to check it.
>>
>> (2) Overridable per-action settings as a property of "action"
>>
>> Instead of adding the argument per-each action, bake it in as a
>> property of the action itself. The original idea behind this was
>> to decouple it from the QMP arguments definition, but this patch
>> here also accomplishes this -- at the expense of subclassing each
>> QMP argument set manually.
>>
>> Something like this is what I was originally thinking of doing:
>>
>> { "execute": "transaction", "arguments": { "actions": [ { "type":
>> "drive-backup", "data": { ... }, "properties": {
>> "transactional-cancel": true } } ] } }
>>
>> In light of how Fam and Eric solved the problem of "not polluting
>> the QMP arguments" for this patch, #2 is perhaps less pressing or
>> interesting.
>>
>> A benefit, though, is that we can define a set of generic
>> transactional action properties that all actions can inspect to
>> adjust their behavior without us needing to specify additional
>> argument subclasses in the QAPI every time.
>
> And here's how we'd do it in qapi. We'd have to convert
> TransactionAction from simple union into flat union (here, using
> syntax that doesn't work on qemu.git mainline, but requires my v5
> 00/46 mega-patch of introspection followups - hmm, it's still
> verbose, so maybe we want to invent yet more sugar to avoid having
> to declare all those wrapper types):
>
> { 'enum': 'TransactionActionKind', 'data': [
> 'blockdev-snapshot-sync', 'drive-backup', 'blockdev-backup',
> 'abort', 'blockdev-snapshot-internal-sync' ] } { 'struct':
> 'TransactionProperties', 'data': { '*transactional-cancel': 'bool'
> } } { 'struct': 'BlockdevSnapshotSyncWrapper', 'data': { 'data':
> 'BlockdevSnapshotSync' } } { 'union': 'TransactionAction', 'base':
> { 'type': 'TransactionActionKind', '*properties':
> 'TransactionProperties'}, 'discriminator': 'type', 'data': {
> 'blockdev-snapshot-sync': 'BlockdevSnapshotSyncWrapper', ... } }
>
>>
>> Mostly, at this point, I want to ask if we are OK with adding
>> the "transactional-cancel" argument ad-hoc per-action forever, or
>> if we'd like to allow a global setting or move the property "up
>> the stack" to some extent.
>>
>> Maybe the answer is "no," but I wanted to throw the idea out
>> there before we committed to an API.
>
> No, it's a good question. And adding it once at the 'transaction'
> layer or in the 'TransactionAction' union may indeed make more
> sense from the design perspective, rather than ad-hoc adding to
> each (growing) member of the union.
>
#2 was just another method of hoisting the QAPI arguments that are
transaction-specific away from the QMP arguments, and won't
necessarily be needed in conjunction with #1.
--js
next prev parent reply other threads:[~2015-09-22 23:27 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-22 2:46 [Qemu-devel] [PATCH v7 00/14] block: incremental backup transactions using BlockJobTxn Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 01/14] qapi: Add transaction support to block-dirty-bitmap operations Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 02/14] iotests: add transactional incremental backup test Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 03/14] block: rename BlkTransactionState and BdrvActionOps Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 04/14] backup: Extract dirty bitmap handling as a separate function Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 05/14] blockjob: Introduce reference count Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 06/14] blockjob: Add .commit and .abort block job actions Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 07/14] blockjob: Add "completed" and "ret" in BlockJob Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 08/14] blockjob: Simplify block_job_finish_sync Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 09/14] block: Add block job transactions Fam Zheng
2015-09-22 19:09 ` John Snow
2015-09-24 8:29 ` Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 10/14] blockdev: make BlockJobTxn available to qmp 'transaction' Fam Zheng
2015-09-22 19:13 ` John Snow
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 11/14] block/backup: support block job transactions Fam Zheng
2015-09-22 16:03 ` Eric Blake
2015-09-22 21:08 ` John Snow
2015-09-22 22:34 ` Eric Blake
2015-09-22 23:27 ` John Snow [this message]
2015-09-23 11:09 ` Markus Armbruster
2015-09-23 16:14 ` John Snow
2015-09-24 6:34 ` Markus Armbruster
2015-09-25 16:05 ` John Snow
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 12/14] iotests: 124 - transactional failure test Fam Zheng
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 13/14] qmp-commands.hx: Update the supported 'transaction' operations Fam Zheng
2015-09-30 18:56 ` John Snow
2015-10-01 10:57 ` Kashyap Chamarthy
2015-09-22 2:46 ` [Qemu-devel] [PATCH v7 14/14] tests: add BlockJobTxn unit test Fam Zheng
2015-09-22 23:33 ` John Snow
2015-09-22 20:48 ` [Qemu-devel] [PATCH v7 00/14] block: incremental backup transactions using BlockJobTxn John Snow
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=5601E3D0.90301@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=famz@redhat.com \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=vsementsov@parallels.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.