qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] block: format vs. protocol, and how they stack
@ 2010-06-18 12:59 Markus Armbruster
  2010-06-20 10:51 ` [Qemu-devel] " Avi Kivity
  0 siblings, 1 reply; 31+ messages in thread
From: Markus Armbruster @ 2010-06-18 12:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Christoph Hellwig, Luiz Capitulino, Avi Kivity,
	Gerd Hoffmann

The code is pretty confused about format vs. protocol, and so are we.
Let's try to figure them out.

>From cruising altitude, all this format, protocol, stacking business
doesn't matter.  We provide a bunch of arguments, and get an image.

If you look more closely, providing that image involves sub-tasks.  One
is to haul bits.  Another one is to translate between bits in different
formats.

Working hypothesis:

* A protocol hauls image bits.  Examples: file, host_device, nbd.

* A format translates image formats.  Examples: raw, qcow2.

Note: this does *not* follow the code's use of the terms.  It better
doesn't.  Because the code is confused.

Both protocol and format provide an image.  That's why we can and in
fact do have a common abstraction for them: BlockDriver.  Our data type
for a block driver instance is BlockDriverState.

Nothing stops a block driver to translate and haul at the same time.  We
generally separate the two jobs, because it lets us combine the
different ways to translate with the different ways to haul.
Nevertheless, a block driver *can* be both format and protocol.

Example: vvfat arguably both translates and hauls.

Let's call a format that isn't also protocol a pure format, and a
protocol that isn't also a format a pure protocol.

Obviously, pure formats need to sit on top of something providing images
to translate.  Formats don't care whether those somethings translate or
haul.  Therefore, a pure format is always stacked on one or more
BlockDriverStates.

Example: raw is always stacked one exactly one BlockDriverState (stored
in bs->file).

Example: qcow2 is always stacked on exactly two BlockDriverStates
(stored in bs->file and bs->backing_hd).

Conversely, anything that isn't stacked on any BlockDriverState can't be
a pure format, and thus must be a protocol.

Example: file hauls an ordinary file's bits, nbd hauls bits over TCP
using the NBD protocol.

Summary so far:

1. BlockDriverStates form a tree.

2. The leaves of the tree are protocols, not pure formats.

3. The non-leaf nodes may be anything.  We haven't found a reason why
   not.


In general, a block driver needs some arguments to create an instance.
The current code provides two BlockDriver methods for that:

* bdrv_open() takes a flags argument.

* bdrv_file_open() takes a flags argument and a filename argument.

This is woefully inadequate for anything but the simplest block drivers.
Any driver taking more complex arguments has to extract them out of the
"filename".

Example: http extracts url and optional readahead.

A saner interface would pass flags and a suitable argument dictionary
such as QemuOpts.


Now, let's review our existing interface to create such a tree of block
drivers.  Beware, royal mess ahead.

There are two interfaces.  The first one is bdrv_open().  It takes three
arguments: filename, flags and an optional block driver argument.

If flag BDRV_O_SNAPSHOT is set, we do snapshot magic.  Omitted here in
an attempt to protect reader sanity.

If the block driver is missing, we guess one.  More on that below.

The block driver is instantiated to set up the root of the tree.  Let's
call it the root block driver, and its instance bs.

If the root block driver provides method bdrv_file_open(), it is used,
and gets the flags and filename argument.

Else, we first instantiate *another* driver.

    We use the second interface for that: bdrv_file_open().  It takes
    filename and flags arguments like bdrv_open(), but no block driver
    argument.

    It chooses the block driver by looking at filename.  If filename
    names a host device, use the protocol for hauling that device's
    bits.  If it starts with P:, where P is some driver's
    "protocol_name", use that driver.  Else fail.  Except I just lied;
    the actual rules are messier than that.

    Unlike bdrv_open(), bdrv_file_open() ignores flag BDRV_O_SNAPSHOT,
    and always behaves as if flag BDRV_O_NO_BACKING was set.

We store the instance in bs->file.

Then the root block driver is instantiated with method bdrv_open().  It
gets the flags argument.  It stacks on top of bs->file, but that's mere
convention.

Note: one of the code's ideas on format vs. protocol is "protocols
provide bdrv_file_open(), formats do not".  I don't think that idea is
helpful.

The root block driver may ask for a backing file.  To do that, it sets
bs->backing_filename and optionally bs->backing_format, both strings.

Example: qcow2 reads the two strings from the image header.

We instantiate the backing file bs->backing_hd with bdrv_open().
Recursion.  Arguments: bs->backing_filename, flags derived from our own
flags argument, and the driver named by bs->backing_format.  If
bs->backing_format is unset, pick one just like -drive does when its
format option is unset.

The root block driver stacks on top of bs->backing_hd, by convention.

Flag BDRV_O_NO_BACKING supresses backing file setup, but let's ignore
that here.

This provides for common stacking, but it's not general.  Block drivers
can and do instantiate other block drivers on their own, for their
stacking needs.

Example: blkdebug instantiates bs->file with bdrv_file_open().  It
passes on its flags argument and the part of its filename argument it
doesn't use itself.


How could a saner interface look like?

An obvious interface for building trees lets you build bottom up: tree
node constructor takes children and whatever other arguments it needs.

COW backing files complicate matters.  We need to open the COW to find
its backing file information.  I'd build a tree without the backing file
normally, read the backing file information, create the tree for the
backing file, and attach it to the COW node.


Next, let's review the encoding of the filename argument.  It is decoded
in the block driver bdrv_file_open() methods.  Every block driver has
its own ad hoc encoding.

Example: file interprets it as a filename.

Example: nbd parses "nbd:" [ "unix:" filename | host ":" port ]

Additionally, bdrv_file_open() recognizes P: (see above).  This breaks
when the block driver's encoding is incompatible with that.

Examples:

    bdrv_open() arguments           behavior
    filename        block driver
    scruffy:duck    none            fails: no driver named "scruffy"
    scruffy:duck    bdrv_raw        fails: no driver named "scruffy"
    scruffy:duck    bdrv_file       bdrv_file uses file "scruffy:duck"
    fat:duck        none            bdrv_raw stacks onto
                                    bdrv_vvfat uses directory "duck"
    fat:duck        bdrv_raw        bdrv_raw stacks onto
                                    bdrv_vvfat uses directory "duck"
    fat:duck        bdrv_file       bdrv_file uses file "fat:duck"

Bizarre, isn't it?

More examples: try to use a qcow2 image named "fat:duck"

    bdrv_open() arguments           behavior
    filename        block driver
    fat:duck        qcow2           bdrv_qcow2 stacks onto
                                    bdrv_vvfat uses directory "duck"
                                    fails: vvfat2 doesn't provide a
                                    qcow2 image
    file:fat:duck   qcow2           bdrv_qcow2 stacks onto
                                    bdrv_file uses file "file:fat:duck"

Close, but no cigar.


-drive & friends expose this mess in the user interface as follows:

* They use bdrv_open().

* Option format selects its block driver argument.  It need not be a
  format.  Any block driver does.  Pearls like "format=file" confuse
  users (What format is "file"?  And what's the difference to "raw"?).
  Note that you need format=file if you have colons in your filenames.

* Option file is the filename argument.  It's not really a filename, but
  an encoding of block driver name and arguments.

  If the block driver selected by format makes bdrv_open() instantiate a
  second block driver (because it wants to stack on it), then this
  argument also selects that block driver.  But you can only select
  block drivers that support the funny colon syntax.

* Options snapshot, cache, aio, readonly are combined into the flags
  argument.

We need to think about a saner user interface, but I figure this message
is already plenty long, so I stop here.



[*] It must provide bdrv_file_open(), or else death by infinite
recursion (I think).

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-18 12:59 [Qemu-devel] block: format vs. protocol, and how they stack Markus Armbruster
@ 2010-06-20 10:51 ` Avi Kivity
  2010-06-21  7:00   ` Markus Armbruster
  2010-06-21  8:19   ` Kevin Wolf
  0 siblings, 2 replies; 31+ messages in thread
From: Avi Kivity @ 2010-06-20 10:51 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann

On 06/18/2010 03:59 PM, Markus Armbruster wrote:
> The code is pretty confused about format vs. protocol, and so are we.
> Let's try to figure them out.
>
>  From cruising altitude, all this format, protocol, stacking business
> doesn't matter.  We provide a bunch of arguments, and get an image.
>
> If you look more closely, providing that image involves sub-tasks.  One
> is to haul bits.  Another one is to translate between bits in different
> formats.
>
> Working hypothesis:
>
> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>
> * A format translates image formats.  Examples: raw, qcow2.
>
>    

Is there a reason to make the distinction?  Is there a reason to expose 
the distinction to the user?

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-20 10:51 ` [Qemu-devel] " Avi Kivity
@ 2010-06-21  7:00   ` Markus Armbruster
  2010-06-22 16:46     ` Jamie Lokier
  2010-06-21  8:19   ` Kevin Wolf
  1 sibling, 1 reply; 31+ messages in thread
From: Markus Armbruster @ 2010-06-21  7:00 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann

Avi Kivity <avi@redhat.com> writes:

> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>> The code is pretty confused about format vs. protocol, and so are we.
>> Let's try to figure them out.
>>
>>  From cruising altitude, all this format, protocol, stacking business
>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>
>> If you look more closely, providing that image involves sub-tasks.  One
>> is to haul bits.  Another one is to translate between bits in different
>> formats.
>>
>> Working hypothesis:
>>
>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>
>> * A format translates image formats.  Examples: raw, qcow2.
>>
>>    
>
> Is there a reason to make the distinction?  Is there a reason to
> expose the distinction to the user?

After thinking this through by writing a treatise on it, I've come to
the conclusion that we're confused about the distinction because it's
not a particularly useful one.

Evidence: I define the terms "format" and "protocol" in the first
section of my treatise.  They occur in later sections pretty much only
to explain problematic implementation details, or problematic user
interface.

Making the distinction may still be useful when reasoning about code,
e.g. the proper design of block drivers.

A possible reason why we currently expose format and protocol at the
user interface is to avoid stacking there.  Until blkdebug showed up, a
drive's "tree" of block drivers had one or two nodes.  Another "tree" of
one or two for COW's backing image, but those are configured separately.
Hardcoding configuration knobs for up to two block drivers avoids having
to deal with stacking.  We happen to call the two knobs "format" and
"protocol".  When blkdebug showed up, we shoehorned it into the existing
"protocol".

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-20 10:51 ` [Qemu-devel] " Avi Kivity
  2010-06-21  7:00   ` Markus Armbruster
@ 2010-06-21  8:19   ` Kevin Wolf
  2010-06-21 13:09     ` Anthony Liguori
  1 sibling, 1 reply; 31+ messages in thread
From: Kevin Wolf @ 2010-06-21  8:19 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Christoph Hellwig, qemu-devel, Markus Armbruster, Luiz Capitulino,
	Gerd Hoffmann

