]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Define Network Metadata change event
authorK Shiva Kiran <shiva_kr@riseup.net>
Sun, 3 Sep 2023 14:58:33 +0000 (20:28 +0530)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 18 Sep 2023 09:24:47 +0000 (11:24 +0200)
When changing the metadata via virNetworkSetMetadata(), we can
now emit an event to notify the app of changes. This is useful
when co-ordinating different applications read/write of custom
metadata.

Signed-off-by: K Shiva Kiran <shiva_kr@riseup.net>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
include/libvirt/libvirt-network.h
src/conf/network_event.c
src/remote/remote_daemon_dispatch.c
src/remote/remote_protocol.x
src/remote_protocol-structs
tools/virsh-network.c

index 0f7ad8300fd5880d3087fc6c504b07e56682311c..58591be7ac995b7e1cb865d8e77e749d392282ef 100644 (file)
@@ -330,6 +330,7 @@ typedef void (*virConnectNetworkEventLifecycleCallback)(virConnectPtr conn,
  */
 typedef enum {
     VIR_NETWORK_EVENT_ID_LIFECYCLE = 0,       /* virConnectNetworkEventLifecycleCallback (Since: 1.2.1) */
+    VIR_NETWORK_EVENT_ID_METADATA_CHANGE = 1,   /* virConnectNetworkEventMetadataChangeCallback (Since: 9.8.0) */
 
 # ifdef VIR_ENUM_SENTINELS
     VIR_NETWORK_EVENT_ID_LAST
@@ -576,4 +577,25 @@ virNetworkGetMetadata(virNetworkPtr network,
                       const char *uri,
                       unsigned int flags);
 
+/**
+ * virConnectNetworkEventMetadataChangeCallback:
+ * @conn: connection object
+ * @net: network on which the event occurred
+ * @type: a value from virNetworkMetadataType
+ * @nsuri: XML namespace URI
+ * @opaque: application specified data
+ *
+ * This callback is triggered when the Network XML metadata changes
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_NETWORK_EVENT_ID_METADATA_CHANGE with virConnectNetworkEventRegisterAny().
+ *
+ * Since: 9.8.0
+ */
+typedef void (*virConnectNetworkEventMetadataChangeCallback)(virConnectPtr conn,
+                                                             virNetworkPtr net,
+                                                             int type,
+                                                             const char *nsuri,
+                                                             void *opaque);
+
 #endif /* LIBVIRT_NETWORK_H */
index 6f25e43711c6cf58b7d76352c64b7d5e2e768467..d1b3aa5721249ec61cd321182ab34927825c7e3f 100644 (file)
@@ -45,10 +45,21 @@ struct _virNetworkEventLifecycle {
 };
 typedef struct _virNetworkEventLifecycle virNetworkEventLifecycle;
 
+struct _virNetworkEventMetadataChange {
+    virNetworkEvent parent;
+
+    int type;
+    char *nsuri;
+};
+typedef struct _virNetworkEventMetadataChange virNetworkEventMetadataChange;
+
 static virClass *virNetworkEventClass;
 static virClass *virNetworkEventLifecycleClass;
+static virClass *virNetworkEventMetadataChangeClass;
+
 static void virNetworkEventDispose(void *obj);
 static void virNetworkEventLifecycleDispose(void *obj);
+static void virNetworkEventMetadataChangeDispose(void *obj);
 
 static int
 virNetworkEventsOnceInit(void)
@@ -59,6 +70,9 @@ virNetworkEventsOnceInit(void)
     if (!VIR_CLASS_NEW(virNetworkEventLifecycle, virNetworkEventClass))
         return -1;
 
+    if (!VIR_CLASS_NEW(virNetworkEventMetadataChange, virNetworkEventClass))
+        return -1;
+
     return 0;
 }
 
@@ -104,6 +118,18 @@ virNetworkEventDispatchDefaultFunc(virConnectPtr conn,
             return;
         }
 
+    case VIR_NETWORK_EVENT_ID_METADATA_CHANGE:
+        {
+            virNetworkEventMetadataChange *metadataChangeEvent;
+
+            metadataChangeEvent = (virNetworkEventMetadataChange *)event;
+            ((virConnectNetworkEventMetadataChangeCallback)cb)(conn, net,
+                                                               metadataChangeEvent->type,
+                                                               metadataChangeEvent->nsuri,
+                                                               cbopaque);
+            return;
+        }
+
     case VIR_NETWORK_EVENT_ID_LAST:
         break;
     }
@@ -231,3 +257,13 @@ virNetworkEventLifecycleNew(const char *name,
 
     return (virObjectEvent *)event;
 }
+
+
+static void
+virNetworkEventMetadataChangeDispose(void *obj)
+{
+    virNetworkEventMetadataChange *event = obj;
+    VIR_DEBUG("obj=%p", event);
+
+    g_free(event->nsuri);
+}
index 2bb9e306a47be50cf88c54d0996acf42cf884aa3..7daf503b517af5961a01789a6105d41ca5ed90e3 100644 (file)
@@ -1385,8 +1385,46 @@ remoteRelayNetworkEventLifecycle(virConnectPtr conn,
     return 0;
 }
 
