Emit the channel lifecycle event on VSERPORT_CHANGE
and when refreshing virtio state.

On "org.qemu.guest_agent.0" channel state change both
agent and channel lifecycle events are emitted in that order.

Signed-off-by: Lucas Kornicki <[email protected]>
---
 src/qemu/qemu_driver.c  |  8 ++++++++
 src/qemu/qemu_process.c | 28 ++++++++++++++++++++++------
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index eda1f42054..d260c1cc74 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3906,6 +3906,14 @@ processSerialChangedEvent(virQEMUDriver *driver,
         virObjectEventStateQueue(driver->domainEventState, event);
     }
 
+    /* we deliberately allow for goto endjob to skip generic event emission
+     * to ensure identical semantics for "org.qemu.guest_agent.0" */
+    event = virDomainEventChannelLifecycleNewFromObj(vm,
+                                                     dev.data.chr->target.name,
+                                                     newstate,
+                                                     
VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_CHANNEL);
+    virObjectEventStateQueue(driver->domainEventState, event);
+
  endjob:
     virDomainObjEndJob(vm);
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 83f5ebb19c..38c1fa05ce 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2253,7 +2253,7 @@ qemuProcessRefreshChannelVirtioState(virQEMUDriver 
*driver,
     size_t i;
     int agentReason = VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL;
     qemuMonitorChardevInfo *entry;
-    virObjectEvent *event = NULL;
+    virObjectEvent *events[2];
     g_autofree char *id = NULL;
 
     if (booted)
@@ -2271,11 +2271,27 @@ qemuProcessRefreshChannelVirtioState(virQEMUDriver 
*driver,
                 !entry->state)
                 continue;
 
-            if (entry->state != VIR_DOMAIN_CHR_DEVICE_STATE_DEFAULT &&
-                STREQ_NULLABLE(chr->target.name, "org.qemu.guest_agent.0") &&
-                (event = virDomainEventAgentLifecycleNewFromObj(vm, 
entry->state,
-                                                                agentReason)))
-                virObjectEventStateQueue(driver->domainEventState, event);
+            if (entry->state != VIR_DOMAIN_CHR_DEVICE_STATE_DEFAULT) {
+                events[0] = virDomainEventChannelLifecycleNewFromObj(vm,
+                                                                     
chr->target.name,
+                                                                     
entry->state,
+                                                                     
agentReason);
+                if (STREQ_NULLABLE(chr->target.name, 
"org.qemu.guest_agent.0")) {
+                    events[1] = virDomainEventAgentLifecycleNewFromObj(vm,
+                                                                       
entry->state,
+                                                                       
agentReason);
+                } else {
+                    events[1] = NULL;
+                }
+
+                /* emit agent then channel when emitting both events */
+                if (events[0] && events[1]) {
+                    virObjectEventStateQueue(driver->domainEventState, 
events[1]);
+                    virObjectEventStateQueue(driver->domainEventState, 
events[0]);
+                } else if (events[0]) {
+                    virObjectEventStateQueue(driver->domainEventState, 
events[0]);
+                }
+            }
 
             chr->state = entry->state;
         }
-- 
2.43.0

Reply via email to