Use data provided by "query-chardev" to refresh the guest frontend state
of virtio channels.
---
src/qemu/qemu_process.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f19963c..3c3ff66 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2068,6 +2068,61 @@ qemuProcessFindCharDevicePTYs(virDomainObjPtr vm,
static int
+qemuProcessRefreshChannelVirtioState(virDomainObjPtr vm,
+ virHashTablePtr info)
+{
+ size_t i;
+ qemuMonitorChardevInfoPtr entry;
+ char id[32];
+
+ for (i = 0; i < vm->def->nchannels; i++) {
+ virDomainChrDefPtr chr = vm->def->channels[i];
+ if (chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
+ if (snprintf(id, sizeof(id), "char%s",
+ chr->info.alias) >= sizeof(id)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to format device alias "
+ "for PTY retrieval"));
+ return -1;
+ }
+
+ /* port state not reported */
+ if (!(entry = virHashLookup(info, id)))
+ continue;
+
+ chr->state = entry->state;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+qemuProcessReconnectRefreshChannelVirtioState(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virHashTablePtr info = NULL;
+ int ret = -1;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ ret = qemuMonitorGetChardevInfo(priv->mon, &info);
+ qemuDomainObjExitMonitor(driver, vm);
+
+ if (ret < 0)
+ goto cleanup;
+
+ ret = qemuProcessRefreshChannelVirtioState(vm, info);
+
+ cleanup:
+ virHashFree(info);
+ return ret;
+
+}
+
+
+static int
qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
virDomainObjPtr vm,
int asyncJob,
@@ -2110,8 +2165,14 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
qemuDomainObjExitMonitor(driver, vm);
VIR_DEBUG("qemuMonitorGetChardevInfo returned %i", ret);
- if (ret == 0)
- ret = qemuProcessFindCharDevicePTYsMonitor(vm, qemuCaps, info);
+ if (ret == 0) {
+ if ((ret = qemuProcessFindCharDevicePTYsMonitor(vm, qemuCaps,
+ info)) != 0)
+ goto cleanup;
+
+ if ((ret = qemuProcessRefreshChannelVirtioState(vm, info)) != 0)
+ goto cleanup;
+ }
cleanup:
virHashFree(info);
@@ -3594,6 +3655,9 @@ qemuProcessReconnect(void *opaque)
if (qemuDomainCheckEjectableMedia(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
+ if (qemuProcessReconnectRefreshChannelVirtioState(driver, obj) < 0)
+ goto error;
+
if (qemuProcessRecoverJob(driver, obj, conn, &oldjob) < 0)
goto error;
--
2.1.0