1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-30 18:50:18 +03:00

Introduce NIC_MAC_CHANGE event

The aim off this event is to notify management application that
guest changed MAC address on one of its vNICs so the app can
update its internal records, e.g. for finding match between
guest/host view of vNICs.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Michal Privoznik 2023-06-27 10:13:51 +02:00
parent ac95617d3d
commit 057872df2d
10 changed files with 258 additions and 1 deletions

View File

@ -1102,6 +1102,19 @@ myNetworkEventMetadataChangeCallback(virConnectPtr conn G_GNUC_UNUSED,
}
static int
myDomainEventNICMACChangeCallback(virConnectPtr conn G_GNUC_UNUSED,
virDomainPtr dom,
const char *alias,
const char *oldMAC,
const char *newMAC,
void *opaque G_GNUC_UNUSED)
{
printf("%s EVENT: Domain %s(%d) NIC MAC changed: alias: '%s' oldMAC: '%s' newMAC: '%s'\n",
__func__, virDomainGetName(dom), virDomainGetID(dom), alias, oldMAC, newMAC);
return 0;
}
static void
myFreeFunc(void *opaque)
@ -1160,6 +1173,7 @@ struct domainEventData domainEvents[] = {
DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, myDomainEventBlockThresholdCallback),
DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_MEMORY_FAILURE, myDomainEventMemoryFailureCallback),
DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_MEMORY_DEVICE_SIZE_CHANGE, myDomainEventMemoryDeviceSizeChangeCallback),
DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE, myDomainEventNICMACChangeCallback),
};
struct storagePoolEventData {

View File

@ -6993,6 +6993,33 @@ typedef void (*virConnectDomainEventMemoryDeviceSizeChangeCallback)(virConnectPt
void *opaque);
/**
* virConnectDomainEventNICMACChangeCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @alias: network interface device alias
* @oldMAC: the old value of network interface MAC address
* @newMAC: the new value of network interface MAC address
* @opaque: application specified data
*
* The callback occurs when the guest changes MAC address on one of
* its virtual network interfaces, for QEMU domains this is emitted
* only for vNICs of model virtio. The event is not emitted for
* other types (e.g. PCI device passthrough).
*
* The callback signature to use when registering for an event of
* type VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE with
* virConnectDomainEventRegisterAny().
*
* Since: 11.2.0
*/
typedef void (*virConnectDomainEventNICMACChangeCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *alias,
const char *oldMAC,
const char *newMAC,
void *opaque);
/**
* VIR_DOMAIN_EVENT_CALLBACK:
*
@ -7041,6 +7068,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD = 24, /* virConnectDomainEventBlockThresholdCallback (Since: 3.2.0) */
VIR_DOMAIN_EVENT_ID_MEMORY_FAILURE = 25, /* virConnectDomainEventMemoryFailureCallback (Since: 6.9.0) */
VIR_DOMAIN_EVENT_ID_MEMORY_DEVICE_SIZE_CHANGE = 26, /* virConnectDomainEventMemoryDeviceSizeChangeCallback (Since: 7.9.0) */
VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE = 27, /* virConnectDomainEventNICMACChangeCallback (Since: 11.2.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST

View File

@ -57,6 +57,7 @@ static virClass *virDomainEventMetadataChangeClass;
static virClass *virDomainEventBlockThresholdClass;
static virClass *virDomainEventMemoryFailureClass;
static virClass *virDomainEventMemoryDeviceSizeChangeClass;
static virClass *virDomainEventNICMACChangeClass;
static void virDomainEventDispose(void *obj);
static void virDomainEventLifecycleDispose(void *obj);
@ -81,6 +82,7 @@ static void virDomainEventMetadataChangeDispose(void *obj);
static void virDomainEventBlockThresholdDispose(void *obj);
static void virDomainEventMemoryFailureDispose(void *obj);
static void virDomainEventMemoryDeviceSizeChangeDispose(void *obj);
static void virDomainEventNICMACChangeDispose(void *obj);
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@ -285,6 +287,15 @@ struct _virDomainEventMemoryDeviceSizeChange {
};
typedef struct _virDomainEventMemoryDeviceSizeChange virDomainEventMemoryDeviceSizeChange;
struct _virDomainEventNICMACChange {
virDomainEvent parent;
char *alias;
char *oldMAC;
char *newMAC;
};
typedef struct _virDomainEventNICMACChange virDomainEventNICMACChange;
static int
virDomainEventsOnceInit(void)
{
@ -334,6 +345,8 @@ virDomainEventsOnceInit(void)
return -1;
if (!VIR_CLASS_NEW(virDomainEventMemoryDeviceSizeChange, virDomainEventClass))
return -1;
if (!VIR_CLASS_NEW(virDomainEventNICMACChange, virDomainEventClass))
return -1;
return 0;
}
@ -559,6 +572,16 @@ virDomainEventMemoryDeviceSizeChangeDispose(void *obj)
g_free(event->alias);
}
static void
virDomainEventNICMACChangeDispose(void *obj)
{
virDomainEventNICMACChange *event = obj;
g_free(event->alias);
g_free(event->oldMAC);
g_free(event->newMAC);
}
static void *
virDomainEventNew(virClass *klass,
int eventID,
@ -1733,6 +1756,62 @@ virDomainEventMemoryDeviceSizeChangeNewFromDom(virDomainPtr dom,
}
static virObjectEvent *
virDomainEventNICMACChangeNew(int id,
const char *name,
unsigned char *uuid,
const char *alias,
const char *oldMAC,
const char *newMAC)
{
virDomainEventNICMACChange *ev;
if (virDomainEventsInitialize() < 0)
return NULL;
if (!(ev = virDomainEventNew(virDomainEventNICMACChangeClass,
VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE,
id, name, uuid)))
return NULL;
ev->alias = g_strdup(alias);
ev->oldMAC = g_strdup(oldMAC);
ev->newMAC = g_strdup(newMAC);
return (virObjectEvent *)ev;
}
virObjectEvent *
virDomainEventNICMACChangeNewFromObj(virDomainObj *obj,
const char *alias,
const char *oldMAC,
const char *newMAC)
{
return virDomainEventNICMACChangeNew(obj->def->id,
obj->def->name,
obj->def->uuid,
alias,
oldMAC,
newMAC);
}
virObjectEvent *
virDomainEventNICMACChangeNewFromDom(virDomainPtr dom,
const char *alias,
const char *oldMAC,
const char *newMAC)
{
return virDomainEventNICMACChangeNew(dom->id,
dom->name,
dom->uuid,
alias,
oldMAC,
newMAC);
}
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
virObjectEvent *event,
@ -2041,6 +2120,20 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE:
{
virDomainEventNICMACChange *nicMacChangeEvent;
nicMacChangeEvent = (virDomainEventNICMACChange *)event;
((virConnectDomainEventNICMACChangeCallback)cb)(conn, dom,
nicMacChangeEvent->alias,
nicMacChangeEvent->oldMAC,
nicMacChangeEvent->newMAC,
cbopaque);
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}

View File

@ -277,6 +277,18 @@ virDomainEventMemoryDeviceSizeChangeNewFromDom(virDomainPtr dom,
const char *alias,
unsigned long long size);
virObjectEvent *
virDomainEventNICMACChangeNewFromObj(virDomainObj *obj,
const char *alias,
const char *oldMAC,
const char *newMAC);
virObjectEvent *
virDomainEventNICMACChangeNewFromDom(virDomainPtr dom,
const char *alias,
const char *oldMAC,
const char *newMAC);
int
virDomainEventStateRegister(virConnectPtr conn,
virObjectEventState *state,

View File

@ -779,6 +779,8 @@ virDomainEventMetadataChangeNewFromDom;
virDomainEventMetadataChangeNewFromObj;
virDomainEventMigrationIterationNewFromDom;
virDomainEventMigrationIterationNewFromObj;
virDomainEventNICMACChangeNewFromDom;
virDomainEventNICMACChangeNewFromObj;
virDomainEventPMSuspendDiskNewFromDom;
virDomainEventPMSuspendDiskNewFromObj;
virDomainEventPMSuspendNewFromDom;

View File

@ -1323,6 +1323,37 @@ remoteRelayDomainEventMemoryDeviceSizeChange(virConnectPtr conn,
}
static int
remoteRelayDomainEventNICMACChange(virConnectPtr conn,
virDomainPtr dom,
const char *alias,
const char *oldMAC,
const char *newMAC,
void *opaque)
{
daemonClientEventCallback *callback = opaque;
remote_domain_event_nic_mac_change_msg data;
if (callback->callbackID < 0 ||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
return -1;
/* build return data */
memset(&data, 0, sizeof(data));
data.callbackID = callback->callbackID;
data.alias = g_strdup(alias);
data.oldMAC = g_strdup(oldMAC);
data.newMAC = g_strdup(newMAC);
make_nonnull_domain(&data.dom, dom);
remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE,
(xdrproc_t)xdr_remote_domain_event_nic_mac_change_msg,
&data);
return 0;
}
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@ -1351,6 +1382,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockThreshold),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMemoryFailure),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMemoryDeviceSizeChange),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventNICMACChange),
};
G_STATIC_ASSERT(G_N_ELEMENTS(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);

View File

@ -432,6 +432,11 @@ remoteConnectNotifyEventConnectionClosed(virNetClientProgram *prog G_GNUC_UNUSED
virNetClient *client G_GNUC_UNUSED,
void *evdata, void *opaque);
static void
remoteDomainBuildEventNICMACChange(virNetClientProgram *prog,
virNetClient *client,
void *evdata, void *opaque);
static virNetClientProgramEvent remoteEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
remoteDomainBuildEventLifecycle,
@ -650,6 +655,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventMemoryDeviceSizeChange,
sizeof(remote_domain_event_memory_device_size_change_msg),
(xdrproc_t)xdr_remote_domain_event_memory_device_size_change_msg },
{ REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE,
remoteDomainBuildEventNICMACChange,
sizeof(remote_domain_event_nic_mac_change_msg),
(xdrproc_t)xdr_remote_domain_event_nic_mac_change_msg },
};
static void
@ -5068,6 +5077,31 @@ remoteDomainBuildEventMemoryDeviceSizeChange(virNetClientProgram *prog G_GNUC_UN
}
static void
remoteDomainBuildEventNICMACChange(virNetClientProgram *prog G_GNUC_UNUSED,
virNetClient *client G_GNUC_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
remote_domain_event_nic_mac_change_msg *msg = evdata;
struct private_data *priv = conn->privateData;
virDomainPtr dom;
virObjectEvent *event = NULL;
if (!(dom = get_nonnull_domain(conn, msg->dom)))
return;
event = virDomainEventNICMACChangeNewFromDom(dom,
msg->alias,
msg->oldMAC,
msg->newMAC);
virObjectUnref(dom);
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
}
static int
remoteStreamSend(virStreamPtr st,
const char *data,

View File

@ -4000,6 +4000,14 @@ struct remote_domain_set_autostart_once_args {
int autostart;
};
struct remote_domain_event_nic_mac_change_msg {
int callbackID;
remote_nonnull_domain dom;
remote_nonnull_string alias;
remote_nonnull_string oldMAC;
remote_nonnull_string newMAC;
};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@ -7105,5 +7113,11 @@ enum remote_procedure {
* @acl: domain:save:!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE
* @acl: domain:save:VIR_DOMAIN_AFFECT_CONFIG
*/
REMOTE_PROC_DOMAIN_DEL_THROTTLE_GROUP = 452
REMOTE_PROC_DOMAIN_DEL_THROTTLE_GROUP = 452,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453
};

View File

@ -3330,6 +3330,13 @@ struct remote_domain_set_autostart_once_args {
remote_nonnull_domain dom;
int autostart;
};
struct remote_domain_event_nic_mac_change_msg {
int callbackID;
remote_nonnull_domain dom;
remote_nonnull_string alias;
remote_nonnull_string oldMAC;
remote_nonnull_string newMAC;
};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@ -3783,4 +3790,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_AUTOSTART_ONCE = 450,
REMOTE_PROC_DOMAIN_SET_THROTTLE_GROUP = 451,
REMOTE_PROC_DOMAIN_DEL_THROTTLE_GROUP = 452,
REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453,
};