Am 20.06.2010 12:51, schrieb Avi Kivity:
> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>> The code is pretty confused about format vs. protocol, and so are we.
>> Let's try to figure them out.
>>
>>  From cruising altitude, all this format, protocol, stacking business
>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>
>> If you look more closely, providing that image involves sub-tasks.  One
>> is to haul bits.  Another one is to translate between bits in different
>> formats.
>>
>> Working hypothesis:
>>
>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>
>> * A format translates image formats.  Examples: raw, qcow2.
>>
>>    
> 
> Is there a reason to make the distinction?  Is there a reason to expose 
> the distinction to the user?

There are good reasons to make that distinction internally. There's no
need to expose it to the user - the question is if it helps or not.

Historically, format and protocol are defined like this (so in fact they
are user-visible currently):

* A format is what you specify as file=...
* A protocol is what is encoded in the file name

And I think as long as you have exactly one format and one protocol,
it's easier to understand than a chain of block drivers. But that's
really just about how to expose it.

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21  8:19   ` Kevin Wolf
@ 2010-06-21 13:09     ` Anthony Liguori
  2010-06-21 13:30       ` Kevin Wolf
  0 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 13:09 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/21/2010 03:19 AM, Kevin Wolf wrote:
> Am 20.06.2010 12:51, schrieb Avi Kivity:
>    
>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>      
>>> The code is pretty confused about format vs. protocol, and so are we.
>>> Let's try to figure them out.
>>>
>>>   From cruising altitude, all this format, protocol, stacking business
>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>
>>> If you look more closely, providing that image involves sub-tasks.  One
>>> is to haul bits.  Another one is to translate between bits in different
>>> formats.
>>>
>>> Working hypothesis:
>>>
>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>
>>> * A format translates image formats.  Examples: raw, qcow2.
>>>
>>>
>>>        
>> Is there a reason to make the distinction?  Is there a reason to expose
>> the distinction to the user?
>>      
> There are good reasons to make that distinction internally. There's no
> need to expose it to the user - the question is if it helps or not.
>    

If we drop the distinction, then I think the remaining issue is how to 
expose the stacking to a user.

Right now, we could have a syntax like:

-blockdev format=file,file=image.qcow2,id=base  \
-blockdev format=qcow2,backing_dev=base,id=blk1

backing_dev is a sucky name, but hopefully the point is clear.  I think 
the following would be a better user syntax:

-blockdev format=qcow2,file=image.qcow2,id=blk1

I think the easiest way to support this is to make qcow2 take a file 
parameter and have it open the file with default options.  For users 
that need anything more sophisticated a user has to use the former syntax.

We can still support format probing.  We should drop any support for 
parameter passing via file name too (with nbd and vfat).

Regards,

Anthony Liguori

> Historically, format and protocol are defined like this (so in fact they
> are user-visible currently):
>
> * A format is what you specify as file=...
> * A protocol is what is encoded in the file name
>
> And I think as long as you have exactly one format and one protocol,
> it's easier to understand than a chain of block drivers. But that's
> really just about how to expose it.
>
> Kevin
>    

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 13:09     ` Anthony Liguori
@ 2010-06-21 13:30       ` Kevin Wolf
  2010-06-21 13:37         ` Anthony Liguori
  0 siblings, 1 reply; 31+ messages in thread
From: Kevin Wolf @ 2010-06-21 13:30 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Am 21.06.2010 15:09, schrieb Anthony Liguori:
> On 06/21/2010 03:19 AM, Kevin Wolf wrote:
>> Am 20.06.2010 12:51, schrieb Avi Kivity:
>>    
>>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>>      
>>>> The code is pretty confused about format vs. protocol, and so are we.
>>>> Let's try to figure them out.
>>>>
>>>>   From cruising altitude, all this format, protocol, stacking business
>>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>>
>>>> If you look more closely, providing that image involves sub-tasks.  One
>>>> is to haul bits.  Another one is to translate between bits in different
>>>> formats.
>>>>
>>>> Working hypothesis:
>>>>
>>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>>
>>>> * A format translates image formats.  Examples: raw, qcow2.
>>>>
>>>>
>>>>        
>>> Is there a reason to make the distinction?  Is there a reason to expose
>>> the distinction to the user?
>>>      
>> There are good reasons to make that distinction internally. There's no
>> need to expose it to the user - the question is if it helps or not.
>>    
> 
> If we drop the distinction, then I think the remaining issue is how to 
> expose the stacking to a user.
> 
> Right now, we could have a syntax like:
> 
> -blockdev format=file,file=image.qcow2,id=base  \
> -blockdev format=qcow2,backing_dev=base,id=blk1
> 
> backing_dev is a sucky name, but hopefully the point is clear.  I think 
> the following would be a better user syntax:
> 
> -blockdev format=qcow2,file=image.qcow2,id=blk1
> 
> I think the easiest way to support this is to make qcow2 take a file 
> parameter and have it open the file with default options.  For users 
> that need anything more sophisticated a user has to use the former syntax.

Not only qcow2, but also raw, qcow, vmdk, vdi, bochs, cow, dmg, ...

In short: Any format needs an underlying protocol. You may not call it
by its name, but that's effectively what you'd implement. And if you
implemented it in each format driver instead of generic code, you'd be
doing a bad implementation.

The more I think about it, the more I believe that the logic of how qemu
handles things is made much clearer if we actually call it by its name
and expose the distinction to the user.

"If there is no protocol specified, qemu will pick one automatically"
vs. "If you specify an image in raw, qcow2, qcow, vmdk, vdi, bochs, cow,
dmg or blkdebug format and you have no backing_dev specified, qemu will
pick one automatically; it won't do so for images in file, host_device,
host_flopy, host_cdrom, nbd, http or vvfat format." It's an easy choice.

> We can still support format probing.  We should drop any support for 
> parameter passing via file name too (with nbd and vfat).

For -blockdev, agreed. We need to retain it with -drive, though.

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 13:30       ` Kevin Wolf
@ 2010-06-21 13:37         ` Anthony Liguori
  2010-06-21 14:01           ` Kevin Wolf
  0 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 13:37 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/21/2010 08:30 AM, Kevin Wolf wrote:
> Am 21.06.2010 15:09, schrieb Anthony Liguori:
>    
>> On 06/21/2010 03:19 AM, Kevin Wolf wrote:
>>      
>>> Am 20.06.2010 12:51, schrieb Avi Kivity:
>>>
>>>        
>>>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>>>
>>>>          
>>>>> The code is pretty confused about format vs. protocol, and so are we.
>>>>> Let's try to figure them out.
>>>>>
>>>>>    From cruising altitude, all this format, protocol, stacking business
>>>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>>>
>>>>> If you look more closely, providing that image involves sub-tasks.  One
>>>>> is to haul bits.  Another one is to translate between bits in different
>>>>> formats.
>>>>>
>>>>> Working hypothesis:
>>>>>
>>>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>>>
>>>>> * A format translates image formats.  Examples: raw, qcow2.
>>>>>
>>>>>
>>>>>
>>>>>            
>>>> Is there a reason to make the distinction?  Is there a reason to expose
>>>> the distinction to the user?
>>>>
>>>>          
>>> There are good reasons to make that distinction internally. There's no
>>> need to expose it to the user - the question is if it helps or not.
>>>
>>>        
>> If we drop the distinction, then I think the remaining issue is how to
>> expose the stacking to a user.
>>
>> Right now, we could have a syntax like:
>>
>> -blockdev format=file,file=image.qcow2,id=base  \
>> -blockdev format=qcow2,backing_dev=base,id=blk1
>>
>> backing_dev is a sucky name, but hopefully the point is clear.  I think
>> the following would be a better user syntax:
>>
>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>>
>> I think the easiest way to support this is to make qcow2 take a file
>> parameter and have it open the file with default options.  For users
>> that need anything more sophisticated a user has to use the former syntax.
>>      
> Not only qcow2, but also raw, qcow, vmdk, vdi, bochs, cow, dmg, ...
>
> In short: Any format needs an underlying protocol. You may not call it
> by its name, but that's effectively what you'd implement. And if you
> implemented it in each format driver instead of generic code, you'd be
> doing a bad implementation.
>    

Sure.  I don't think it would be all that difficult to implement in 
common code.

> The more I think about it, the more I believe that the logic of how qemu
> handles things is made much clearer if we actually call it by its name
> and expose the distinction to the user.
>
> "If there is no protocol specified, qemu will pick one automatically"
> vs. "If you specify an image in raw, qcow2, qcow, vmdk, vdi, bochs, cow,
> dmg or blkdebug format and you have no backing_dev specified, qemu will
> pick one automatically; it won't do so for images in file, host_device,
> host_flopy, host_cdrom, nbd, http or vvfat format." It's an easy choice.
>    

Are you basically saying:

[1] -blockdev format=qcow2,protocol=file,file=foo.img,id=blk1

Because what I was suggesting is that we don't allow protocol=XX here.  
We would try to guess the protocol from foo.img.  If a user wishes to 
override this, they should do the full syntax of:

[2] -blockdev protocol=host_dev,file=/dev/sda,id=base \
-blockdev format=qcow2,backing_dev=base,id=blk1

But we're also suggesting s/protocol/format/ because the distinction 
doesn't seem to be important unless you try to support syntax [1] and 
you need a mechanism to specify the leaf format (which you're calling a 
protocol).

Regards,

Anthony Liguori

>> We can still support format probing.  We should drop any support for
>> parameter passing via file name too (with nbd and vfat).
>>      
> For -blockdev, agreed. We need to retain it with -drive, though.
>
> Kevin
>    

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 13:37         ` Anthony Liguori
@ 2010-06-21 14:01           ` Kevin Wolf
  2010-06-21 14:51             ` Anthony Liguori
                               ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Kevin Wolf @ 2010-06-21 14:01 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Am 21.06.2010 15:37, schrieb Anthony Liguori:
