[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