[PATCH 0/5] ch: Emit more events

*** BLURB HERE *** Michal Prívozník (5): ch: Emit event on device attach ch: Emit event on device attach ch: Propagate lifecycle events ch: Implement virConnectDomainEventRegister() ch: Implement virConnectDomainEventDeregister() src/ch/ch_driver.c | 41 +++++++++++++++++++++++++++++++++ src/ch/ch_events.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ src/ch/ch_hotplug.c | 33 ++++++++++++++++++++++----- 3 files changed, 123 insertions(+), 6 deletions(-) -- 2.49.1

From: Michal Privoznik <mprivozn@redhat.com> When a device is attached to a running guest we ought to emit the VIR_DOMAIN_EVENT_ID_DEVICE_ADDED event. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/ch/ch_hotplug.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ch/ch_hotplug.c b/src/ch/ch_hotplug.c index 0a55a57069..e7734e2ff0 100644 --- a/src/ch/ch_hotplug.c +++ b/src/ch/ch_hotplug.c @@ -52,23 +52,26 @@ chDomainAddDisk(virCHMonitor *mon, } static int -chDomainAttachDeviceLive(virDomainObj *vm, +chDomainAttachDeviceLive(virCHDriver *driver, + virDomainObj *vm, virDomainDeviceDef *dev) { int ret = -1; virCHDomainObjPrivate *priv = vm->privateData; virCHMonitor *mon = priv->monitor; + const char *alias = NULL; switch (dev->type) { - case VIR_DOMAIN_DEVICE_DISK: { + case VIR_DOMAIN_DEVICE_DISK: if (chDomainAddDisk(mon, vm, dev->data.disk) < 0) { break; } + alias = dev->data.disk->info.alias; dev->data.disk = NULL; ret = 0; break; - } + case VIR_DOMAIN_DEVICE_NET: case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: @@ -104,6 +107,13 @@ chDomainAttachDeviceLive(virDomainObj *vm, break; } + if (alias) { + virObjectEvent *event; + + event = virDomainEventDeviceAddedNewFromObj(vm, alias); + virObjectEventStateQueue(driver->domainEventState, event); + } + return ret; } @@ -148,7 +158,7 @@ chDomainAttachDeviceLiveAndUpdateConfig(virDomainObj *vm, return -1; } - if (chDomainAttachDeviceLive(vm, devLive) < 0) { + if (chDomainAttachDeviceLive(driver, vm, devLive) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to add device")); return -1; -- 2.49.1

From: Michal Privoznik <mprivozn@redhat.com> When a device is detached from a running guest we ought to emit the VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED event. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/ch/ch_hotplug.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/ch/ch_hotplug.c b/src/ch/ch_hotplug.c index e7734e2ff0..b953fe4c6c 100644 --- a/src/ch/ch_hotplug.c +++ b/src/ch/ch_hotplug.c @@ -267,12 +267,15 @@ chDomainRemoveDevice(virDomainObj *vm, static int -chDomainDetachDeviceLive(virDomainObj *vm, +chDomainDetachDeviceLive(virCHDriver *driver, + virDomainObj *vm, virDomainDeviceDef *match) { virDomainDeviceDef detach = { .type = match->type }; virDomainDeviceInfo *info = NULL; virCHDomainObjPrivate *priv = vm->privateData; + virObjectEvent *event = NULL; + g_autofree char *alias = NULL; switch (match->type) { case VIR_DOMAIN_DEVICE_DISK: @@ -339,6 +342,11 @@ chDomainDetachDeviceLive(virDomainObj *vm, return -1; } + /* Save the alias to use when sending a DEVICE_REMOVED event after all + * other tear down is complete. + */ + alias = g_strdup(info->alias); + if (virCHMonitorRemoveDevice(priv->monitor, info->alias) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid response from CH. Disk removal failed.")); @@ -348,6 +356,9 @@ chDomainDetachDeviceLive(virDomainObj *vm, if (chDomainRemoveDevice(vm, &detach) < 0) return -1; + event = virDomainEventDeviceRemovedNewFromObj(vm, alias); + virObjectEventStateQueue(driver->domainEventState, event); + return 0; } @@ -386,7 +397,7 @@ chDomainDetachDeviceLiveAndUpdateConfig(virCHDriver *driver, return -1; } - if (chDomainDetachDeviceLive(vm, dev_live) < 0) { + if (chDomainDetachDeviceLive(driver, vm, dev_live) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could detach device")); return -1; -- 2.49.1

From: Michal Privoznik <mprivozn@redhat.com> We already have a thread that listens on cloud-hypervisor's monitor for incoming events and processes them. What is missing though, is emitting of corresponding lifecycle events. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/ch/ch_events.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/ch/ch_events.c b/src/ch/ch_events.c index cd2f92a493..5125f26912 100644 --- a/src/ch/ch_events.c +++ b/src/ch/ch_events.c @@ -25,6 +25,7 @@ #include "ch_domain.h" #include "ch_events.h" #include "ch_process.h" +#include "domain_event.h" #include "virfile.h" #include "virlog.h" @@ -65,6 +66,58 @@ virCHEventStopProcess(virDomainObj *vm, return 0; } + +static void +virCHProcessEmitEvent(virDomainObj *vm, + virCHEvent ev) +{ + virCHDriver *driver = CH_DOMAIN_PRIVATE(vm)->driver; + virObjectEvent *event = NULL; + + switch (ev) { + case VIR_CH_EVENT_VM_BOOTED: + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_BOOTED); + break; + case VIR_CH_EVENT_VM_PAUSED: + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); + break; + case VIR_CH_EVENT_VM_RESUMED: + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_RESUMED, + VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); + break; + case VIR_CH_EVENT_VM_REBOOTED: + event = virDomainEventRebootNewFromObj(vm); + break; + case VIR_CH_EVENT_VMM_SHUTDOWN: + case VIR_CH_EVENT_VM_SHUTDOWN: + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_SHUTDOWN, + VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED); + break; + case VIR_CH_EVENT_VMM_STARTING: + case VIR_CH_EVENT_VM_BOOTING: + case VIR_CH_EVENT_VM_REBOOTING: + case VIR_CH_EVENT_VM_DELETED: + case VIR_CH_EVENT_VM_PAUSING: + case VIR_CH_EVENT_VM_RESUMING: + case VIR_CH_EVENT_VM_SNAPSHOTTING: + case VIR_CH_EVENT_VM_SNAPSHOTTED: + case VIR_CH_EVENT_VM_RESTORING: + case VIR_CH_EVENT_VM_RESTORED: + case VIR_CH_EVENT_LAST: + default: + break; + } + + virObjectEventStateQueue(driver->domainEventState, event); +} + + static int virCHProcessEvent(virCHMonitor *mon, virJSONValue *eventJSON) @@ -91,6 +144,8 @@ virCHProcessEvent(virCHMonitor *mon, ev = virCHEventTypeFromString(full_event); VIR_DEBUG("%s: Source: %s, Event: %s, ev: %d", vm->def->name, source, event, ev); + virCHProcessEmitEvent(vm, ev); + switch (ev) { case VIR_CH_EVENT_VMM_STARTING: case VIR_CH_EVENT_VM_BOOTING: -- 2.49.1

From: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/ch/ch_driver.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index 0a516f3384..d16e2ed3aa 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -2434,6 +2434,27 @@ static int chDomainDetachDevice(virDomainPtr dom, const char *xml) VIR_DOMAIN_AFFECT_LIVE); } + +static int +chConnectDomainEventRegister(virConnectPtr conn, + virConnectDomainEventCallback callback, + void *opaque, + virFreeCallback freecb) +{ + virCHDriver *driver = conn->privateData; + + if (virConnectDomainEventRegisterEnsureACL(conn) < 0) + return -1; + + if (virDomainEventStateRegister(conn, + driver->domainEventState, + callback, opaque, freecb) < 0) + return -1; + + return 0; +} + + /* Function Tables */ static virHypervisorDriver chHypervisorDriver = { .name = "CH", @@ -2499,6 +2520,7 @@ static virHypervisorDriver chHypervisorDriver = { .domainAttachDeviceFlags = chDomainAttachDeviceFlags, /* 11.8.0 */ .domainDetachDevice = chDomainDetachDevice, /* 11.8.0 */ .domainDetachDeviceFlags = chDomainDetachDeviceFlags, /* 11.8.0 */ + .connectDomainEventRegister = chConnectDomainEventRegister, /* 11.8.0 */ }; static virConnectDriver chConnectDriver = { -- 2.49.1

From: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/ch/ch_driver.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index d16e2ed3aa..ad13306c4c 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -2455,6 +2455,24 @@ chConnectDomainEventRegister(virConnectPtr conn, } +static int +chConnectDomainEventDeregister(virConnectPtr conn, + virConnectDomainEventCallback callback) +{ + virCHDriver *driver = conn->privateData; + + if (virConnectDomainEventDeregisterEnsureACL(conn) < 0) + return -1; + + if (virDomainEventStateDeregister(conn, + driver->domainEventState, + callback) < 0) + return -1; + + return 0; +} + + /* Function Tables */ static virHypervisorDriver chHypervisorDriver = { .name = "CH", @@ -2521,6 +2539,7 @@ static virHypervisorDriver chHypervisorDriver = { .domainDetachDevice = chDomainDetachDevice, /* 11.8.0 */ .domainDetachDeviceFlags = chDomainDetachDeviceFlags, /* 11.8.0 */ .connectDomainEventRegister = chConnectDomainEventRegister, /* 11.8.0 */ + .connectDomainEventDeregister = chConnectDomainEventDeregister, /* 11.8.0 */ }; static virConnectDriver chConnectDriver = { -- 2.49.1

On a Friday in 2025, Michal Privoznik via Devel wrote:
*** BLURB HERE ***
Michal Prívozník (5): ch: Emit event on device attach ch: Emit event on device attach ch: Propagate lifecycle events ch: Implement virConnectDomainEventRegister() ch: Implement virConnectDomainEventDeregister()
src/ch/ch_driver.c | 41 +++++++++++++++++++++++++++++++++ src/ch/ch_events.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ src/ch/ch_hotplug.c | 33 ++++++++++++++++++++++----- 3 files changed, 123 insertions(+), 6 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Michal Privoznik