> On 06/21/2010 08:30 AM, Kevin Wolf wrote:
>> Am 21.06.2010 15:09, schrieb Anthony Liguori:
>>    
>>> On 06/21/2010 03:19 AM, Kevin Wolf wrote:
>>>      
>>>> Am 20.06.2010 12:51, schrieb Avi Kivity:
>>>>
>>>>        
>>>>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>>>>
>>>>>          
>>>>>> The code is pretty confused about format vs. protocol, and so are we.
>>>>>> Let's try to figure them out.
>>>>>>
>>>>>>    From cruising altitude, all this format, protocol, stacking business
>>>>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>>>>
>>>>>> If you look more closely, providing that image involves sub-tasks.  One
>>>>>> is to haul bits.  Another one is to translate between bits in different
>>>>>> formats.
>>>>>>
>>>>>> Working hypothesis:
>>>>>>
>>>>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>>>>
>>>>>> * A format translates image formats.  Examples: raw, qcow2.
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> Is there a reason to make the distinction?  Is there a reason to expose
>>>>> the distinction to the user?
>>>>>
>>>>>          
>>>> There are good reasons to make that distinction internally. There's no
>>>> need to expose it to the user - the question is if it helps or not.
>>>>
>>>>        
>>> If we drop the distinction, then I think the remaining issue is how to
>>> expose the stacking to a user.
>>>
>>> Right now, we could have a syntax like:
>>>
>>> -blockdev format=file,file=image.qcow2,id=base  \
>>> -blockdev format=qcow2,backing_dev=base,id=blk1
>>>
>>> backing_dev is a sucky name, but hopefully the point is clear.  I think
>>> the following would be a better user syntax:
>>>
>>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>
>>> I think the easiest way to support this is to make qcow2 take a file
>>> parameter and have it open the file with default options.  For users
>>> that need anything more sophisticated a user has to use the former syntax.
>>>      
>> Not only qcow2, but also raw, qcow, vmdk, vdi, bochs, cow, dmg, ...
>>
>> In short: Any format needs an underlying protocol. You may not call it
>> by its name, but that's effectively what you'd implement. And if you
>> implemented it in each format driver instead of generic code, you'd be
>> doing a bad implementation.
>>    
> 
> Sure.  I don't think it would be all that difficult to implement in 
> common code.

