]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: Connect to guest agent after channel hotplug
authorPeter Krempa <pkrempa@redhat.com>
Fri, 24 Apr 2015 14:48:26 +0000 (16:48 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Sun, 26 Apr 2015 15:19:22 +0000 (17:19 +0200)
If a user hot-attaches the guest agent channel libvirt would ignore it
until the restart of libvirtd or shutdown/destroy and start of the VM
itself.

This patch adds code that opens or closes the guest agent connection
according to the state of the guest agent channel according to
connect/disconnect events.

To allow opening the channel from the event handler qemuConnectAgent
needed to be exported.

src/qemu/qemu_driver.c
src/qemu/qemu_process.c
src/qemu/qemu_process.h

index 6b16441907fa39f76d9b86d731d6cac089858bf5..70bf7aa1d6d6834aea67498ee16ae24ecdbd8463 100644 (file)
@@ -4468,6 +4468,8 @@ processSerialChangedEvent(virQEMUDriverPtr driver,
     virDomainChrDeviceState newstate;
     virObjectEventPtr event = NULL;
     virDomainDeviceDef dev;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int rc;
 
     if (connected)
         newstate = VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED;
@@ -4494,10 +4496,35 @@ processSerialChangedEvent(virQEMUDriverPtr driver,
         dev.data.chr->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO)
         goto endjob;
 
-    if (STREQ_NULLABLE(dev.data.chr->target.name, "org.qemu.guest_agent.0") &&
-        (event = virDomainEventAgentLifecycleNewFromObj(vm, newstate,
-                                                        VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL)))
-        qemuDomainEventQueue(driver, event);
+    if (STREQ_NULLABLE(dev.data.chr->target.name, "org.qemu.guest_agent.0")) {
+        switch (newstate) {
+        case VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED:
+            if (!priv->agent) {
+                if ((rc = qemuConnectAgent(driver, vm)) == -2)
+                    goto endjob;
+
+                if (rc < 0)
+                    priv->agentError = true;
+            }
+            break;
+
+        case VIR_DOMAIN_CHR_DEVICE_STATE_DISCONNECTED:
+            if (priv->agent) {
+                qemuAgentClose(priv->agent);
+                priv->agent = NULL;
+                priv->agentError = false;
+            }
+            break;
+
+        case VIR_DOMAIN_CHR_DEVICE_STATE_DEFAULT:
+        case VIR_DOMAIN_CHR_DEVICE_STATE_LAST:
+            break;
+        };
+
+        if ((event = virDomainEventAgentLifecycleNewFromObj(vm, newstate,
+                                                            VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL)))
+            qemuDomainEventQueue(driver, event);
+    }
 
     dev.data.chr->state = newstate;
 
index 75ccb66ff58c7f9c7852c99609dc5ee2acc5c5a7..7eeee47255247b11e8ae2ae0cecb40cd368bc1e4 100644 (file)
@@ -202,7 +202,7 @@ static qemuAgentCallbacks agentCallbacks = {
 };
 
 
-static int
+int
 qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
index c67b0cb677719a35d7aed2cbfce050d4c670ab6c..d40f68d3a9d10643481536f2aa999643dc182844 100644 (file)
@@ -113,4 +113,6 @@ int qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
 virDomainDiskDefPtr qemuProcessFindDomainDiskByAlias(virDomainObjPtr vm,
                                                      const char *alias);
 
+int qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm);
+
 #endif /* __QEMU_PROCESS_H__ */