From: K Shiva Kiran Date: Sun, 3 Sep 2023 14:58:33 +0000 (+0530) Subject: Define Network Metadata change event X-Git-Tag: v9.8.0-rc1~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95ee416a755c613870d48341e6baaac6ef574b81;p=thirdparty%2Flibvirt.git Define Network Metadata change event 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 Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h index 0f7ad8300f..58591be7ac 100644 --- a/include/libvirt/libvirt-network.h +++ b/include/libvirt/libvirt-network.h @@ -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 */ diff --git a/src/conf/network_event.c b/src/conf/network_event.c index 6f25e43711..d1b3aa5721 100644 --- a/src/conf/network_event.c +++ b/src/conf/network_event.c @@ -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); +} diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 2bb9e306a4..7daf503b51 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -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); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 7ff059e393..e295b0acc3 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -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 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index c07e0af1e6..924ca41825 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -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, }; diff --git a/tools/virsh-network.c b/tools/virsh-network.c index f6d2db54ba..998e7e15e3 100644 --- a/tools/virsh-network.c +++ b/tools/virsh-network.c @@ -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));