Probably not. I mean, if you ignore blkdebug for a moment, this is
what's implemented today. But it makes a difference between formats and
protocols: If you say format=qcow2, you get qcow2 on file. If you say
format=file, you get just file with no other protocol because file is
already one (I think what you really should get is an error message, but
that's another topic...)

>> The more I think about it, the more I believe that the logic of how qemu
>> handles things is made much clearer if we actually call it by its name
>> and expose the distinction to the user.
>>
>> "If there is no protocol specified, qemu will pick one automatically"
>> vs. "If you specify an image in raw, qcow2, qcow, vmdk, vdi, bochs, cow,
>> dmg or blkdebug format and you have no backing_dev specified, qemu will
>> pick one automatically; it won't do so for images in file, host_device,
>> host_flopy, host_cdrom, nbd, http or vvfat format." It's an easy choice.
>>    
> 
> Are you basically saying:
> 
> [1] -blockdev format=qcow2,protocol=file,file=foo.img,id=blk1
> 
> Because what I was suggesting is that we don't allow protocol=XX here.  
> We would try to guess the protocol from foo.img.  If a user wishes to 
> override this, they should do the full syntax of:
> 
> [2] -blockdev protocol=host_dev,file=/dev/sda,id=base \
> -blockdev format=qcow2,backing_dev=base,id=blk1

No, what I'm saying is that even in your model

  -blockdev format=qcow2,file=image.qcow2,id=blk1

becomes qcow2 -> file automatically, whereas

  -blockdev format=vvfat,file=/tmp/dir/,id=blk1

doesn't become vvfat -> file, but stays just vvfat.

This is the difference between a protocol and a format. The logic is
that you need one protocol and if you don't specify it explicitly, qemu
will guess it.

If you decide to avoid calling them format and protocol, you need to
talk about "raw, qcow2, qcow2, vmdk, ..." instead of "format" and about
"file, host_device, ..." instead of "protocol" - because you have
removed the terms, but not the concepts.

I think the user interface is clearer if we call them by their name.

> But we're also suggesting s/protocol/format/ because the distinction 
> doesn't seem to be important unless you try to support syntax [1] and 
> you need a mechanism to specify the leaf format (which you're calling a 
> protocol).

Syntax [1] would be a nice abbreviation when you need to specify the
protocol explicitly, but it's not what decides about the concept.

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 14:01           ` Kevin Wolf
@ 2010-06-21 14:51             ` Anthony Liguori
  2010-06-21 14:52               ` Anthony Liguori
  2010-06-21 15:00               ` Christoph Hellwig
  2010-06-21 15:34             ` Anthony Liguori
  2010-06-21 15:56             ` Markus Armbruster
  2 siblings, 2 replies; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 14:51 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/21/2010 09:01 AM, Kevin Wolf wrote:
> Am 21.06.2010 15:37, schrieb Anthony Liguori:
>    
>> On 06/21/2010 08:30 AM, Kevin Wolf wrote:
>>      
>>> Am 21.06.2010 15:09, schrieb Anthony Liguori:
>>>
>>>        
>>>> On 06/21/2010 03:19 AM, Kevin Wolf wrote:
>>>>
>>>>          
>>>>> Am 20.06.2010 12:51, schrieb Avi Kivity:
>>>>>
>>>>>
>>>>>            
>>>>>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>>>>>
>>>>>>
>>>>>>              
>>>>>>> The code is pretty confused about format vs. protocol, and so are we.
>>>>>>> Let's try to figure them out.
>>>>>>>
>>>>>>>     From cruising altitude, all this format, protocol, stacking business
>>>>>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>>>>>
>>>>>>> If you look more closely, providing that image involves sub-tasks.  One
>>>>>>> is to haul bits.  Another one is to translate between bits in different
>>>>>>> formats.
>>>>>>>
>>>>>>> Working hypothesis:
>>>>>>>
>>>>>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>>>>>
>>>>>>> * A format translates image formats.  Examples: raw, qcow2.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>> Is there a reason to make the distinction?  Is there a reason to expose
>>>>>> the distinction to the user?
>>>>>>
>>>>>>
>>>>>>              
>>>>> There are good reasons to make that distinction internally. There's no
>>>>> need to expose it to the user - the question is if it helps or not.
>>>>>
>>>>>
>>>>>            
>>>> If we drop the distinction, then I think the remaining issue is how to
>>>> expose the stacking to a user.
>>>>
>>>> Right now, we could have a syntax like:
>>>>
>>>> -blockdev format=file,file=image.qcow2,id=base  \
>>>> -blockdev format=qcow2,backing_dev=base,id=blk1
>>>>
>>>> backing_dev is a sucky name, but hopefully the point is clear.  I think
>>>> the following would be a better user syntax:
>>>>
>>>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>>
>>>> I think the easiest way to support this is to make qcow2 take a file
>>>> parameter and have it open the file with default options.  For users
>>>> that need anything more sophisticated a user has to use the former syntax.
>>>>
>>>>          
>>> Not only qcow2, but also raw, qcow, vmdk, vdi, bochs, cow, dmg, ...
>>>
>>> In short: Any format needs an underlying protocol. You may not call it
>>> by its name, but that's effectively what you'd implement. And if you
>>> implemented it in each format driver instead of generic code, you'd be
>>> doing a bad implementation.
>>>
>>>        
>> Sure.  I don't think it would be all that difficult to implement in
>> common code.
>>      
> Probably not. I mean, if you ignore blkdebug for a moment, this is
> what's implemented today. But it makes a difference between formats and
> protocols: If you say format=qcow2, you get qcow2 on file. If you say
> format=file, you get just file with no other protocol because file is
> already one (I think what you really should get is an error message, but
> that's another topic...)
>
>    
>>> The more I think about it, the more I believe that the logic of how qemu
>>> handles things is made much clearer if we actually call it by its name
>>> and expose the distinction to the user.
>>>
>>> "If there is no protocol specified, qemu will pick one automatically"
>>> vs. "If you specify an image in raw, qcow2, qcow, vmdk, vdi, bochs, cow,
>>> dmg or blkdebug format and you have no backing_dev specified, qemu will
>>> pick one automatically; it won't do so for images in file, host_device,
>>> host_flopy, host_cdrom, nbd, http or vvfat format." It's an easy choice.
>>>
>>>        
>> Are you basically saying:
>>
>> [1] -blockdev format=qcow2,protocol=file,file=foo.img,id=blk1
>>
>> Because what I was suggesting is that we don't allow protocol=XX here.
>> We would try to guess the protocol from foo.img.  If a user wishes to
>> override this, they should do the full syntax of:
>>
>> [2] -blockdev protocol=host_dev,file=/dev/sda,id=base \
>> -blockdev format=qcow2,backing_dev=base,id=blk1
>>      
> No, what I'm saying is that even in your model
>
>    -blockdev format=qcow2,file=image.qcow2,id=blk1
>
> becomes qcow2 ->  file automatically, whereas
>
>    -blockdev format=vvfat,file=/tmp/dir/,id=blk1
>
> doesn't become vvfat ->  file, but stays just vvfat.
>
> This is the difference between a protocol and a format.

I can appreciate the desire to keep protocols and formats as an internal 
distinction but as a user visible concept, I think your two examples 
highlight why exposing protocols as formats make sense.  A user doesn't 
necessarily care what's happening under the cover.  I think:

-blockdev format=qcow2,file=image.qcow2,id=blk1

and:

-blockdev protocol=vvfat,file=/tmp/dir,id=blk1

Would cause a bit of confusion.  It's not immediately clear why vvfat is 
a protocol and qcow2 isn't.  It's really an implementation detail that 
we implement qcow2 on top of a "protocol" called file.

>   The logic is
> that you need one protocol and if you don't specify it explicitly, qemu
> will guess it.
>
> If you decide to avoid calling them format and protocol, you need to
> talk about "raw, qcow2, qcow2, vmdk, ..." instead of "format" and about
> "file, host_device, ..." instead of "protocol" - because you have
> removed the terms, but not the concepts.
>    

 From the user interface.  For the internal implementation, if you think 
we should distinguish protocols from formats, I think that's a fair 
thing to do.

> I think the user interface is clearer if we call them by their name.
>    

I think the user interface for you is clearer, but for the majority of 
users including most developers without intimate knowledge of the block 
layer, the distinction will only lead to confusion.

>> But we're also suggesting s/protocol/format/ because the distinction
>> doesn't seem to be important unless you try to support syntax [1] and
>> you need a mechanism to specify the leaf format (which you're calling a
>> protocol).
>>      
> Syntax [1] would be a nice abbreviation when you need to specify the
> protocol explicitly, but it's not what decides about the concept.
>    

I don't think specifying the protocol explicitly is an extremely common 
use case but if you disagree, we can certainly consider abbreviated 
syntax.  I agree though that this is not core to the concepts.

Regards,

Anthony Liguori

> Kevin
>    

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 14:51             ` Anthony Liguori
@ 2010-06-21 14:52               ` Anthony Liguori
  2010-06-21 15:00               ` Christoph Hellwig
  1 sibling, 0 replies; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 14:52 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/21/2010 09:51 AM, Anthony Liguori wrote:
>> This is the difference between a protocol and a format.
>
>
> I can appreciate the desire to keep protocols and formats as an 
> internal distinction but as a user visible concept,

but *not* as a user visible concept.  /me heads for the second cup of 
coffee.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 14:51             ` Anthony Liguori
  2010-06-21 14:52               ` Anthony Liguori
@ 2010-06-21 15:00               ` Christoph Hellwig
  2010-06-21 15:22                 ` Paul Brook
                                   ` (3 more replies)
  1 sibling, 4 replies; 31+ messages in thread
From: Christoph Hellwig @ 2010-06-21 15:00 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Markus Armbruster,
	Luiz Capitulino, Gerd Hoffmann, Avi Kivity

On Mon, Jun 21, 2010 at 09:51:23AM -0500, Anthony Liguori wrote:
> I can appreciate the desire to keep protocols and formats as an internal 
> distinction but as a user visible concept, I think your two examples 
> highlight why exposing protocols as formats make sense.  A user doesn't 
> necessarily care what's happening under the cover.  I think:
> 
> -blockdev format=qcow2,file=image.qcow2,id=blk1
> 
> and:
> 
> -blockdev protocol=vvfat,file=/tmp/dir,id=blk1
> 
> Would cause a bit of confusion.  It's not immediately clear why vvfat is 
> a protocol and qcow2 isn't.  It's really an implementation detail that 
> we implement qcow2 on top of a "protocol" called file.

Everything involving vvfat will end up in sheer confusion, and that's
because vvfat is such a beast.  But it's a rather traditional example
of a "protocol".  Unlike qcow2 / vmdk / vpc it can not be stacked on
an arbitrary protocol (file/nbd/http), but rather accessed a directory
tree.  vvfat then makes up something that looks like a file so upper
levels can use it like that.  As far as qemu is concerned you can then
use any format on top of it, but given that it fakes up a fat filesystem
that format better be raw to make sense.

What about renaming the protocol a transport?  It seems like a lot
of issues here seem to resolve around naming.

The user basically can specify two things:

 - a transport protocol.  Normally this is just the filesystem
   interface, but it can also be nbd, http or for really sick people
   vvfat.  This is a setting which can't be guessed, btw - it needs
   to be explicitly set in some way, with file used as a reasonable
   fallback.

 - an image format.  This one interprets the content the transport
   protocol delivers to us.  This can either be raw for not interpreting
   it all, or things like qcow2 / vmdk to add more functionality to it.

Keeping these separate makes a lot of sense to me, even with my user
hat on.  And as lon as we don't require the transport protocol but fall
back to file it's even more understandable for the users, as he simply
doesn't have to care about it for the 99% case.  Now for the image
format specifying it usually is a good thing as the autodetecting could
easily get into trouble when the guest creates say a full-device qcow2
image in a device that's an image file on the host.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:00               ` Christoph Hellwig
@ 2010-06-21 15:22                 ` Paul Brook
  2010-06-21 15:37                 ` Anthony Liguori
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 31+ messages in thread
From: Paul Brook @ 2010-06-21 15:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Christoph Hellwig, Markus Armbruster, Luiz Capitulino,
	Gerd Hoffmann, Christoph Hellwig, Avi Kivity

> The user basically can specify two things:
> 
>  - a transport protocol.  Normally this is just the filesystem
>    interface, but it can also be nbd, http or for really sick people
>    vvfat.  This is a setting which can't be guessed, btw - it needs
>    to be explicitly set in some way, with file used as a reasonable
>    fallback.
>
>  - an image format.  This one interprets the content the transport
>    protocol delivers to us.  This can either be raw for not interpreting
>    it all, or things like qcow2 / vmdk to add more functionality to it.

Makes sense to me.

In theory we should be able to stack image formats. In practice it's probably 
not very useful with the current set of formats, so may not be worth the 
hassle. The best way to implement it may be to add a "blockdev" transport.

Paul

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 14:01           ` Kevin Wolf
  2010-06-21 14:51             ` Anthony Liguori
@ 2010-06-21 15:34             ` Anthony Liguori
  2010-06-22  8:10               ` Kevin Wolf
  2010-06-21 15:56             ` Markus Armbruster
  2 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 15:34 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/21/2010 09:01 AM, Kevin Wolf wrote:
>
> No, what I'm saying is that even in your model
>
>    -blockdev format=qcow2,file=image.qcow2,id=blk1
>
> becomes qcow2 ->  file automatically, whereas
>
>    -blockdev format=vvfat,file=/tmp/dir/,id=blk1
>
> doesn't become vvfat ->  file, but stays just vvfat.
>    

I should say, that -blockdev format= vs. -blockdev transport= is 
definitely at a place where I don't care that much.

The things that I think are most important are:

1) That we have structured options that map well to config file without 
trickery to do nesting
2) That we don't automagically pass options through from the first layer 
down to subsequent layers

I think we're pretty much agreed here so while I think it's worth 
discussing whether format or transport should be exposed to the user, it 
shouldn't stop someone from coding something up and submitting it.  
Either way would be a vast improvement over what we have now.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:00               ` Christoph Hellwig
  2010-06-21 15:22                 ` Paul Brook
@ 2010-06-21 15:37                 ` Anthony Liguori
  2010-06-21 16:01                   ` Christoph Hellwig
  2010-06-21 16:21                 ` Markus Armbruster
  2010-06-22 16:30                 ` Jamie Lokier
  3 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 15:37 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Markus Armbruster,
	Luiz Capitulino, Gerd Hoffmann, Avi Kivity

On 06/21/2010 10:00 AM, Christoph Hellwig wrote:
> Keeping these separate makes a lot of sense to me, even with my user
> hat on.  And as lon as we don't require the transport protocol but fall
> back to file it's even more understandable for the users, as he simply
> doesn't have to care about it for the 99% case.  Now for the image
> format specifying it usually is a good thing as the autodetecting could
> easily get into trouble when the guest creates say a full-device qcow2
> image in a device that's an image file on the host.
>    

I agree that transport makes a lot more sense.

There's just a couple cases we should consider:

[1] -blockdev format=raw,file=/dev/cdrom,id=blk1

[2] -blockdev format=vvfat,file=/path/to/directory,id=blk1

For [1], we just defaulting transport to file is would not give us the 
same semantics we have today.  Is that desirable?

It's not clear to me why [2] should be transport=vvfat.  vvfat really 
isn't a transport.  What about things like blkdebug and if we had 
something like a ramdisk?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 14:01           ` Kevin Wolf
  2010-06-21 14:51             ` Anthony Liguori
  2010-06-21 15:34             ` Anthony Liguori
@ 2010-06-21 15:56             ` Markus Armbruster
  2010-06-22  8:22               ` Kevin Wolf
  2 siblings, 1 reply; 31+ messages in thread
From: Markus Armbruster @ 2010-06-21 15:56 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, qemu-devel, Luiz Capitulino, Gerd Hoffmann,
	Avi Kivity

Kevin Wolf <kwolf@redhat.com> writes:

> Am 21.06.2010 15:37, schrieb Anthony Liguori:
>> On 06/21/2010 08:30 AM, Kevin Wolf wrote:
>>> Am 21.06.2010 15:09, schrieb Anthony Liguori:
>>>    
>>>> On 06/21/2010 03:19 AM, Kevin Wolf wrote:
>>>>      
>>>>> Am 20.06.2010 12:51, schrieb Avi Kivity:
>>>>>
>>>>>        
>>>>>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>>>>>
>>>>>>          
>>>>>>> The code is pretty confused about format vs. protocol, and so are we.
>>>>>>> Let's try to figure them out.
>>>>>>>
>>>>>>>    From cruising altitude, all this format, protocol, stacking business
>>>>>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>>>>>
>>>>>>> If you look more closely, providing that image involves sub-tasks.  One
>>>>>>> is to haul bits.  Another one is to translate between bits in different
>>>>>>> formats.
>>>>>>>
>>>>>>> Working hypothesis:
>>>>>>>
>>>>>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>>>>>
>>>>>>> * A format translates image formats.  Examples: raw, qcow2.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>            
>>>>>> Is there a reason to make the distinction?  Is there a reason to expose
>>>>>> the distinction to the user?
>>>>>>
>>>>>>          
>>>>> There are good reasons to make that distinction internally. There's no
>>>>> need to expose it to the user - the question is if it helps or not.
>>>>>
>>>>>        
>>>> If we drop the distinction, then I think the remaining issue is how to
>>>> expose the stacking to a user.
>>>>
>>>> Right now, we could have a syntax like:
>>>>
>>>> -blockdev format=file,file=image.qcow2,id=base  \
>>>> -blockdev format=qcow2,backing_dev=base,id=blk1
>>>>
>>>> backing_dev is a sucky name, but hopefully the point is clear.  I think
>>>> the following would be a better user syntax:
>>>>
>>>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>>
>>>> I think the easiest way to support this is to make qcow2 take a file
>>>> parameter and have it open the file with default options.  For users
>>>> that need anything more sophisticated a user has to use the former syntax.
>>>>      
>>> Not only qcow2, but also raw, qcow, vmdk, vdi, bochs, cow, dmg, ...
>>>
>>> In short: Any format needs an underlying protocol. You may not call it
>>> by its name, but that's effectively what you'd implement. And if you
>>> implemented it in each format driver instead of generic code, you'd be
>>> doing a bad implementation.
>>>    
>> 
>> Sure.  I don't think it would be all that difficult to implement in 
>> common code.
>
> Probably not. I mean, if you ignore blkdebug for a moment, this is
> what's implemented today. But it makes a difference between formats and
> protocols: If you say format=qcow2, you get qcow2 on file. If you say
> format=file, you get just file with no other protocol because file is
> already one

There you go, talking about format and protocol again :)

>             (I think what you really should get is an error message, but
> that's another topic...)

I disagree.  "file" by itself is a perfectly valid block driver tree.

>>> The more I think about it, the more I believe that the logic of how qemu
>>> handles things is made much clearer if we actually call it by its name
>>> and expose the distinction to the user.
>>>
>>> "If there is no protocol specified, qemu will pick one automatically"
>>> vs. "If you specify an image in raw, qcow2, qcow, vmdk, vdi, bochs, cow,
>>> dmg or blkdebug format and you have no backing_dev specified, qemu will
>>> pick one automatically; it won't do so for images in file, host_device,
>>> host_flopy, host_cdrom, nbd, http or vvfat format." It's an easy choice.

We hardly need "protocol" to do better than that :)

First of all, "formats" do not need "protocols".  That's merely a
special case.  Instead, block drivers need children (tree parlance).
Backing devices, if you will.

We can and should provide useful defaults and shortcuts.  Instead of "If
there is no protocol", say "to configure a block driver's child, you can
do X, Y or Z", where one of the options provides full control, and
others are shortcuts.  For instance, filename=F could be a shortcut for
"let QEMU auto-configure a block driver appropriate for file F".

The "protocol" parlance breaks down when we move away from the simple
stuff.  For instance, qcow2 needs two children: the block driver
providing the delta bits (in qcow2 format), and the block driver
providing the base bits (whose configuration happens to be stored in the
delta bits).  All qcow2 wants from them is access to bits.  It doesn't
care about format vs. protocol at all.  In fact, the driver for the base
bits is commonly what you'd call a format.  Even the driver for the
delta bits could be a format.  As long as the bits it provides are valid
qcow2, the qcow2 driver won't mind.

[...]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:37                 ` Anthony Liguori
@ 2010-06-21 16:01                   ` Christoph Hellwig
  2010-06-21 16:09                     ` Anthony Liguori
  2010-06-21 16:36                     ` Markus Armbruster
  0 siblings, 2 replies; 31+ messages in thread
From: Christoph Hellwig @ 2010-06-21 16:01 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Markus Armbruster,
	Luiz Capitulino, Gerd Hoffmann, Christoph Hellwig, Avi Kivity

On Mon, Jun 21, 2010 at 10:37:37AM -0500, Anthony Liguori wrote:
> There's just a couple cases we should consider:
> 
> [1] -blockdev format=raw,file=/dev/cdrom,id=blk1

> For [1], we just defaulting transport to file is would not give us the 
> same semantics we have today.  Is that desirable?

By mentioning the host devices you're opening another can of worms here.
The host devices are another special case which is a rather problematic.
I think the best we can do is to eliminate the different protocols for
the host devices and fold them into file.  For one the basic host
device Blockdriver really doesn't make any sense to be different from
file.  The only differences are:

 - host_device sets the no_zero_init flag.  This is something we could easily
   do per-instance with an S_ISCHR || S_ISBLK check in the right place
 - host_device has a different ->create method.  Instead of truncating
   the file to the image size it does an llseek to figure if the new
   size fits.  Again, this could be one method with an S_ISCHR || S_ISBLK
   block check.  (and btw, the llseek seems to be wrong for some weirded
   unix variants, compare to raw_getlength).
 - host_device implements the ioctl and aio_ioctl methods.  We'll need
   them for file anyway once my discard support lands.

Now what's more interesting than the plain host_device are the magic
cdrom and floppy devices.  These offer bdrv_is_inserted /
bdrv_media_changed / bdrv_eject eject methods, and once it a while do
some magic in bdrv_open.  We could easily key those off with a small
host_device_operations structure inside raw-posix.c (which should be
rename file-posix.c these days).  That would make the whole model a
lot more consistent, and we could get rid of all the device probing
special casing in the block layer which, which is a complete mess
due to the Windows vs Unix differences.


> [2] -blockdev format=vvfat,file=/path/to/directory,id=blk1
> 
> 
> It's not clear to me why [2] should be transport=vvfat.  vvfat really 
> isn't a transport.

Well, it's a wart if you want to be exact.  But in the above model
it's a clearly a transport.  It does not take an arbitrary BlockDriver
on the layer below it but implements it's own I/O methods not using the
qemu block layer - it maps from an image file the filesystem namespace.
Similar to file connects to a file on the local system and nbd/http
connects an image on a remote system.

> What about things like blkdebug and if we had 
> something like a ramdisk?

A ramdisk again is a transport into a file that's purely in-memory.
You can trivially run any format we have ontop of it.

blkdebug in it's current form is a trivial image format, just like raw
in the above terminology.  It takes an arbitrary qemu BlockDriver as
input and then stacks on top.

Think of a protocol/transport as the thing that implements the lowest
layer of the qemu block I/O stack which then maps to native I/O methods.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 16:01                   ` Christoph Hellwig
@ 2010-06-21 16:09                     ` Anthony Liguori
  2010-06-21 16:36                     ` Markus Armbruster
  1 sibling, 0 replies; 31+ messages in thread
From: Anthony Liguori @ 2010-06-21 16:09 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kevin Wolf, Christoph Hellwig, Markus Armbruster, qemu-devel,
	Luiz Capitulino, Gerd Hoffmann, Avi Kivity

On 06/21/2010 11:01 AM, Christoph Hellwig wrote:
> On Mon, Jun 21, 2010 at 10:37:37AM -0500, Anthony Liguori wrote:
>    
>> There's just a couple cases we should consider:
>>
>> [1] -blockdev format=raw,file=/dev/cdrom,id=blk1
>>      
>    
>> For [1], we just defaulting transport to file is would not give us the
>> same semantics we have today.  Is that desirable?
>>      
> By mentioning the host devices you're opening another can of worms here.
> The host devices are another special case which is a rather problematic.
> I think the best we can do is to eliminate the different protocols for
> the host devices and fold them into file.  For one the basic host
> device Blockdriver really doesn't make any sense to be different from
> file.  The only differences are:
>
>   - host_device sets the no_zero_init flag.  This is something we could easily
>     do per-instance with an S_ISCHR || S_ISBLK check in the right place
>   - host_device has a different ->create method.  Instead of truncating
>     the file to the image size it does an llseek to figure if the new
>     size fits.  Again, this could be one method with an S_ISCHR || S_ISBLK
>     block check.  (and btw, the llseek seems to be wrong for some weirded
>     unix variants, compare to raw_getlength).
>   - host_device implements the ioctl and aio_ioctl methods.  We'll need
>     them for file anyway once my discard support lands.
>
> Now what's more interesting than the plain host_device are the magic
> cdrom and floppy devices.  These offer bdrv_is_inserted /
> bdrv_media_changed / bdrv_eject eject methods, and once it a while do
> some magic in bdrv_open.  We could easily key those off with a small
> host_device_operations structure inside raw-posix.c (which should be
> rename file-posix.c these days).  That would make the whole model a
> lot more consistent, and we could get rid of all the device probing
> special casing in the block layer which, which is a complete mess
> due to the Windows vs Unix differences.
>    

I fully agree here.  The result would be a much cleaner distinction 
between format and transport once you get rid of the host device stuff.

>> [2] -blockdev format=vvfat,file=/path/to/directory,id=blk1
>>
>>
>> It's not clear to me why [2] should be transport=vvfat.  vvfat really
>> isn't a transport.
>>      
> Well, it's a wart if you want to be exact.  But in the above model
> it's a clearly a transport.  It does not take an arbitrary BlockDriver
> on the layer below it but implements it's own I/O methods not using the
> qemu block layer - it maps from an image file the filesystem namespace.
> Similar to file connects to a file on the local system and nbd/http
> connects an image on a remote system.
>
>    
>> What about things like blkdebug and if we had
>> something like a ramdisk?
>>      
> A ramdisk again is a transport into a file that's purely in-memory.
> You can trivially run any format we have ontop of it.
>
> blkdebug in it's current form is a trivial image format, just like raw
> in the above terminology.  It takes an arbitrary qemu BlockDriver as
> input and then stacks on top.
>
> Think of a protocol/transport as the thing that implements the lowest
> layer of the qemu block I/O stack which then maps to native I/O methods.
>    

Yes, we're back to the whole discussion of leaf vs. non-leaf nodes.  The 
fundamental question is, why make this distinction visible to the user?  
Why does the user care if something is a leaf vs. a non-leaf node?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:00               ` Christoph Hellwig
  2010-06-21 15:22                 ` Paul Brook
  2010-06-21 15:37                 ` Anthony Liguori
@ 2010-06-21 16:21                 ` Markus Armbruster
  2010-06-22  8:32                   ` Kevin Wolf
  2010-06-28 10:28                   ` Christoph Hellwig
  2010-06-22 16:30                 ` Jamie Lokier
  3 siblings, 2 replies; 31+ messages in thread
From: Markus Armbruster @ 2010-06-21 16:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Christoph Hellwig <hch@lst.de> writes:

> On Mon, Jun 21, 2010 at 09:51:23AM -0500, Anthony Liguori wrote:
>> I can appreciate the desire to keep protocols and formats as an internal 
>> distinction but as a user visible concept, I think your two examples 
>> highlight why exposing protocols as formats make sense.  A user doesn't 
>> necessarily care what's happening under the cover.  I think:
>> 
>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>> 
>> and:
>> 
>> -blockdev protocol=vvfat,file=/tmp/dir,id=blk1
>> 
>> Would cause a bit of confusion.  It's not immediately clear why vvfat is 
>> a protocol and qcow2 isn't.  It's really an implementation detail that 
>> we implement qcow2 on top of a "protocol" called file.
>
> Everything involving vvfat will end up in sheer confusion, and that's
> because vvfat is such a beast.

Yes, vvfat doesn't fit the format/protocol model very well, but that's
because that model sucks :)

