On Fri, Jul 15, 2011 at 10:18:39AM -0500, Adam Litke wrote: > In light of discussion on V1 of this API, here is V2 of the next generation > BlockPull API. In this series we make the abort and info operations more > generic so that they may apply to future block jobs (such as compression, > live block copy, etc). We also add in a mechanism to set the maximum > bandwidth of an operation. > > Changes since V1: > - Make virDomainBlockPullAbort() and virDomainGetBlockPullInfo() into a > generic BlockJob interface. > - Added virDomainBlockJobSetSpeed() > - Rename VIR_DOMAIN_EVENT_ID_BLOCK_PULL event to fit into block job API > - Add bandwidth argument to virDomainBlockPull() > > Summary of changes since first generation patch series: > - Qemu dropped incremental streaming so remove libvirt incremental > BlockPull() API > - Rename virDomainBlockPullAll() to virDomainBlockPull() > - Changes required to qemu monitor handlers for changed command names > > -- > > To help speed the provisioning process for large domains, new QED disks are > created with backing to a template image. These disks are configured with > copy on read such that blocks that are read from the backing file are copied > to the new disk. This reduces I/O over a potentially costly path to the > backing image. > > In such a configuration, there is a desire to remove the dependency on the > backing image as the domain runs. To accomplish this, qemu will provide an > interface to perform sequential copy on read operations during normal VM > operation. Once all data has been copied, the disk image's link to the > backing file is removed. > > The virDomainBlockPull API family brings this functionality to libvirt. > > virDomainBlockPull() instructs the hypervisor to stream the entire device in > the background. Progress of this operation can be checked with the function > virDomainBlockJobInfo(). An ongoing stream can be cancelled with > virDomainBlockJobAbort(). virDomainBlockJobSetSpeed() allows you to limit the > bandwidth that the operation may consume. > > An event (VIR_DOMAIN_EVENT_ID_BLOCK_JOB) will be emitted when a disk has been > fully populated or if a BlockPull() operation was terminated due to an error. > This event is useful to avoid polling on virDomainBlockJobInfo() for > completion and could also be used by the security driver to revoke access to > the backing file when it is no longer needed. > > /* > * BlockJob API > */ > > /** > * virDomainBlockJobType: > * > * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull) > */ > typedef enum { > VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = -1, > VIR_DOMAIN_BLOCK_JOB_TYPE_PULL = 0, > } virDomainBlockJobType; > > /* An iterator for monitoring block job operations */ > typedef unsigned long long virDomainBlockJobCursor; > > typedef struct _virDomainBlockJobInfo virDomainBlockJobInfo; > struct _virDomainBlockJobInfo { > virDomainBlockJobType type; > /* > * The following fields provide an indication of block job progress. @cur > * indicates the current position and will be between 0 and @end. @end is > * the final cursor position for this operation and represents completion. > * To approximate progress, divide @cur by @end. > */ > virDomainBlockJobCursor cur; > virDomainBlockJobCursor end; > }; > typedef virDomainBlockJobInfo *virDomainBlockJobInfoPtr; > > /** > * virDomainBlockJobAbort: > * @dom: pointer to domain object > * @path: fully-qualified filename of disk > * @flags: currently unused, for future extension > * > * Cancel the active block job on the given disk. > * > * Returns -1 in case of failure, 0 when successful. > */ > int virDomainBlockJobAbort(virDomainPtr dom, > const char *path, > unsigned int flags); > > /** > * virDomainGetBlockJobInfo: > * @dom: pointer to domain object > * @path: fully-qualified filename of disk > * @info: pointer to a virDomainBlockJobInfo structure > * @flags: currently unused, for future extension > * > * Request block job information for the given disk. If an operation is > active > * @info will be updated with the current progress. > * > * Returns -1 in case of failure, 0 when successful. > */ > int virDomainGetBlockJobInfo(virDomainPtr dom, > const char *path, > virDomainBlockJobInfoPtr info, > unsigned int flags); > > /** > * virDomainBlockJobSetSpeed: > * @dom: pointer to domain object > * @path: fully-qualified filename of disk > * @bandwidth: specify bandwidth limit in Mbps > * @flags: currently unused, for future extension > * > * Set the maximimum allowable bandwidth that a block job may consume. If > * bandwidth is 0, the limit will revert to the hypervisor default. > * > * Returns -1 in case of failure, 0 when successful. > */ > int virDomainBlockJobSetSpeed(virDomainPtr dom, > const char *path, > unsigned long bandwidth, > unsigned int flags); > > /** > * virConnectDomainEventBlockJobStatus: > * > * The final status of a block job > */ > typedef enum { > VIR_DOMAIN_BLOCK_JOB_COMPLETED = 0, > VIR_DOMAIN_BLOCK_JOB_FAILED = 1, > } virConnectDomainEventBlockJobStatus; > > /** > * virConnectDomainEventBlockPullCallback: > * @conn: connection object > * @dom: domain on which the event occurred > * @path: fully-qualified filename of the affected disk > * @type: type of block job (virDomainBlockJobType) > * @status: final status of the operation > (virConnectDomainEventBlockPullStatus) > * @opaque: callback context > * > * The callback signature to use when registering for an event of type > * VIR_DOMAIN_EVENT_ID_BLOCK_PULL with virConnectDomainEventRegisterAny() > */ > typedef void (*virConnectDomainEventBlockPullCallback)(virConnectPtr conn, > virDomainPtr dom, > const char *path, > int type, > int status, > void *opaque); > > /** > * virDomainBlockPull: > * @dom: pointer to domain object > * @path: Fully-qualified filename of disk > * @bandwidth: (optional) specify copy bandwidth limit in Mbps > * @flags: currently unused, for future extension > * > * Populate a disk image with data from its backing image. Once all data from > * its backing image has been pulled, the disk no longer depends on a backing > * image. This function pulls data for the entire device in the background. > * Progress of the operation can be checked with virDomainGetBlockJobInfo() > and > * the operation can be aborted with virDomainBlockJobAbort(). When finished, > * an asynchronous event is raised to indicate the final status. > * > * The maximum bandwidth (in Mbps) that will be used to do the copy can be > * specified with the bandwidth parameter. If set to 0, libvirt will choose a > * suitable default. Some hypervisors do not support this feature and will > * return an error if bandwidth is not 0. > * > * Returns 0 if the operation has started, -1 on failure. > */ > int virDomainBlockPull(virDomainPtr dom, > const char *path, > unsigned long bandwidth, > unsigned int flags);
Looks fine to me, my only suggestion as said on IRC would be to start the VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN entry at 0, not -1 thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ dan...@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list