qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] BlockDriverState stack and BlockListeners


From: Paolo Bonzini
Subject: Re: [Qemu-devel] BlockDriverState stack and BlockListeners
Date: Tue, 21 Feb 2012 12:36:46 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.1) Gecko/20120209 Thunderbird/10.0.1

On 02/21/2012 11:51 AM, Kevin Wolf wrote:
> And even protocols and protocols don't. Compare file to blkdebug, for
> example. In fact, blkdebug and blkverify are already very close to what
> BlockListeners would be.

Yes, and I think considering blkdebug and blkverify help in the design.
They provide the difference between views and listeners: listeners can
be applied to both a protocol and a view, while views can only be
applied to a format.

> > - Protocols -- Protocols tell you where to get the raw bits.
> > - Formats -- Formats transform those raw bits into a block device.
> > - Views -- Views can move from a format to another.  A format can use a
> > default view implementation, or provide its own (e.g. to access
> > different snapshots).
> > - Listeners -- I think a view can have-a listener?
> 
> Where protocols, formats and listeners are-a image (Not the best name,
> I'm open for suggestions. Something like "BDS stack building block"
> would be most accurate...). Or actually not is-a in terms of
> inheritance, but I think it would be the very same thing without any
> subclassing, implemented by a BlockDriver.
> 
> > with the following relationship:
> > 
> > - A format has-a protocol for the raw bits and has-a view for the
> > backing file.
> 
> An image has-a image from which it takes its data (bs->file).

No. A protocol has neither an image below it, nor a backing file.  I
think a view has no backing file either (except as provided by the
format).  I'm not sure that a listener can have a backing file, either;
you could say that blkverify has one, but it could just as well have
three or four, so it's not the same thing.

A format does not do much more than create views, do snapshots, and hold
state that is common to all of its views.

So, let's put aside listeners for a moment, and consider this
alternative hierarchy:

BlockDriver
    Protocol
        FileProtocol
        ...
    View
        QCOW2View
        RawView
        ...
BlockFormat
    QCOW2Format
    RawFormat
    ...

Now we have to figure out how to fit listeners in this picture.

> And it has-a view for the backing file, yes. Both could be a listener.
> 
>> > - A view has-a format, a device has-a view.
>> > - A view can have-a listener?  Or is it formats?
> A view has-a image. This may happen to be a listener, which in turn
> has-a image (could be another listener, a format or a protocol).
> 
> The question is what the semantics is with live snapshots (there are
> probably similar problems, but this is the obvious one). For example we
> could now have:
> 
> mirror -> qcow2 -> blkdebug -> file

Let's be precise here:

mirror -> currentSnapshot -> qcow2 -> blkdebug -> file

- file is a protocol.

- blkdebug is a listener

- qcow2 is a format

- currentSnapshot is a view

- mirror is a listener

The difference between blkdebug/mirror on one side, and currentSnapshot
on the other, is that (as you said) blkdebug/mirror are always stacked
on top of something else. A driver that references currentSnapshot
actually gets mirror.

So we get to the actual hierarchy I'm proposing:

BlockDriver
    BlockSource (see below)
    Protocol (bdrv_file_open)
        FileProtocol
        ...
    View (has-a BlockFormat)
        QCOW2View
        RawView
        ...
    BlockListener (has-a BlockDriver)
        MirrorListener
        BlkDebugListener
BlockFormat (has-a BlockSource)
    QCOW2Format
    RawFormat
    ...

Protocols and views are only internal.  Formats and devices in practice
will only ever see BlockSources.  A BlockSource is a reference a stack of
BlockDrivers, where the base must be a protocol or view and there can
be a number of listeners stacked on top of it.  Listeners can be
added or removed from the stack, and the bottom driver can be swapped
for another (for snapshots).

So, here is how it would look:

  .== BlockSource ==.                   .== BlockSource ===.
  | MirrorListener  |                   | BlkDebugListener |
  | QCOW2View ------+--> QCOW2Format -> | FileProtocol     |
  '================='                   '=================='


> There are two listeners here, mirror and blkdebug. (Things like blkdebug
> are why view has-a listener isn't enough). After creating an external
> snapshot, we expect the graph to look like this (the arrow down is the
> backing file):
> 
> mirror -> qcow2 -> file
>             |
>             +-> qcow2 -> blkdebug -> file

And here:

  .== BlockSource ==.
  | MirrorListener  |                   .== BlockSource ==.
  | QCOW2View ------+--> QCOW2Format -> | FileProtocol    |
  '================='    |              '================='
                         |                                          .== 
BlockSource ===.
                         |   .== BlockSource ==.                    | 
BlkDebugListener |
                         '-> | QCOW2View ------+--> QCOW2Format --> | 
FileProtocol     |
                             '================='                    
'=================='

Does it seem sane?

> The question is: Can we assume that any listeners that are on top of the
> first format or protocol (i.e. those that would fit your model) should
> move to the new top-level view? Or would it sometimes make sense to keep
> it at the old one?

I think it depends, but both possibilities should be doable in this model.

Paolo



reply via email to

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