vvfat is a block driver.  A block driver requires a number of children.
For vvfat that number is zero.  It can only be a leaf in the block
driver tree.

As with any block driver, you can stack another block driver on top of
it (the parent, in tree parlance).  Also as with any block driver, the
parent might not like the bits it gets from the child.  Yes, stacking
qcow2 on vvfat doesn't work.  Just like stacking qcow2 on your old DOS
partition.

>                                 But it's a rather traditional example
> of a "protocol".  Unlike qcow2 / vmdk / vpc it can not be stacked on
> an arbitrary protocol (file/nbd/http), but rather accessed a directory
> tree.  vvfat then makes up something that looks like a file so upper
> levels can use it like that.  As far as qemu is concerned you can then
> use any format on top of it, but given that it fakes up a fat filesystem
> that format better be raw to make sense.
>
> What about renaming the protocol a transport?  It seems like a lot
> of issues here seem to resolve around naming.
>
> The user basically can specify two things:
>
>  - a transport protocol.  Normally this is just the filesystem
>    interface, but it can also be nbd, http or for really sick people
>    vvfat.  This is a setting which can't be guessed, btw - it needs
>    to be explicitly set in some way, with file used as a reasonable
>    fallback.
>
>  - an image format.  This one interprets the content the transport
>    protocol delivers to us.  This can either be raw for not interpreting
>    it all, or things like qcow2 / vmdk to add more functionality to it.

You describe the special case where format and protocol make some sense:
you have a block driver that can transport bits in arbitrary formats,
and a block driver that interprets bits without caring for transport.

In the general case, we have things like vvfat that make people wonder
whether it's a format or a protocol.  You can't stack it onto a
transport, so it can't be a format!  You can't stack a format on it, so
it can't be a protocol!

[...]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 16:01                   ` Christoph Hellwig
  2010-06-21 16:09                     ` Anthony Liguori
@ 2010-06-21 16:36                     ` Markus Armbruster
  1 sibling, 0 replies; 31+ messages in thread
From: Markus Armbruster @ 2010-06-21 16:36 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Christoph Hellwig <hch@lst.de> writes:

> On Mon, Jun 21, 2010 at 10:37:37AM -0500, Anthony Liguori wrote:
[...]
>> [2] -blockdev format=vvfat,file=/path/to/directory,id=blk1
>> 
>> 
>> It's not clear to me why [2] should be transport=vvfat.  vvfat really 
>> isn't a transport.
>
> Well, it's a wart if you want to be exact.  But in the above model
> it's a clearly a transport.  It does not take an arbitrary BlockDriver
> on the layer below it but implements it's own I/O methods not using the
> qemu block layer - it maps from an image file the filesystem namespace.
> Similar to file connects to a file on the local system and nbd/http
> connects an image on a remote system.
>
>> What about things like blkdebug and if we had 
>> something like a ramdisk?
>
> A ramdisk again is a transport into a file that's purely in-memory.
> You can trivially run any format we have ontop of it.
>
> blkdebug in it's current form is a trivial image format, just like raw
> in the above terminology.  It takes an arbitrary qemu BlockDriver as
> input and then stacks on top.

blkdebug could be viewed as transport just as well: it transports bits
in arbitrary formats.  In your own words: "You can trivially run any
format we have ontop of it."

> Think of a protocol/transport as the thing that implements the lowest
> layer of the qemu block I/O stack which then maps to native I/O methods.

We're still discussing whether a certain block driver is a "format" or a
"protocol".  And we're still disagreeing.

I don't think the format vs. protocol distinction is useful.

The job at hand is to configure a tree of block drivers.  In QMP, HMP,
command line and config file.

For QMP, why don't we do just that?  Trees are perfectly natural there,
and arbitrarily dividing trees into format and protocol parts only
complicates things.

For the rest, let's rely on sensible defaults and perhaps a few shortcut
forms for common cases.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:34             ` Anthony Liguori
@ 2010-06-22  8:10               ` Kevin Wolf
  2010-06-22 12:39                 ` Anthony Liguori
  0 siblings, 1 reply; 31+ messages in thread