View File

@ -783,6 +783,24 @@ virshEventMemoryDeviceSizeChangePrint(virConnectPtr conn G_GNUC_UNUSED,
}
static void
virshEventNICMACChangePrint(virConnectPtr conn G_GNUC_UNUSED,
virDomainPtr dom,
const char *alias,
const char *oldMAC,
const char *newMAC,
void *opaque)
{
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
virBufferAsprintf(&buf,
_("event 'nic-mac-change' for domain '%1$s':\nalias: %2$s\noldMAC: %3$s\nnewMAC: %4$s\n"),
virDomainGetName(dom), alias, oldMAC, newMAC);
virshEventPrint(opaque, &buf);
}
virshDomainEventCallback virshDomainEventCallbacks[] = {
{ "lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(virshEventLifecyclePrint), },
@ -836,6 +854,8 @@ virshDomainEventCallback virshDomainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(virshEventMemoryFailurePrint), },
{ "memory-device-size-change",
VIR_DOMAIN_EVENT_CALLBACK(virshEventMemoryDeviceSizeChangePrint), },
{ "nic-mac-change",
VIR_DOMAIN_EVENT_CALLBACK(virshEventNICMACChangePrint), },
};
G_STATIC_ASSERT(VIR_DOMAIN_EVENT_ID_LAST == G_N_ELEMENTS(virshDomainEventCallbacks));