qemu-block
[Top][All Lists]
Advanced

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

Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] qapi: add transaction support


From: John Snow
Subject: Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] qapi: add transaction support for x-block-dirty-bitmap-merge
Date: Fri, 6 Jul 2018 11:38:34 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0


On 07/06/2018 06:12 AM, Vladimir Sementsov-Ogievskiy wrote:
> 
> Ok, let's go this way for now, I'll rewrite it.
> 
> Last requirement looks a bit strange for me in transaction context. We
> should not assume that action is done before commit.
> What is main idea of transaction action, do everything which will not
> fail in commit, or do everything which may be undone in prepare? Is
> there more formal way to manage dependencies between actions in one
> transaction?

Honestly, that's what I was wondering -- is there some formal model
people would be familiar with to help explain inter-dependencies between
transactional actions?

I don't know of one, presently, so I'm making it up as I go along.

I think this statement is intuitively true, though:

"For actions that are affected by other actions, the order of those two
actions matter, with the first action having an effect on the second."

We process actions in a linear order, first .prepare and then .commit --
so actions that come first in the list do have their callbacks executed
first. There's no way to express priority otherwise unless we give
certain actions a priority score, which we don't have right now.

Next, backup actions take ownership of the bitmap in .prepare()... so in
order for bitmap manipulation commands to affect these actions, they
also need to modify the bitmap in .prepare().

This may feel counter-intuitive to how transactions appear to be
designed to work, but on this subject Stefan said (May 2015):

> The ambiguity is whether "commit the changes" for .commit() means
> "changes take effect" or "discard stashed state, making undo
> impossible".
> 
> I think the "discard stashed state, making undo impossible"
> interpretation is good because .commit() is not allowed to fail.  That
> function should only do things that never fail.

I think this is probably the correct way to proceed, and we ought to
formalize this model. I think it's actually nearly impossible to do it
the other way around, too.

Let's say we've got two actions that both do error-checking in .prepare,
but perform their actual stateful changes in .commit, but are
interdependent.

{ a, b }

- a.prepare() checks state and confirms we will be able to proceed, but
changes no state.
- b.prepare() checks state and confirms it will be able to proceed, but
can't see what a is planning to do.
- a.commit() succeeds as expected.
- b.commit() does not fail as it is not allowed to, but the effects are
undetermined because we have not checked the state change from a.commit()

In general we can get around this, but the more actions we add, the
harder it is to do proper error checking while considering the
hypothetical state after some actions have committed.

I think the model where we take effect in .prepare() and undo it if
necessary in .abort() is actually easier to model in your head, because
error checking is simpler. That's probably the right model, then.



At the very least, I think that's correct for 3.0 and the immediate
future. If you disagree, please speak up because I've long been
particularly uncertain about this aspect.

--John



reply via email to

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