From: Kevin Wolf @ 2010-06-22  8:10 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Am 21.06.2010 17:34, schrieb Anthony Liguori:
> On 06/21/2010 09:01 AM, Kevin Wolf wrote:
>>
>> No, what I'm saying is that even in your model
>>
>>    -blockdev format=qcow2,file=image.qcow2,id=blk1
>>
>> becomes qcow2 ->  file automatically, whereas
>>
>>    -blockdev format=vvfat,file=/tmp/dir/,id=blk1
>>
>> doesn't become vvfat ->  file, but stays just vvfat.
>>    
> 
> I should say, that -blockdev format= vs. -blockdev transport= is 
> definitely at a place where I don't care that much.
> 
> The things that I think are most important are:
> 
> 1) That we have structured options that map well to config file without 
> trickery to do nesting
> 2) That we don't automagically pass options through from the first layer 
> down to subsequent layers

Does this mean that you need to specify the protocol explicitly for any
non-trivial case? So if you want to use just default for everything you
can use

  -blockdev id=foo,format=qcow2,file=foo.qcow2

and it will be turned into something sensible automagically (namely
adding a file blockdev underneath and passing the file parameter to that
one), but if you want to change an option, you need to specify both?

  -blockdev id=foo,format=qcow2,parent=foo_file
  -blockdev id=foo_file,format=file,file=foo.qcow2,cache=off

What about read-only? Is it something that must be specified for each
single node in the chain to actually get the right semantics?

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:56             ` Markus Armbruster
@ 2010-06-22  8:22               ` Kevin Wolf
  2010-06-22 16:40                 ` Jamie Lokier
  0 siblings, 1 reply; 31+ messages in thread
From: Kevin Wolf @ 2010-06-22  8:22 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Christoph Hellwig, qemu-devel, Luiz Capitulino, Gerd Hoffmann,
	Avi Kivity

Am 21.06.2010 17:56, schrieb Markus Armbruster:
> Kevin Wolf <kwolf@redhat.com> writes:
> 
>> Am 21.06.2010 15:37, schrieb Anthony Liguori:
>>> On 06/21/2010 08:30 AM, Kevin Wolf wrote:
>>>> Am 21.06.2010 15:09, schrieb Anthony Liguori:
>>>>    
>>>>> On 06/21/2010 03:19 AM, Kevin Wolf wrote:
>>>>>      
>>>>>> Am 20.06.2010 12:51, schrieb Avi Kivity:
>>>>>>
>>>>>>        
>>>>>>> On 06/18/2010 03:59 PM, Markus Armbruster wrote:
>>>>>>>
>>>>>>>          
>>>>>>>> The code is pretty confused about format vs. protocol, and so are we.
>>>>>>>> Let's try to figure them out.
>>>>>>>>
>>>>>>>>    From cruising altitude, all this format, protocol, stacking business
>>>>>>>> doesn't matter.  We provide a bunch of arguments, and get an image.
>>>>>>>>
>>>>>>>> If you look more closely, providing that image involves sub-tasks.  One
>>>>>>>> is to haul bits.  Another one is to translate between bits in different
>>>>>>>> formats.
>>>>>>>>
>>>>>>>> Working hypothesis:
>>>>>>>>
>>>>>>>> * A protocol hauls image bits.  Examples: file, host_device, nbd.
>>>>>>>>
>>>>>>>> * A format translates image formats.  Examples: raw, qcow2.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>            
>>>>>>> Is there a reason to make the distinction?  Is there a reason to expose
>>>>>>> the distinction to the user?
>>>>>>>
>>>>>>>          
>>>>>> There are good reasons to make that distinction internally. There's no
>>>>>> need to expose it to the user - the question is if it helps or not.
>>>>>>
>>>>>>        
>>>>> If we drop the distinction, then I think the remaining issue is how to
>>>>> expose the stacking to a user.
>>>>>
>>>>> Right now, we could have a syntax like:
>>>>>
>>>>> -blockdev format=file,file=image.qcow2,id=base  \
>>>>> -blockdev format=qcow2,backing_dev=base,id=blk1
>>>>>
>>>>> backing_dev is a sucky name, but hopefully the point is clear.  I think
>>>>> the following would be a better user syntax:
>>>>>
>>>>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>>>
>>>>> I think the easiest way to support this is to make qcow2 take a file
>>>>> parameter and have it open the file with default options.  For users
>>>>> that need anything more sophisticated a user has to use the former syntax.
>>>>>      
>>>> Not only qcow2, but also raw, qcow, vmdk, vdi, bochs, cow, dmg, ...
>>>>
>>>> In short: Any format needs an underlying protocol. You may not call it
>>>> by its name, but that's effectively what you'd implement. And if you
>>>> implemented it in each format driver instead of generic code, you'd be
>>>> doing a bad implementation.
>>>>    
>>>
>>> Sure.  I don't think it would be all that difficult to implement in 
>>> common code.
>>
>> Probably not. I mean, if you ignore blkdebug for a moment, this is
>> what's implemented today. But it makes a difference between formats and
>> protocols: If you say format=qcow2, you get qcow2 on file. If you say
>> format=file, you get just file with no other protocol because file is
>> already one
> 
> There you go, talking about format and protocol again :)

I'm happy to hear about your theory why there's a difference when
protocols and formats are the same. So...?

>>             (I think what you really should get is an error message, but
>> that's another topic...)
> 
> I disagree.  "file" by itself is a perfectly valid block driver tree.
> 
>>>> The more I think about it, the more I believe that the logic of how qemu
>>>> handles things is made much clearer if we actually call it by its name
>>>> and expose the distinction to the user.
>>>>
>>>> "If there is no protocol specified, qemu will pick one automatically"
>>>> vs. "If you specify an image in raw, qcow2, qcow, vmdk, vdi, bochs, cow,
>>>> dmg or blkdebug format and you have no backing_dev specified, qemu will
>>>> pick one automatically; it won't do so for images in file, host_device,
>>>> host_flopy, host_cdrom, nbd, http or vvfat format." It's an easy choice.
> 
> We hardly need "protocol" to do better than that :)
> 
> First of all, "formats" do not need "protocols".  That's merely a
> special case.  Instead, block drivers need children (tree parlance).
> Backing devices, if you will.

Some block drivers do (formats), others don't (protcols/transports).

> We can and should provide useful defaults and shortcuts.  Instead of "If
> there is no protocol", say "to configure a block driver's child, you can
> do X, Y or Z", where one of the options provides full control, and
> others are shortcuts.  For instance, filename=F could be a shortcut for
> "let QEMU auto-configure a block driver appropriate for file F".
> 
> The "protocol" parlance breaks down when we move away from the simple
> stuff.  For instance, qcow2 needs two children: the block driver
> providing the delta bits (in qcow2 format), and the block driver
> providing the base bits (whose configuration happens to be stored in the
> delta bits).  

Backing files are different. When talking about opening images (which is
what we do here) the main difference is that they can be opened only
after the image itself has been opened. I don't think we should include
them in this discussion.

> All qcow2 wants from them is access to bits.  It doesn't
> care about format vs. protocol at all.  In fact, the driver for the base
> bits is commonly what you'd call a format.  Even the driver for the
> delta bits could be a format.  As long as the bits it provides are valid
> qcow2, the qcow2 driver won't mind.

Right, why should it mind if there's one layer or two layers under it?
Where the difference matters is opening images.

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 16:21                 ` Markus Armbruster
@ 2010-06-22  8:32                   ` Kevin Wolf
  2010-06-22 14:24                     ` Markus Armbruster
  2010-06-28 10:28                   ` Christoph Hellwig
  1 sibling, 1 reply; 31+ messages in thread
From: Kevin Wolf @ 2010-06-22  8:32 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Christoph Hellwig, qemu-devel, Luiz Capitulino, Gerd Hoffmann,
	Christoph Hellwig, Avi Kivity

Am 21.06.2010 18:21, schrieb Markus Armbruster:
> Christoph Hellwig <hch@lst.de> writes:
> 
>> On Mon, Jun 21, 2010 at 09:51:23AM -0500, Anthony Liguori wrote:
>>> I can appreciate the desire to keep protocols and formats as an internal 
>>> distinction but as a user visible concept, I think your two examples 
>>> highlight why exposing protocols as formats make sense.  A user doesn't 
>>> necessarily care what's happening under the cover.  I think:
>>>
>>> -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>
>>> and:
>>>
>>> -blockdev protocol=vvfat,file=/tmp/dir,id=blk1
>>>
>>> Would cause a bit of confusion.  It's not immediately clear why vvfat is 
>>> a protocol and qcow2 isn't.  It's really an implementation detail that 
>>> we implement qcow2 on top of a "protocol" called file.
>>
>> Everything involving vvfat will end up in sheer confusion, and that's
>> because vvfat is such a beast.
> 
> Yes, vvfat doesn't fit the format/protocol model very well, but that's
> because that model sucks :)

What's the different between vvfat and accessing a FAT image via nbd
(except that vvfat is broken)? It's clearly a protocol/transport, as
Christoph already said.

> vvfat is a block driver.  A block driver requires a number of children.
> For vvfat that number is zero.  It can only be a leaf in the block
> driver tree.
> 
> As with any block driver, you can stack another block driver on top of
> it (the parent, in tree parlance).  Also as with any block driver, the
> parent might not like the bits it gets from the child.  Yes, stacking
> qcow2 on vvfat doesn't work.  Just like stacking qcow2 on your old DOS
> partition.
> 
>>                                 But it's a rather traditional example
>> of a "protocol".  Unlike qcow2 / vmdk / vpc it can not be stacked on
>> an arbitrary protocol (file/nbd/http), but rather accessed a directory
>> tree.  vvfat then makes up something that looks like a file so upper
>> levels can use it like that.  As far as qemu is concerned you can then
>> use any format on top of it, but given that it fakes up a fat filesystem
>> that format better be raw to make sense.
>>
>> What about renaming the protocol a transport?  It seems like a lot
>> of issues here seem to resolve around naming.
>>
>> The user basically can specify two things:
>>
>>  - a transport protocol.  Normally this is just the filesystem
>>    interface, but it can also be nbd, http or for really sick people
>>    vvfat.  This is a setting which can't be guessed, btw - it needs
>>    to be explicitly set in some way, with file used as a reasonable
>>    fallback.
>>
>>  - an image format.  This one interprets the content the transport
>>    protocol delivers to us.  This can either be raw for not interpreting
>>    it all, or things like qcow2 / vmdk to add more functionality to it.
> 
> You describe the special case where format and protocol make some sense:
> you have a block driver that can transport bits in arbitrary formats,
> and a block driver that interprets bits without caring for transport.

No, that's not a special case. It's the only case there is.

> In the general case, we have things like vvfat that make people wonder
> whether it's a format or a protocol.  You can't stack it onto a
> transport, so it can't be a format!  You can't stack a format on it, so
> it can't be a protocol!

Sure you can stack formats on it. raw and blkdebug are the ones that
will be happy with the data that vvfat provides.

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-22  8:10               ` Kevin Wolf
@ 2010-06-22 12:39                 ` Anthony Liguori
  2010-06-22 12:57                   ` Kevin Wolf
  0 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2010-06-22 12:39 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/22/2010 03:10 AM, Kevin Wolf wrote:
