mirror of https://gitee.com/openkylin/libvirt.git
qemu: Connect to guest agent iff needed
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>
This commit is contained in:
parent
d860b2f537
commit
88ed9d771e
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -166,4 +166,6 @@ int qemuProcessSetupVcpu(virDomainObjPtr vm,
|
|||
int qemuProcessSetupIOThread(virDomainObjPtr vm,
|
||||
virDomainIOThreadIDDefPtr iothread);
|
||||
|
||||
int qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm);
|
||||
#endif /* __QEMU_PROCESS_H__ */
|
||||
|
|
Loading…
Reference in New Issue