[libvirt] [PATCH 11/2] event: don't turn offline domain into global event

Eric Blake eblake at redhat.com
Sat Jan 4 14:00:35 UTC 2014


If a user registers for a domain event filtered to a particular
domain, but the persistent domain is offline at the time, then
the code silently failed to set up the filter.  As a result,
the event fires for all domains, rather than being filtered.
Network events were immune, since they always passed an id
0 argument.

The key to this patch is realizing that
virObjectEventDispatchMatchCallback() only cared about uuid;
so refusing to create a meta for a negative id is pointless,
and in fact, malloc'ing meta at all was overkill; instead,
just directly store a uuid and a flag of whether to filter.

* src/conf/object_event_private.h (_virObjectEventCallback):
Replace meta with uuid and flag.
(virObjectEventCallbackListAddID): Update signature.
* src/conf/object_event.h (virObjectEventStateRegisterID):
Likewise.
* src/conf/object_event.c (virObjectEventCallbackListAddID): Drop
arguments that don't affect filtering.
(virObjectEventCallbackListRemoveID)
(virObjectEventDispatchMatchCallback)
(virObjectEventStateRegisterID): Update clients.
* src/conf/domain_event.c (virDomainEventCallbackListAdd)
(virDomainEventStateRegisterID): Likewise.
* src/conf/network_event.c (virNetworkEventStateRegisterID):
Likewise.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/conf/domain_event.c  | 16 +++++-----------
 src/conf/network_event.c | 13 +++----------
 src/conf/object_event.c  | 48 +++++++++++++++++-------------------------------
 src/conf/object_event.h  |  2 --
 4 files changed, 25 insertions(+), 54 deletions(-)

diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 4f8ede5..35212ef 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -1284,7 +1284,7 @@ virDomainEventStateRegister(virConnectPtr conn,
     if (virDomainEventsInitialize() < 0)
         return -1;

-    return virObjectEventStateRegisterID(conn, state, NULL, NULL, 0,
+    return virObjectEventStateRegisterID(conn, state, NULL,
                                          virDomainEventClass,
                                          VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                          VIR_OBJECT_EVENT_CALLBACK(callback),
@@ -1322,16 +1322,10 @@ virDomainEventStateRegisterID(virConnectPtr conn,
     if (virDomainEventsInitialize() < 0)
         return -1;

-    if (dom)
-        return virObjectEventStateRegisterID(conn, state, dom->uuid, dom->name,
-                                             dom->id, virDomainEventClass, eventID,
-                                             VIR_OBJECT_EVENT_CALLBACK(cb),
-                                             opaque, freecb, callbackID);
-     else
-        return virObjectEventStateRegisterID(conn, state, NULL, NULL, 0,
-                                             virDomainEventClass, eventID,
-                                             VIR_OBJECT_EVENT_CALLBACK(cb),
-                                             opaque, freecb, callbackID);
+    return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
+                                         virDomainEventClass, eventID,
+                                         VIR_OBJECT_EVENT_CALLBACK(cb),
+                                         opaque, freecb, callbackID);
 }


diff --git a/src/conf/network_event.c b/src/conf/network_event.c
index a192ffe..38c74d1 100644
--- a/src/conf/network_event.c
+++ b/src/conf/network_event.c
@@ -151,16 +151,9 @@ virNetworkEventStateRegisterID(virConnectPtr conn,
     if (virNetworkEventsInitialize() < 0)
         return -1;

-    if (net)
-        return virObjectEventStateRegisterID(conn, state,
-                                             net->uuid, net->name, 0,
-                                             virNetworkEventClass, eventID,
-                                             cb, opaque, freecb, callbackID);
-    else
-        return virObjectEventStateRegisterID(conn, state,
-                                             NULL, NULL, 0,
-                                             virNetworkEventClass, eventID,
-                                             cb, opaque, freecb, callbackID);
+    return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
+                                         virNetworkEventClass, eventID,
+                                         cb, opaque, freecb, callbackID);
 }


diff --git a/src/conf/object_event.c b/src/conf/object_event.c
index 87e10e0..320a422 100644
--- a/src/conf/object_event.c
+++ b/src/conf/object_event.c
@@ -66,7 +66,8 @@ struct _virObjectEventCallback {
     virClassPtr klass;
     int eventID;
     virConnectPtr conn;
-    virObjectMetaPtr meta;
+    bool uuid_filter;
+    unsigned char uuid[VIR_UUID_BUFLEN];
     virConnectObjectEventGenericCallback cb;
     void *opaque;
     virFreeCallback freecb;
@@ -201,9 +202,6 @@ virObjectEventCallbackListRemoveID(virConnectPtr conn,
             if (cb->freecb)
                 (*cb->freecb)(cb->opaque);
             virObjectUnref(cb->conn);
-            if (cb->meta)
-                VIR_FREE(cb->meta->name);
-            VIR_FREE(cb->meta);
             VIR_FREE(cb);
             VIR_DELETE_ELEMENT(cbList->callbacks, i, cbList->count);

@@ -309,9 +307,9 @@ virObjectEventCallbackLookup(virConnectPtr conn,
             cb->eventID == eventID &&
             cb->conn == conn &&
             cb->legacy == legacy &&
-            ((uuid && cb->meta &&
-              memcmp(cb->meta->uuid, uuid, VIR_UUID_BUFLEN) == 0) ||
-             (!uuid && !cb->meta))) {
+            ((uuid && cb->uuid_filter &&
+              memcmp(cb->uuid, uuid, VIR_UUID_BUFLEN) == 0) ||
+             (!uuid && !cb->uuid_filter))) {
             ret = cb->callbackID;
             break;
         }
@@ -325,8 +323,6 @@ virObjectEventCallbackLookup(virConnectPtr conn,
  * @conn: pointer to the connection
  * @cbList: the list
  * @uuid: the uuid of the object to filter on
- * @name: the name of the object to filter on
- * @id: the ID of the object to filter on
  * @klass: the base event class
  * @eventID: the event ID
  * @callback: the callback to add
@@ -340,8 +336,6 @@ static int
 virObjectEventCallbackListAddID(virConnectPtr conn,
                                 virObjectEventCallbackListPtr cbList,
                                 unsigned char uuid[VIR_UUID_BUFLEN],
-                                const char *name,
-                                int id,
                                 virClassPtr klass,
                                 int eventID,
                                 virConnectObjectEventGenericCallback callback,
@@ -352,10 +346,9 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
     virObjectEventCallbackPtr event;
     int ret = -1;

-    VIR_DEBUG("conn=%p cblist=%p uuid=%p name=%s id=%d "
+    VIR_DEBUG("conn=%p cblist=%p uuid=%p "
               "klass=%p eventID=%d callback=%p opaque=%p",
-              conn, cbList, uuid, name, id, klass, eventID,
-              callback, opaque);
+              conn, cbList, uuid, klass, eventID, callback, opaque);

     /* Check incoming */
     if (!cbList) {
@@ -381,13 +374,12 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
     event->opaque = opaque;
     event->freecb = freecb;

-    if (name && uuid && id > 0) {
-        if (VIR_ALLOC(event->meta) < 0)
-            goto cleanup;
-        if (VIR_STRDUP(event->meta->name, name) < 0)
-            goto cleanup;
-        memcpy(event->meta->uuid, uuid, VIR_UUID_BUFLEN);
-        event->meta->id = id;
+    /* Only need 'uuid' for matching; 'id' can change as domain
+     * switches between running and shutoff, and 'name' can change in
+     * Xen migration.  */
+    if (uuid) {
+        event->uuid_filter = true;
+        memcpy(event->uuid, uuid, VIR_UUID_BUFLEN);
     }

     if (callbackID)
@@ -401,12 +393,8 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
     ret = virObjectEventCallbackListCount(conn, cbList, klass, eventID);

 cleanup:
-    if (event) {
+    if (event)
         virObjectUnref(event->conn);
-        if (event->meta)
-            VIR_FREE(event->meta->name);
-        VIR_FREE(event->meta);
-    }
     VIR_FREE(event);
     return ret;
 }
@@ -669,14 +657,14 @@ virObjectEventDispatchMatchCallback(virObjectEventPtr event,
     if (cb->eventID != event->eventID)
         return false;

-    if (cb->meta) {
+    if (cb->uuid_filter) {
         /* Deliberately ignoring 'id' for matching, since that
          * will cause problems when a domain switches between
          * running & shutoff states & ignoring 'name' since
          * Xen sometimes renames guests during migration, thus
          * leaving 'uuid' as the only truly reliable ID we can use. */

-        return memcmp(event->meta.uuid, cb->meta->uuid, VIR_UUID_BUFLEN) == 0;
+        return memcmp(event->meta.uuid, cb->uuid, VIR_UUID_BUFLEN) == 0;
     }
     return true;
 }
@@ -807,8 +795,6 @@ int
 virObjectEventStateRegisterID(virConnectPtr conn,
                               virObjectEventStatePtr state,
                               unsigned char *uuid,
-                              const char *name,
-                              int id,
                               virClassPtr klass,
                               int eventID,
                               virConnectObjectEventGenericCallback cb,
@@ -832,7 +818,7 @@ virObjectEventStateRegisterID(virConnectPtr conn,
     }

     ret = virObjectEventCallbackListAddID(conn, state->callbacks,
-                                          uuid, name, id, klass, eventID,
+                                          uuid, klass, eventID,
                                           cb, opaque, freecb,
                                           callbackID);

diff --git a/src/conf/object_event.h b/src/conf/object_event.h
index fa1281c..e44d4f2 100644
--- a/src/conf/object_event.h
+++ b/src/conf/object_event.h
@@ -71,8 +71,6 @@ int
 virObjectEventStateRegisterID(virConnectPtr conn,
                               virObjectEventStatePtr state,
                               unsigned char *uuid,
-                              const char *name,
-                              int id,
                               virClassPtr klass,
                               int eventID,
                               virConnectObjectEventGenericCallback cb,
-- 
1.8.4.2




More information about the libvir-list mailing list