> Am 21.06.2010 17:34, schrieb Anthony Liguori:
>    
>> On 06/21/2010 09:01 AM, Kevin Wolf wrote:
>>      
>>> No, what I'm saying is that even in your model
>>>
>>>     -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>
>>> becomes qcow2 ->   file automatically, whereas
>>>
>>>     -blockdev format=vvfat,file=/tmp/dir/,id=blk1
>>>
>>> doesn't become vvfat ->   file, but stays just vvfat.
>>>
>>>        
>> I should say, that -blockdev format= vs. -blockdev transport= is
>> definitely at a place where I don't care that much.
>>
>> The things that I think are most important are:
>>
>> 1) That we have structured options that map well to config file without
>> trickery to do nesting
>> 2) That we don't automagically pass options through from the first layer
>> down to subsequent layers
>>      
> Does this mean that you need to specify the protocol explicitly for any
> non-trivial case? So if you want to use just default for everything you
> can use
>
>    -blockdev id=foo,format=qcow2,file=foo.qcow2
>    

Yes.  I think we should explicitly support an option like file.

> and it will be turned into something sensible automagically (namely
> adding a file blockdev underneath and passing the file parameter to that
> one), but if you want to change an option, you need to specify both?
>
>    -blockdev id=foo,format=qcow2,parent=foo_file
>    -blockdev id=foo_file,format=file,file=foo.qcow2,cache=off
>
> What about read-only?

Good question.  If a user specifies file, I think the (or generic block 
layer) should have wide latitude to decide how to creating that backing 
format which could include propagating options that it thinks are 
reasonable (like readonly).

My concern is seeing something like:

-blockdev id=foo,format=qcow2,file=blah.img,funkyopt=value

or:

-blockdev id=foo,format=qcow2,protocol=[file=blah.img,funkyopt=value]

