
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 :|