[libvirt] [PATCH 7/8] Asynchronous event for BlockPull completion
Daniel P. Berrange
berrange at redhat.com
Tue Jun 14 10:03:02 UTC 2011
On Thu, Jun 09, 2011 at 12:10:13PM -0500, Adam Litke wrote:
> When an operation started by virDomainBlockPullAll completes (either with
> success or with failure), raise an event to indicate the final status. This
> allows an API user to avoid polling on virDomainBlockPullInfo if they would
> prefer to use the event mechanism.
>
> * daemon/remote.c: Dispatch events to client
> * include/libvirt/libvirt.h.in: Define event ID and callback signature
> * src/conf/domain_event.c, src/conf/domain_event.h,
> src/libvirt_private.syms: Extend API to handle the new event
> * src/qemu/qemu_driver.c: Connect to the QEMU monitor event
> for block_stream completion and emit a libvirt block pull event
> * src/remote/remote_driver.c: Receive and dispatch events to application
> * src/remote/remote_protocol.x: Wire protocol definition for the event
> * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
> src/qemu/qemu_monitor_json.c: Watch for BLOCK_STREAM_COMPLETED event
> from QEMU monitor
>
> Signed-off-by: Adam Litke <agl at us.ibm.com>
> diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
> index fabc1a5..90c2b32 100644
> --- a/src/conf/domain_event.c
> +++ b/src/conf/domain_event.c
> @@ -84,6 +84,10 @@ struct _virDomainEvent {
> char *authScheme;
> virDomainEventGraphicsSubjectPtr subject;
> } graphics;
> + struct {
> + char *path;
> + int status;
> + } blockPull;
> } data;
> };
>
> @@ -500,6 +504,11 @@ void virDomainEventFree(virDomainEventPtr event)
> }
> VIR_FREE(event->data.graphics.subject);
> }
> + break;
> +
> + case VIR_DOMAIN_EVENT_ID_BLOCK_PULL:
> + VIR_FREE(event->data.blockPull.path);
> + break;
> }
>
> VIR_FREE(event->dom.name);
> @@ -875,6 +884,40 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
> return ev;
> }
>
> +static virDomainEventPtr
> +virDomainEventBlockPullNew(int id, const char *name, unsigned char *uuid,
> + const char *path, int status)
> +{
> + virDomainEventPtr ev =
> + virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_BLOCK_PULL,
> + id, name, uuid);
> +
> + if (ev) {
> + if (!(ev->data.blockPull.path = strdup(path))) {
> + virDomainEventFree(ev);
> + return NULL;
You want a virReportOOMError() call there.
> + }
> + ev->data.blockPull.status = status;
> + }
> +
> + return ev;
> +}
> +
> +virDomainEventPtr virDomainEventBlockPullNewFromObj(virDomainObjPtr obj,
> + const char *path,
> + int status)
> +{
> + return virDomainEventBlockPullNew(obj->def->id, obj->def->name,
> + obj->def->uuid, path, status);
> +}
> +
> +virDomainEventPtr virDomainEventBlockPullNewFromDom(virDomainPtr dom,
> + const char *path,
> + int status)
> +{
> + return virDomainEventBlockPullNew(dom->id, dom->name, dom->uuid,
> + path, status);
> +}
>
> virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom)
> {
> +static int
> +qemuProcessHandleBlockPull(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
> + virDomainObjPtr vm,
> + const char *diskAlias,
> + int status)
> +{
> + struct qemud_driver *driver = qemu_driver;
> + virDomainEventPtr blockPullEvent = NULL;
> + const char *path;
> + virDomainDiskDefPtr disk;
> +
> + virDomainObjLock(vm);
> + disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
> +
> + if (disk)
> + path = disk->src;
> + else
> + path = "";
If we can't find the disk associated with the alias, then
I think we should just discard the event rather than emitting
one with a zero-length path.
> + blockPullEvent = virDomainEventBlockPullNewFromObj(vm, path, status);
> +
> + virDomainObjUnlock(vm);
> + qemuDriverLock(driver);
> + qemuDomainEventQueue(driver, blockPullEvent);
> + qemuDriverUnlock(driver);
> +
> + return 0;
> +}
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list