I think the later syntax is overwhelming.  If the semantics of the 
former syntax is "passthrough any options we don't understand at this 
layer", I'm afraid it gets too confusing about which level actually 
processed the option (and it certainly doesn't deal with propagation).

Regards,

Anthony Liguori

>   Is it something that must be specified for each
> single node in the chain to actually get the right semantics?
>
> Kevin
>    

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-22 12:39                 ` Anthony Liguori
@ 2010-06-22 12:57                   ` Kevin Wolf
  2010-06-22 13:07                     ` Anthony Liguori
  0 siblings, 1 reply; 31+ messages in thread
From: Kevin Wolf @ 2010-06-22 12:57 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Am 22.06.2010 14:39, schrieb Anthony Liguori:
> On 06/22/2010 03:10 AM, Kevin Wolf wrote:
>> Am 21.06.2010 17:34, schrieb Anthony Liguori:
>>    
>>> On 06/21/2010 09:01 AM, Kevin Wolf wrote:
>>>      
>>>> No, what I'm saying is that even in your model
>>>>
>>>>     -blockdev format=qcow2,file=image.qcow2,id=blk1
>>>>
>>>> becomes qcow2 ->   file automatically, whereas
>>>>
>>>>     -blockdev format=vvfat,file=/tmp/dir/,id=blk1
>>>>
>>>> doesn't become vvfat ->   file, but stays just vvfat.
>>>>
>>>>        
>>> I should say, that -blockdev format= vs. -blockdev transport= is
>>> definitely at a place where I don't care that much.
>>>
>>> The things that I think are most important are:
>>>
>>> 1) That we have structured options that map well to config file without
>>> trickery to do nesting
>>> 2) That we don't automagically pass options through from the first layer
>>> down to subsequent layers
>>>      
>> Does this mean that you need to specify the protocol explicitly for any
>> non-trivial case? So if you want to use just default for everything you
>> can use
>>
>>    -blockdev id=foo,format=qcow2,file=foo.qcow2
>>    
> 
> Yes.  I think we should explicitly support an option like file.

Makes sense. I don't really like adding some special magic for file, but
I do see that it's a requirement to make at least the simplest case easy
- and this was about the only clear result of my discussion with Markus
before he posted his proposal.

>> and it will be turned into something sensible automagically (namely
>> adding a file blockdev underneath and passing the file parameter to that
>> one), but if you want to change an option, you need to specify both?
>>
>>    -blockdev id=foo,format=qcow2,parent=foo_file
>>    -blockdev id=foo_file,format=file,file=foo.qcow2,cache=off
>>
>> What about read-only?
> 
> Good question.  If a user specifies file, I think the (or generic block 
> layer) should have wide latitude to decide how to creating that backing 
> format which could include propagating options that it thinks are 
> reasonable (like readonly).

Right, if we get to use a default value, we can propagate things that
the generic block layer knows. However, as soon as someone specifies a
protocol explicitly, he'll need to add readonly=on to each -blockdev in
the chain?

> My concern is seeing something like:
> 
> -blockdev id=foo,format=qcow2,file=blah.img,funkyopt=value
> 
> or:
> 
> -blockdev id=foo,format=qcow2,protocol=[file=blah.img,funkyopt=value]
> 
> I think the later syntax is overwhelming.  If the semantics of the 
> former syntax is "passthrough any options we don't understand at this 
> layer", I'm afraid it gets too confusing about which level actually 
> processed the option (and it certainly doesn't deal with propagation).

The former involves definitely too much magic for assigning the options
to the right blockdev. The latter would be more comprehensible, but
isn't really nice either.

On the other hand, funkyopt might be something as common as cache, and
I'd hate to require specifying the protocol explicitly in a second
-blockdev referenced by another ID when you just want to change the
cache option.

Kevin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-22 12:57                   ` Kevin Wolf
@ 2010-06-22 13:07                     ` Anthony Liguori
  0 siblings, 0 replies; 31+ messages in thread
From: Anthony Liguori @ 2010-06-22 13:07 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, Markus Armbruster, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

On 06/22/2010 07:57 AM, Kevin Wolf wrote:
>>> and it will be turned into something sensible automagically (namely
>>> adding a file blockdev underneath and passing the file parameter to that
>>> one), but if you want to change an option, you need to specify both?
>>>
>>>     -blockdev id=foo,format=qcow2,parent=foo_file
>>>     -blockdev id=foo_file,format=file,file=foo.qcow2,cache=off
>>>
>>> What about read-only?
>>>        
>> Good question.  If a user specifies file, I think the (or generic block
>> layer) should have wide latitude to decide how to creating that backing
>> format which could include propagating options that it thinks are
>> reasonable (like readonly).
>>      
> Right, if we get to use a default value, we can propagate things that
> the generic block layer knows. However, as soon as someone specifies a
> protocol explicitly, he'll need to add readonly=on to each -blockdev in
> the chain?
>    

Yes.  I think once you do an explicit option, you have to be very careful.

>> My concern is seeing something like:
>>
>> -blockdev id=foo,format=qcow2,file=blah.img,funkyopt=value
>>
>> or:
>>
>> -blockdev id=foo,format=qcow2,protocol=[file=blah.img,funkyopt=value]
>>
>> I think the later syntax is overwhelming.  If the semantics of the
>> former syntax is "passthrough any options we don't understand at this
>> layer", I'm afraid it gets too confusing about which level actually
>> processed the option (and it certainly doesn't deal with propagation).
>>      
> The former involves definitely too much magic for assigning the options
> to the right blockdev. The latter would be more comprehensible, but
> isn't really nice either.
>
> On the other hand, funkyopt might be something as common as cache, and
> I'd hate to require specifying the protocol explicitly in a second
> -blockdev referenced by another ID when you just want to change the
> cache option.
>    

I understand the concern but I think one of the big problems with -drive 
and bdrv_open today is they are far too magical.  We shouldn't make the 
same mistake again.

We ought to keep in my the 80/20 rule.  In this case, I'm fairly certain 
that it's closer to 99% of users are only doing 1% of what is actually 
possible and generally that's going to either be -hda foo.img or 
-blockdev file=foo.img,option=value.

Regards,

Anthony Liguori

> Kevin
>    

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-22  8:32                   ` Kevin Wolf
@ 2010-06-22 14:24                     ` Markus Armbruster
  0 siblings, 0 replies; 31+ messages in thread
From: Markus Armbruster @ 2010-06-22 14:24 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, qemu-devel, Luiz Capitulino, Gerd Hoffmann,
	Christoph Hellwig, Avi Kivity

Kevin Wolf <kwolf@redhat.com> writes:

> Am 21.06.2010 18:21, schrieb Markus Armbruster:
>> Christoph Hellwig <hch@lst.de> writes:
>> 
[...]
>>> The user basically can specify two things:
>>>
>>>  - a transport protocol.  Normally this is just the filesystem
>>>    interface, but it can also be nbd, http or for really sick people
>>>    vvfat.  This is a setting which can't be guessed, btw - it needs
>>>    to be explicitly set in some way, with file used as a reasonable
>>>    fallback.
>>>
>>>  - an image format.  This one interprets the content the transport
>>>    protocol delivers to us.  This can either be raw for not interpreting
>>>    it all, or things like qcow2 / vmdk to add more functionality to it.
>> 
>> You describe the special case where format and protocol make some sense:
>> you have a block driver that can transport bits in arbitrary formats,
>> and a block driver that interprets bits without caring for transport.
>
> No, that's not a special case. It's the only case there is.
>
>> In the general case, we have things like vvfat that make people wonder
>> whether it's a format or a protocol.  You can't stack it onto a
>> transport, so it can't be a format!  You can't stack a format on it, so
>> it can't be a protocol!
>
> Sure you can stack formats on it. raw and blkdebug are the ones that
> will be happy with the data that vvfat provides.

You can stack raw and blkdebug on *anything*.  And that includes qcow2.
Does that make qcow2 a protocol?  Are we running in circles yet?  :)

I've come the conclusion that distinguishing between format and protocol
doesn't help.  It only breeds confusion (and e-mail, lots of e-mail).
I've rethought blockdev_add, and I think I can do quite well without
format and protocol.  Let me try that in practice.  I'll post revised
docs & code when I have them.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 15:00               ` Christoph Hellwig
                                   ` (2 preceding siblings ...)
  2010-06-21 16:21                 ` Markus Armbruster
@ 2010-06-22 16:30                 ` Jamie Lokier
  3 siblings, 0 replies; 31+ messages in thread
From: Jamie Lokier @ 2010-06-22 16:30 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kevin Wolf, Christoph Hellwig, Markus Armbruster, qemu-devel,
	Luiz Capitulino, Gerd Hoffmann, Avi Kivity

Christoph Hellwig wrote:
> On Mon, Jun 21, 2010 at 09:51:23AM -0500, Anthony Liguori wrote:
> > I can appreciate the desire to keep protocols and formats as an internal 
> > distinction but as a user visible concept, I think your two examples 
> > highlight why exposing protocols as formats make sense.  A user doesn't 
> > necessarily care what's happening under the cover.  I think:
> > 
> > -blockdev format=qcow2,file=image.qcow2,id=blk1
> > 
> > and:
> > 
> > -blockdev protocol=vvfat,file=/tmp/dir,id=blk1
> > 
> > Would cause a bit of confusion.  It's not immediately clear why vvfat is 
> > a protocol and qcow2 isn't.  It's really an implementation detail that 
> > we implement qcow2 on top of a "protocol" called file.
> 
> Everything involving vvfat will end up in sheer confusion, and that's
> because vvfat is such a beast.  But it's a rather traditional example
> of a "protocol".  Unlike qcow2 / vmdk / vpc it can not be stacked on
> an arbitrary protocol (file/nbd/http), but rather accessed a directory
> tree.

There is no technical reason why vvfat couldn't be stacked on top of
FTP or HTTP-DAV or RSYNC or SCP, or even "wget -R".  Basically
anything with multiple files addressed by paths, and a way to retrieve
directories to find all the paths.

vvfat doesn't stack on top of "file-like protocols", it stacks
conceptually on top of "directory tree-like protocols", of which there
is currently one.  The arrival of Plan9fs may motivate the addition of
more.

You can't meaningfully stack "qcow2" or any other format than "raw" on
top of the virtual file image created by vvfat.  So that's another reason
it isn't the same as other "protocols".

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-22  8:22               ` Kevin Wolf
@ 2010-06-22 16:40                 ` Jamie Lokier
  2010-06-22 16:56                   ` Daniel P. Berrange
  0 siblings, 1 reply; 31+ messages in thread
From: Jamie Lokier @ 2010-06-22 16:40 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Christoph Hellwig, qemu-devel, Markus Armbruster, Luiz Capitulino,
	Avi Kivity, Gerd Hoffmann

Kevin Wolf wrote:
> > The "protocol" parlance breaks down when we move away from the simple
> > stuff.  For instance, qcow2 needs two children: the block driver
> > providing the delta bits (in qcow2 format), and the block driver
> > providing the base bits (whose configuration happens to be stored in the
> > delta bits).  
> 
> Backing files are different. When talking about opening images (which is
> what we do here) the main difference is that they can be opened only
> after the image itself has been opened. I don't think we should include
> them in this discussion.

Imho, being unable to override the qcow2 backing file from the command
line / monitor is very annoying, if you've moved files from another
machine or just renamed them for tidiness.  It's especially bad if the
supplied qcow2 file has an absolute path in it, quite bad if it has
subdirectories or ".." components, annoying if you've been given
several qcow2 files all of which have the name "backing-file" stored
in them which are different images because they were originally on
different machines, and awful if it has the name of a block device in it.

So, imho, for the discussion of command line / QMP options, there
should be reserved a place for giving the name of the backing file
through command line/monitor/QMP, along with the backing file's
formats/protocols/transports/options, and so on recursively in a tree
structure of arbitrary depth.

There is also the matter of qcow2 files encoding the path, but not
necessarily all the blockdev options that you might want to use to
access the backing file, such as cache=.

In QMP it's obviously quite simple to accept a full child blockdev
specification object as a qcow2-specific parameter, thus not needing
any further discussion in this thread.  It's less obvious how to do it
on the command line or human monitor.

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21  7:00   ` Markus Armbruster
@ 2010-06-22 16:46     ` Jamie Lokier
  0 siblings, 0 replies; 31+ messages in thread
From: Jamie Lokier @ 2010-06-22 16:46 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Avi Kivity

Markus Armbruster wrote:
> A possible reason why we currently expose format and protocol at the
> user interface is to avoid stacking there.

Pragmatic solution?: A few generic flags in each stacking module
("format/protocol/transport"), which govern which other modules are
allowed to stack on top or underneath.

For example, vvfat may provide a blockdev-like abstraction, along with
flags STACK_ABOVE_ONLY_RAW | STACK_BELOW_ONLY_DIRECTORY, which means
"raw" and "blkdebug" are allowed above (of course ;-) but other things
like the image formats shouldn't be.  And below, it can't stack on a
blockdev-like abstraction, but needs a directory and uses filesystem
operations on it - the thing that Plan9fs needs.

Btw, I think we expose "format" because "virtual disk image file
format" is a useful and meaningful concept to users.  When someone
needs to use a .VMDK file, they know it as a "VMDK format file", not
"I must use the VMDK protocol with this file".

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-22 16:40                 ` Jamie Lokier
@ 2010-06-22 16:56                   ` Daniel P. Berrange
  0 siblings, 0 replies; 31+ messages in thread
From: Daniel P. Berrange @ 2010-06-22 16:56 UTC (permalink / raw)
  To: Jamie Lokier
  Cc: Kevin Wolf, Christoph Hellwig, Markus Armbruster, qemu-devel,
	Luiz Capitulino, Avi Kivity, Gerd Hoffmann

On Tue, Jun 22, 2010 at 05:40:02PM +0100, Jamie Lokier wrote:
> Kevin Wolf wrote:
> > > The "protocol" parlance breaks down when we move away from the simple
> > > stuff.  For instance, qcow2 needs two children: the block driver
> > > providing the delta bits (in qcow2 format), and the block driver
> > > providing the base bits (whose configuration happens to be stored in the
> > > delta bits).  
> > 
> > Backing files are different. When talking about opening images (which is
> > what we do here) the main difference is that they can be opened only
> > after the image itself has been opened. I don't think we should include
> > them in this discussion.
> 
> Imho, being unable to override the qcow2 backing file from the command
> line / monitor is very annoying, if you've moved files from another
> machine or just renamed them for tidiness.  It's especially bad if the
> supplied qcow2 file has an absolute path in it, quite bad if it has
> subdirectories or ".." components, annoying if you've been given
> several qcow2 files all of which have the name "backing-file" stored
> in them which are different images because they were originally on
> different machines, and awful if it has the name of a block device in it.

FYI, in the scenario where you've moved backing files around, you can 
use qemu-img to update the location

  qemu-img rebase -u -b /path/to/newbackingfile.img demo.img

Regards,
Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
  2010-06-21 16:21                 ` Markus Armbruster
  2010-06-22  8:32                   ` Kevin Wolf
@ 2010-06-28 10:28                   ` Christoph Hellwig
  1 sibling, 0 replies; 31+ messages in thread
From: Christoph Hellwig @ 2010-06-28 10:28 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Kevin Wolf, Christoph Hellwig, qemu-devel, Luiz Capitulino,
	Gerd Hoffmann, Christoph Hellwig, Avi Kivity

On Mon, Jun 21, 2010 at 06:21:09PM +0200, Markus Armbruster wrote:
> You describe the special case where format and protocol make some sense:
> you have a block driver that can transport bits in arbitrary formats,
> and a block driver that interprets bits without caring for transport.
> 
> In the general case, we have things like vvfat that make people wonder
> whether it's a format or a protocol.  You can't stack it onto a
> transport, so it can't be a format!  You can't stack a format on it, so
> it can't be a protocol!

Instead of starting to get hung up on the protocol name let's go back to
the basic problem.  We have two types of Block drivers in qemu, which
are fundamentally different:

 - leaf drivers which use some sort of native I/O method and present
   an image.  The typical cases for this are file/host_device/nbd/http/
   ceph/sheepdog which just transport arbitrary content over some transport.
   Another category makes up the content of the image on the fly.  This
   is generally an extreme hack as it's very hard to keep any kind of
   coherency if the underlying content changes, but we've unfortunately
   enough done it anyway for vvfat.  I don't think I would accept any
   addition driver of this type.
 - non-leaf drivers which stack on top of another qemu block driver.

I think the difference is important enough for a user to care.  It's
basically two different questions for the users:

 - what image format do I want
 - and where do I store that image

Even vvfat kinda fits into that model.  The users wants to store the
image as a "life" view of a directory hierachy on the host.  Because
of the limitation of that model the choice of image format ontop of
that storage solution is limited to raw.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2010-06-28 10:28 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-18 12:59 [Qemu-devel] block: format vs. protocol, and how they stack Markus Armbruster
2010-06-20 10:51 ` [Qemu-devel] " Avi Kivity
2010-06-21  7:00   ` Markus Armbruster
2010-06-22 16:46     ` Jamie Lokier
2010-06-21  8:19   ` Kevin Wolf
2010-06-21 13:09     ` Anthony Liguori
2010-06-21 13:30       ` Kevin Wolf
2010-06-21 13:37         ` Anthony Liguori
2010-06-21 14:01           ` Kevin Wolf
2010-06-21 14:51             ` Anthony Liguori
2010-06-21 14:52               ` Anthony Liguori
2010-06-21 15:00               ` Christoph Hellwig
2010-06-21 15:22                 ` Paul Brook
2010-06-21 15:37                 ` Anthony Liguori
2010-06-21 16:01                   ` Christoph Hellwig
2010-06-21 16:09                     ` Anthony Liguori
2010-06-21 16:36                     ` Markus Armbruster
2010-06-21 16:21                 ` Markus Armbruster
2010-06-22  8:32                   ` Kevin Wolf
2010-06-22 14:24                     ` Markus Armbruster
2010-06-28 10:28                   ` Christoph Hellwig
2010-06-22 16:30                 ` Jamie Lokier
2010-06-21 15:34             ` Anthony Liguori
2010-06-22  8:10               ` Kevin Wolf
2010-06-22 12:39                 ` Anthony Liguori
2010-06-22 12:57                   ` Kevin Wolf
2010-06-22 13:07                     ` Anthony Liguori
2010-06-21 15:56             ` Markus Armbruster
2010-06-22  8:22               ` Kevin Wolf
2010-06-22 16:40                 ` Jamie Lokier
2010-06-22 16:56                   ` Daniel P. Berrange

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).