[libvirt] [RFC PATCH] qemu: new API for tracking arbitrary monitor events

Daniel P. Berrange berrange at redhat.com
Thu Dec 19 15:23:11 UTC 2013


On Thu, Dec 19, 2013 at 08:15:09AM -0700, Eric Blake wrote:
> diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c
> index db52c65..849932d 100644
> --- a/src/libvirt-qemu.c
> +++ b/src/libvirt-qemu.c
> @@ -237,3 +237,126 @@ error:
>      virDispatchError(conn);
>      return NULL;
>  }
> +
> +
> +/**
> + * virConnectDomainQemuMonitorEventRegister:
> + * @conn: pointer to the connection
> + * @dom: pointer to the domain, or NULL
> + * @event: name of the event, or NULL
> + * @cb: callback to the function handling monitor events
> + * @opaque: opaque data to pass on to the callback
> + * @freecb: optional function to deallocate opaque when not used anymore
> + * @flags: extra flags; not used yet, so callers should always pass 0
> + *
> + * This API is QEMU specific, so it will only work with hypervisor
> + * connections to the QEMU driver.
> + *
> + * Adds a callback to receive notifications of arbitrary qemu monitor events
> + * occurring on a domain.  Many qemu monitor events also result in a libvirt
> + * event which can be delivered via virConnectDomainEventRegisterAny(); this
> + * command is primarily for testing new qemu events that have not yet been
> + * given a libvirt counterpart event.
> + *
> + * If @dom is NULL, then events will be monitored for any domain. If @dom
> + * is non-NULL, then only the specific domain will be monitored.
> + *
> + * If @event is NULL, then all monitor events will be reported. If @event is
> + * non-NULL, then only the specific monitor event will be reported.  @flags
> + * is currently unused, but in the future may support a flag for passing
> + * @event as a glob instead of a literal name to match a category of events.
> + *
> + * The virDomainPtr object handle passed into the callback upon delivery
> + * of an event is only valid for the duration of execution of the callback.
> + * If the callback wishes to keep the domain object after the callback returns,
> + * it shall take a reference to it, by calling virDomainRef().
> + * The reference can be released once the object is no longer required
> + * by calling virDomainFree().
> + *
> + * The return value from this method is a positive integer identifier
> + * for the callback. To unregister a callback, this callback ID should
> + * be passed to the virConnectDomainQemuMonitorEventDeregister() method.
> + *
> + * Returns a callback identifier on success, -1 on failure
> + */
> +int
> +virConnectDomainQemuMonitorEventRegister(virConnectPtr conn,
> +                                         virDomainPtr dom,
> +                                         const char *event,
> +                                         virConnectDomainQemuMonitorEventCallback cb,
> +                                         void *opaque,
> +                                         virFreeCallback freecb,
> +                                         unsigned int flags)
> +{
> +    VIR_DOMAIN_DEBUG(dom,
> +                     "conn=%p, event=%s, cb=%p, opaque=%p, freecb=%p, flags=%x",
> +                     conn, NULLSTR(event), cb, opaque, freecb, flags);
> +
> +    virResetLastError();
> +
> +    if (!VIR_IS_CONNECT(conn)) {
> +        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
> +        virDispatchError(NULL);
> +        return -1;
> +    }
> +    if (dom &&
> +        !(VIR_IS_CONNECTED_DOMAIN(dom) && dom->conn == conn)) {
> +        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
> +        virDispatchError(conn);
> +        return -1;
> +    }
> +    virCheckNonNullArgGoto(cb, error)


I have a gut feeling that we should restrict use of this API to
authenticated users only. So add a check for a read-only connection
here


> +    if ((conn->driver) && (conn->driver->connectDomainQemuMonitorEventRegister)) {

This is excessively bracketed isn't it

> +        int ret;
> +        ret = conn->driver->connectDomainQemuMonitorEventRegister(conn, dom, event, cb, opaque, freecb, flags);
> +        if (ret < 0)
> +            goto error;
> +        return ret;
> +    }
> +
> +    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
> +error:
> +    virDispatchError(conn);
> +    return -1;
> +}
> +
> +/**
> + * virConnectDomainQemuMonitorEventDeregister:
> + * @conn: pointer to the connection
> + * @callbackID: the callback identifier
> + *
> + * Removes an event callback. The callbackID parameter should be the
> + * value obtained from a previous virConnectDomainQemuMonitorEventRegister()
> + * method.
> + *
> + * Returns 0 on success, -1 on failure
> + */
> +int
> +virConnectDomainQemuMonitorEventDeregister(virConnectPtr conn,
> +                                           int callbackID)
> +{
> +    VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
> +
> +    virResetLastError();
> +
> +    if (!VIR_IS_CONNECT(conn)) {
> +        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
> +        virDispatchError(NULL);
> +        return -1;
> +    }
> +    virCheckNonNegativeArgGoto(callbackID, error);

And add read-only check

> +
> +    if ((conn->driver) && (conn->driver->connectDomainQemuMonitorEventDeregister)) {

To many brackets again

> +        int ret;
> +        ret = conn->driver->connectDomainQemuMonitorEventDeregister(conn, callbackID);
> +        if (ret < 0)
> +            goto error;
> +        return ret;
> +    }
> +
> +    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
> +error:
> +    virDispatchError(conn);
> +    return -1;
> +}

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