On 09/26/2017 12:59 PM, Kevin Wolf wrote: > Hi, > > as the next step after my commit block job fixes, I'm trying to > implement a new, clean version of the QMP command, which I'm calling > blockdev-commit for consistency with all the other "modern" QMP > commands. > > I'll start with the schema that I have so far: > > { 'command': 'blockdev-commit', > 'data': { 'job-id': 'str', 'top': 'str', '*base': 'str' > '*backing-file': 'str', '*speed': 'int', > '*filter-node-name': 'str' } }
Seems okay at first glance, modulo your discussion below on active vs. passive. > > In comparison with the old command, the important changes are: > > * top/base are node names instead of file names. I can agree to that. Do we still allow device names to resolve into the top-most node attached to the device? That matters for 'top', but not for 'base'. > > * You don't need to specify the active layer any more (not the least > because there could very well be more than one of them), but top > becomes mandatory instead. Libvirt should be fine with that. > > * top/base don't accept device (BlockBackend) names, so for > consistency with other block jobs, job-id becomes mandatory. > > Possible alternative: Accept device names and make them the default > for job-id. This is more consistent with existing blockdev-* > commands, but I consider BlockBackend names deprecated, so I prefer > not adding them here. Oh, you're answering my question above. I'm okay if job-id is mandatory, even if we allow the shortcut of a device name for 'top' mapping to its attached active node. > > * filer-node-name is kept optional for now. Should we make it > mandatory, too? > > This was the easy part. Then I started looking at the code and found a > few a bit more interesting questions: > > * The old block-commit command decides between an "actual" commit job > and the mirror-based active commit based on whether top is the > active layer. And libvirt HAS to know whether it is requesting an active vs. intermediate commit job up front, because the two code paths have different expected signals for handling job completion (it is only active commit that reaches a ready point between phases, requiring further QMP commands to end the job). > > We don't get an option for the active layer any more now, so this > isn't how things can work for blockdev-commit. We could probably > check whether top has a BlockBackend parent, but that's not really > what we're interested in anyway. Maybe the best we could do to > decide this automatically is to check whether there is any parent of > top that requires write permissions. If there is, we need active > commit, otherwise the "normal" one is good enough. > > However, who says that the intentions of the user stay as we deduce > them at the start of the block job? Who says that the user doesn't > want to add a writable disk as a user of the node while the block > job is running? > > The optimal solution to this would be that the commit filter node > responds to permission requests and switches between active and > "normal" commit mode. I'm not sure how hard this would be to > implement. > > As long as we don't have the automatic switch, do we have to allow > the user to specify explicitly which mode they want instead of > automatically choosing one? When committing one read-only image into another, you don't need the active mode. On the other hand, committing a writeable image generally means you don't want to lose any data, even as further writes happen while the job is ongoing. Does a "normal" mode commit make sense on a writeable image (perhaps as a point-in-time operation: all data that was present when the job started gets written, but if we do a NEW write, we make sure to FIRST commit the old data into the backing file then do the write into the active layer, and mark that cluster as no longer needing commit), differently from an "active" mode commit (a write to the active layer dirties the cluster, and we make as many passes as necessary, possibly writing some clusters to the backing file multiple times, so that the backing file contains the contents at the point the job ends rather than starts). With our existing active commit code, is there a way to do an intermediate style commit instead of an active commit (by passing the node name instead of the device name, even though it resolves to the same 'top' node)? Maybe an optional boolean is worth having, where we default to active if 'top' is writable and 'normal' otherwise; but can set the boolean to force 'normal' even on a writable, and where setting the boolean on something that is not writable is either a no-op or an error? > > * The 'backing-file' option (which specifies the new backing file > string for parents after the commit job completes) is currently not > allowed if top is the active layer. If we allow graph changes, this > doesn't seem to make sense to me because even if top doesn't have a > parent node when the job starts, it could have one when it's > completed. Based on your recent patch series, I think we're still murky on exactly what graph changes the op-blockers are going to prevent. But allowing 'backing-file' even when 'top' starts life as the active layer makes sense, as we may create a snapshot or some other operation that changes 'top' into something that is no longer active, without invalidating the fact that we are doing a commit job (but there's also the tricky issue of whether libvirt should expect only one event with no followup command to end the job, or two events marking the two phases where a followup is necessary). > > Any opinions on this, especially the active/normal commit thing? > > Kevin > -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature