Add a new domain event for completed vCPU removal.
Wire the event through the internal event framework and extend the
remote protocol so remote clients can receive it. Update virsh and
the event-test example accordingly.
The event is not emitted anywhere yet.
Signed-off-by: Akash Kulhalli <akash.kulhalli@oracle.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
return 0;
}
+static int
+myDomainEventVcpuRemovedCallback(virConnectPtr conn G_GNUC_UNUSED,
+ virDomainPtr dom,
+ unsigned int vcpuid,
+ void *opaque G_GNUC_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) vcpu removed: %u\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), vcpuid);
+ return 0;
+}
+
static const char *
metadataTypeToStr(int status)
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),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_VCPU_REMOVED, myDomainEventVcpuRemovedCallback),
};
struct storagePoolEventData {
const char *devAlias,
void *opaque);
+/**
+ * virConnectDomainEventVcpuRemovedCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @vcpuid: libvirt XML vCPU id
+ * @opaque: application specified data
+ *
+ * This callback occurs when a vCPU is removed from the domain.
+ *
+ * The @vcpuid value matches the ``<vcpu id='...'>`` value from the domain XML.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_DOMAIN_EVENT_ID_VCPU_REMOVED with virConnectDomainEventRegisterAny().
+ *
+ * Since: 12.4.0
+ */
+typedef void (*virConnectDomainEventVcpuRemovedCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ unsigned int vcpuid,
+ void *opaque);
+
/**
* virConnectDomainEventMetadataChangeCallback:
* @conn: connection object
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) */
+ VIR_DOMAIN_EVENT_ID_VCPU_REMOVED = 28, /* virConnectDomainEventVcpuRemovedCallback (Since: 12.4.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST
static virClass *virDomainEventMigrationIterationClass;
static virClass *virDomainEventJobCompletedClass;
static virClass *virDomainEventDeviceRemovalFailedClass;
+static virClass *virDomainEventVcpuRemovedClass;
static virClass *virDomainEventMetadataChangeClass;
static virClass *virDomainEventBlockThresholdClass;
static virClass *virDomainEventMemoryFailureClass;
static void virDomainEventMigrationIterationDispose(void *obj);
static void virDomainEventJobCompletedDispose(void *obj);
static void virDomainEventDeviceRemovalFailedDispose(void *obj);
+static void virDomainEventVcpuRemovedDispose(void *obj);
static void virDomainEventMetadataChangeDispose(void *obj);
static void virDomainEventBlockThresholdDispose(void *obj);
static void virDomainEventMemoryFailureDispose(void *obj);
};
typedef struct _virDomainEventDeviceRemovalFailed virDomainEventDeviceRemovalFailed;
+struct _virDomainEventVcpuRemoved {
+ virDomainEvent parent;
+
+ unsigned int vcpuid;
+};
+typedef struct _virDomainEventVcpuRemoved virDomainEventVcpuRemoved;
+
struct _virDomainEventMetadataChange {
virDomainEvent parent;
return -1;
if (!VIR_CLASS_NEW(virDomainEventDeviceRemovalFailed, virDomainEventClass))
return -1;
+ if (!VIR_CLASS_NEW(virDomainEventVcpuRemoved, virDomainEventClass))
+ return -1;
if (!VIR_CLASS_NEW(virDomainEventMetadataChange, virDomainEventClass))
return -1;
if (!VIR_CLASS_NEW(virDomainEventBlockThreshold, virDomainEventClass))
g_free(event->devAlias);
}
+static void
+virDomainEventVcpuRemovedDispose(void *obj)
+{
+ virDomainEventVcpuRemoved *event = obj;
+ VIR_DEBUG("obj=%p", event);
+}
+
static void
virDomainEventPMDispose(void *obj)
devAlias);
}
+static virObjectEvent *
+virDomainEventVcpuRemovedNew(int id,
+ const char *name,
+ unsigned char *uuid,
+ unsigned int vcpuid)
+{
+ virDomainEventVcpuRemoved *ev;
+
+ if (virDomainEventsInitialize() < 0)
+ return NULL;
+
+ if (!(ev = virDomainEventNew(virDomainEventVcpuRemovedClass,
+ VIR_DOMAIN_EVENT_ID_VCPU_REMOVED,
+ id, name, uuid)))
+ return NULL;
+
+ ev->vcpuid = vcpuid;
+
+ return (virObjectEvent *)ev;
+}
+
+virObjectEvent *
+virDomainEventVcpuRemovedNewFromObj(virDomainObj *obj,
+ unsigned int vcpuid)
+{
+ return virDomainEventVcpuRemovedNew(obj->def->id, obj->def->name,
+ obj->def->uuid, vcpuid);
+}
+
+virObjectEvent *
+virDomainEventVcpuRemovedNewFromDom(virDomainPtr dom,
+ unsigned int vcpuid)
+{
+ return virDomainEventVcpuRemovedNew(dom->id, dom->name, dom->uuid,
+ vcpuid);
+}
+
static virObjectEvent *
virDomainEventAgentLifecycleNew(int id,
goto cleanup;
}
+ case VIR_DOMAIN_EVENT_ID_VCPU_REMOVED:
+ {
+ virDomainEventVcpuRemoved *vcpuRemovedEvent;
+
+ vcpuRemovedEvent = (virDomainEventVcpuRemoved *)event;
+ ((virConnectDomainEventVcpuRemovedCallback)cb)(conn, dom,
+ vcpuRemovedEvent->vcpuid,
+ cbopaque);
+ goto cleanup;
+ }
+
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}
virObjectEvent *
virDomainEventDeviceRemovalFailedNewFromDom(virDomainPtr dom,
const char *devAlias);
+virObjectEvent *
+virDomainEventVcpuRemovedNewFromObj(virDomainObj *obj,
+ unsigned int vcpuid);
+virObjectEvent *
+virDomainEventVcpuRemovedNewFromDom(virDomainPtr dom,
+ unsigned int vcpuid);
virObjectEvent *
virDomainEventTunableNewFromObj(virDomainObj *obj,
virDomainEventTrayChangeNewFromObj;
virDomainEventTunableNewFromDom;
virDomainEventTunableNewFromObj;
+virDomainEventVcpuRemovedNewFromDom;
+virDomainEventVcpuRemovedNewFromObj;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
virDomainQemuMonitorEventNew;
return 0;
}
+static int
+remoteRelayDomainEventVcpuRemoved(virConnectPtr conn,
+ virDomainPtr dom,
+ unsigned int vcpuid,
+ void *opaque)
+{
+ daemonClientEventCallback *callback = opaque;
+ remote_domain_event_vcpu_removed_msg data;
+
+ if (callback->callbackID < 0 ||
+ !remoteRelayDomainEventCheckACL(callback->client, conn, dom))
+ return -1;
+
+ memset(&data, 0, sizeof(data));
+ data.callbackID = callback->callbackID;
+ data.vcpuid = vcpuid;
+ make_nonnull_domain(&data.dom, dom);
+
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED,
+ (xdrproc_t)xdr_remote_domain_event_vcpu_removed_msg,
+ &data);
+ return 0;
+}
+
static int
remoteRelayDomainEventNICMACChange(virConnectPtr conn,
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMemoryFailure),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMemoryDeviceSizeChange),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventNICMACChange),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventVcpuRemoved),
};
G_STATIC_ASSERT(G_N_ELEMENTS(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
virNetClient *client,
void *evdata, void *opaque);
static void
+remoteDomainBuildEventVcpuRemoved(virNetClientProgram *prog,
+ virNetClient *client,
+ void *evdata, void *opaque);
+static void
remoteConnectNotifyEventConnectionClosed(virNetClientProgram *prog G_GNUC_UNUSED,
virNetClient *client G_GNUC_UNUSED,
void *evdata, void *opaque);
remoteDomainBuildEventNICMACChange,
sizeof(remote_domain_event_nic_mac_change_msg),
(xdrproc_t)xdr_remote_domain_event_nic_mac_change_msg },
+ { REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED,
+ remoteDomainBuildEventVcpuRemoved,
+ sizeof(remote_domain_event_vcpu_removed_msg),
+ (xdrproc_t)xdr_remote_domain_event_vcpu_removed_msg },
};
static void
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
}
+static void
+remoteDomainBuildEventVcpuRemoved(virNetClientProgram *prog G_GNUC_UNUSED,
+ virNetClient *client G_GNUC_UNUSED,
+ void *evdata, void *opaque)
+{
+ virConnectPtr conn = opaque;
+ remote_domain_event_vcpu_removed_msg *msg = evdata;
+ struct private_data *priv = conn->privateData;
+ virDomainPtr dom;
+ virObjectEvent *event = NULL;
+
+ if (!(dom = get_nonnull_domain(conn, msg->dom)))
+ return;
+
+ event = virDomainEventVcpuRemovedNewFromDom(dom, msg->vcpuid);
+
+ virObjectUnref(dom);
+
+ virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
+}
+
static void
remoteDomainBuildEventNICMACChange(virNetClientProgram *prog G_GNUC_UNUSED,
unsigned hyper size;
};
+struct remote_domain_event_vcpu_removed_msg {
+ int callbackID;
+ remote_nonnull_domain dom;
+ unsigned int vcpuid;
+};
+
struct remote_domain_fd_associate_args {
remote_nonnull_domain dom;
* @generate: both
* @acl: none
*/
- REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453
+ REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453,
+
+ /**
+ * @generate: both
+ * @acl: none
+ */
+ REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED = 454
};
remote_nonnull_string alias;
uint64_t size;
};
+struct remote_domain_event_vcpu_removed_msg {
+ int callbackID;
+ remote_nonnull_domain dom;
+ u_int vcpuid;
+};
struct remote_domain_fd_associate_args {
remote_nonnull_domain dom;
remote_nonnull_string name;
REMOTE_PROC_DOMAIN_SET_THROTTLE_GROUP = 451,
REMOTE_PROC_DOMAIN_DEL_THROTTLE_GROUP = 452,
REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453,
+ REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED = 454,
};
virshEventPrint(opaque, &buf);
}
+static void
+virshEventVcpuRemovedPrint(virConnectPtr conn G_GNUC_UNUSED,
+ virDomainPtr dom,
+ unsigned int vcpuid,
+ void *opaque)
+{
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAsprintf(&buf,
+ _("event 'vcpu-removed' for domain '%1$s': vcpu %2$u\n"),
+ virDomainGetName(dom), vcpuid);
+ virshEventPrint(opaque, &buf);
+}
+
VIR_ENUM_DECL(virshEventMetadataChangeType);
VIR_ENUM_IMPL(virshEventMetadataChangeType,
VIR_DOMAIN_METADATA_LAST,
VIR_DOMAIN_EVENT_CALLBACK(virshEventMemoryDeviceSizeChangePrint), },
{ "nic-mac-change",
VIR_DOMAIN_EVENT_CALLBACK(virshEventNICMACChangePrint), },
+ { "vcpu-removed",
+ VIR_DOMAIN_EVENT_CALLBACK(virshEventVcpuRemovedPrint), },
};
G_STATIC_ASSERT(VIR_DOMAIN_EVENT_ID_LAST == G_N_ELEMENTS(virshDomainEventCallbacks));