]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Connect to guest agent iff needed
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 8 Jan 2016 16:03:48 +0000 (17:03 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 11 Feb 2016 05:52:50 +0000 (06:52 +0100)
https://bugzilla.redhat.com/show_bug.cgi?id=1293351

Since we already have virtio channel events, we know when guest
agent within guest has (dis-)connected. Instead of us blindly
connecting to a socket that no one is listening to, we can just
follow what qemu-ga does. This has a nice benefit that we don't
need to 'guest-ping' the agent just to timeout and find out
nobody is listening.

The way that this commit is implemented:
- don't connect in qemuProcessLaunch directly, defer that to event
  callback (which already follows the agent) -
  processSerialChangedEvent
- after migration is settled, before we resume vCPUs, ask qemu
  whether somebody is listening on the socket and if so, connect
  to it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_migration.c
src/qemu/qemu_process.c
src/qemu/qemu_process.h

index 793e412070a3d0ed3a7e4298171ec2aa2d97f4a5..f2c7b611cedfdff1b441a03b18cbdfcc3b5f7a51 100644 (file)
@@ -5711,6 +5711,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
     unsigned short port;
     unsigned long long timeReceived = 0;
     virObjectEventPtr event;
+    int rc;
 
     VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
               "cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d",
@@ -5779,6 +5780,20 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
     if (qemuMigrationStopNBDServer(driver, vm, mig) < 0)
         goto endjob;
 
+    if (qemuRefreshVirtioChannelState(driver, vm) < 0)
+        goto endjob;
+
+    if ((rc = qemuConnectAgent(driver, vm)) < 0) {
+        if (rc == -2)
+            goto endjob;
+
+        VIR_WARN("Cannot connect to QEMU guest agent for %s",
+                 vm->def->name);
+        virResetLastError();
+        priv->agentError = true;
+    }
+
+
     if (flags & VIR_MIGRATE_PERSIST_DEST) {
         if (qemuMigrationPersist(driver, vm, mig, !v3proto) < 0) {
             /* Hmpf.  Migration was successful, but making it persistent
index 2523d1d73a902d99c03eae7d5a0ab813f997257d..23238df279579ad389c35fbb0233747e363a6fb1 100644 (file)
@@ -208,6 +208,15 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
     if (!config)
         return 0;
 
+    if (priv->agent)
+        return 0;
+
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE) &&
+        config->state != VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED) {
+        VIR_DEBUG("Deferring connecting to guest agent");
+        return 0;
+    }
+
     if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager,
                                                vm->def) < 0) {
         VIR_ERROR(_("Failed to set security context for agent for %s"),
@@ -1887,9 +1896,9 @@ qemuProcessRefreshChannelVirtioState(virQEMUDriverPtr driver,
 }
 
 
-static int
-qemuProcessReconnectRefreshChannelVirtioState(virQEMUDriverPtr driver,
-                                              virDomainObjPtr vm)
+int
+qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virHashTablePtr info = NULL;
@@ -3371,17 +3380,6 @@ qemuProcessReconnect(void *opaque)
     if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0)
         goto error;
 
-    /* Failure to connect to agent shouldn't be fatal */
-    if ((ret = qemuConnectAgent(driver, obj)) < 0) {
-        if (ret == -2)
-            goto error;
-
-        VIR_WARN("Cannot connect to QEMU guest agent for %s",
-                 obj->def->name);
-        virResetLastError();
-        priv->agentError = true;
-    }
-
     if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0)
         goto error;
 
@@ -3468,7 +3466,7 @@ qemuProcessReconnect(void *opaque)
     if (qemuDomainCheckEjectableMedia(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
         goto error;
 
-    if (qemuProcessReconnectRefreshChannelVirtioState(driver, obj) < 0)
+    if (qemuRefreshVirtioChannelState(driver, obj) < 0)
         goto error;
 
     if (qemuProcessRefreshBalloonState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
@@ -3480,6 +3478,17 @@ qemuProcessReconnect(void *opaque)
     if (qemuProcessUpdateDevices(driver, obj) < 0)
         goto error;
 
+    /* Failure to connect to agent shouldn't be fatal */
+    if ((ret = qemuConnectAgent(driver, obj)) < 0) {
+        if (ret == -2)
+            goto error;
+
+        VIR_WARN("Cannot connect to QEMU guest agent for %s",
+                 obj->def->name);
+        virResetLastError();
+        priv->agentError = true;
+    }
+
     /* update domain state XML with possibly updated state in virDomainObj */
     if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) < 0)
         goto error;
index ad8041085e910060764cb95db7a87fe1ba633ad6..a1c33f4eb04eeccab65dd43913dfbaf7fae2df8c 100644 (file)
@@ -166,4 +166,6 @@ int qemuProcessSetupVcpu(virDomainObjPtr vm,
 int qemuProcessSetupIOThread(virDomainObjPtr vm,
                              virDomainIOThreadIDDefPtr iothread);
 
+int qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
+                                  virDomainObjPtr vm);
 #endif /* __QEMU_PROCESS_H__ */