+static int
+remoteRelayNetworkEventMetadataChange(virConnectPtr conn,
+                                      virNetworkPtr net,
+                                      int type,
+                                      const char *nsuri,
+                                      void *opaque)
+{
+    daemonClientEventCallback *callback = opaque;
+    remote_network_event_callback_metadata_change_msg data;
+
+    if (callback->callbackID < 0 ||
+        !remoteRelayNetworkEventCheckACL(callback->client, conn, net))
+        return -1;
+
+    VIR_DEBUG("Relaying network metadata change %s %d %s, callback %d",
+              net->name, type, NULLSTR(nsuri), callback->callbackID);
+
+    /* build return data */
+    memset(&data, 0, sizeof(data));
+
+    data.type = type;
+    if (nsuri) {
+        data.nsuri = g_new0(remote_nonnull_string, 1);
+        *(data.nsuri) = g_strdup(nsuri);
+    }
+
+    make_nonnull_network(&data.net, net);
+    data.callbackID = callback->callbackID;
+
+    remoteDispatchObjectEventSend(callback->client, callback->program,
+                                  REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE,
+                                  (xdrproc_t)xdr_remote_network_event_callback_metadata_change_msg,
+                                  &data);
+    return 0;
+}
+
+
 static virConnectNetworkEventGenericCallback networkEventCallbacks[] = {
     VIR_NETWORK_EVENT_CALLBACK(remoteRelayNetworkEventLifecycle),
+    VIR_NETWORK_EVENT_CALLBACK(remoteRelayNetworkEventMetadataChange),
 };
 
 G_STATIC_ASSERT(G_N_ELEMENTS(networkEventCallbacks) == VIR_NETWORK_EVENT_ID_LAST);
index 7ff059e3930402c41e4c1d9aa1b52a25599e3656..e295b0acc3591b994c8d303d043e2969214aa9c9 100644 (file)
@@ -3323,6 +3323,13 @@ struct remote_network_event_lifecycle_msg {
     int detail;
 };
 
+struct remote_network_event_callback_metadata_change_msg {
+    int callbackID;
+    remote_nonnull_network net;
+    int type;
+    remote_string nsuri;
+};
+
 struct remote_network_set_metadata_args {
     remote_nonnull_network network;
     int type;
@@ -7008,5 +7015,11 @@ enum remote_procedure {
      * @generate: both
      * @acl: network:read
      */
-    REMOTE_PROC_NETWORK_GET_METADATA = 445
+    REMOTE_PROC_NETWORK_GET_METADATA = 445,
+
+    /**
+     * @generate: both
+     * @acl: none
+     */
+    REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446
 };
index c07e0af1e6afc4b5afc568eaf0b1beea434d37c9..924ca418254edd2b2ed03aa50b74671c28d91392 100644 (file)
@@ -2687,6 +2687,12 @@ struct remote_network_event_lifecycle_msg {
         int                        event;
         int                        detail;
 };
+struct remote_network_event_callback_metadata_change_msg {
+        int                        callbackID;
+        remote_nonnull_network     net;
+        int                        type;
+        remote_string              nsuri;
+};
 struct remote_network_set_metadata_args {
         remote_nonnull_network     network;
         int                        type;
@@ -3736,4 +3742,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443,
         REMOTE_PROC_NETWORK_SET_METADATA = 444,
         REMOTE_PROC_NETWORK_GET_METADATA = 445,
+        REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446,
 };
index f6d2db54bab42647a0c6641fab355258dc9062ed..998e7e15e32f6b992a863c2fa78b7e1b0c4ff3a1 100644 (file)
@@ -1581,7 +1581,8 @@ typedef struct virshNetEventData virshNetEventData;
 VIR_ENUM_DECL(virshNetworkEventId);
 VIR_ENUM_IMPL(virshNetworkEventId,
               VIR_NETWORK_EVENT_ID_LAST,
-              "lifecycle");
+              "lifecycle",
+              "metadata-change");
 
 static void
 vshEventLifecyclePrint(virConnectPtr conn G_GNUC_UNUSED,
@@ -1614,9 +1615,52 @@ vshEventLifecyclePrint(virConnectPtr conn G_GNUC_UNUSED,
         vshEventDone(data->ctl);
 }
 
+VIR_ENUM_DECL(virshNetworkEventMetadataChangeType);
+VIR_ENUM_IMPL(virshNetworkEventMetadataChangeType,
+              VIR_NETWORK_METADATA_LAST,
+              N_("description"),
+              N_("title"),
+              N_("element"));
+
+#define UNKNOWNSTR(str) (str ? str : N_("unsupported value"))
+
+static void
+vshEventMetadataChangePrint(virConnectPtr conn G_GNUC_UNUSED,
+                            virNetworkPtr net,
+                            int type,
+                            const char *nsuri,
+                            void *opaque)
+{
+    virshNetEventData *data = opaque;
+
+    if (!data->loop && data->count)
+        return;
+
+    if (data->timestamp) {
+        char timestamp[VIR_TIME_STRING_BUFLEN];
+
+        if (virTimeStringNowRaw(timestamp) < 0)
+            timestamp[0] = '\0';
+
+        vshPrint(data->ctl, _("%1$s: event 'metadata-change' for network %2$s: type %3$s, uri %4$s\n"),
+                 timestamp, virNetworkGetName(net),
+                 UNKNOWNSTR(virshNetworkEventMetadataChangeTypeTypeToString(type)), NULLSTR(nsuri));
+    } else {
+        vshPrint(data->ctl, _("event 'metadata-change' for network %1$s: type %2$s, uri %3$s\n"),
+                 virNetworkGetName(net),
+                 UNKNOWNSTR(virshNetworkEventMetadataChangeTypeTypeToString(type)), NULLSTR(nsuri));
+    }
+
+    data->count++;
+    if (!data->loop)
+        vshEventDone(data->ctl);
+}
+
 virshNetworkEventCallback virshNetworkEventCallbacks[] = {
     { "lifecycle",
       VIR_NETWORK_EVENT_CALLBACK(vshEventLifecyclePrint), },
+    { "metadata-change",
+      VIR_NETWORK_EVENT_CALLBACK(vshEventMetadataChangePrint), },
 };
 G_STATIC_ASSERT(VIR_NETWORK_EVENT_ID_LAST == G_N_ELEMENTS(virshNetworkEventCallbacks));