On Thu, Jul 05, 2018 at 09:44:38 +0200, Michal Privoznik wrote:
If qemu-pr-helper process died while libvirtd was not running no
event is emitted. Therefore, when reconnecting to the monitor we
must check the qemu-pr-helper process status and act accordingly.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_process.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ac2f73c99e..b6db337e76 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2071,6 +2071,64 @@ qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
return ret;
}
+
+static int
+qemuProcessRefreshPRManagerState(virDomainObjPtr vm,
+ virHashTablePtr info)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuMonitorPRManagerInfoPtr prManagerInfo;
+ const char *managedAlias = qemuDomainGetManagedPRAlias();
+ int ret = -1;
+
+ if (!(prManagerInfo = virHashLookup(info, managedAlias))) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("missing info on pr-manager %s"),
+ managedAlias);
+ goto cleanup;
+ }
+
+ priv->prDaemonRunning = prManagerInfo->connected;
+
+ if (!priv->prDaemonRunning &&
+ virDomainDefHasManagedPR(vm->def) &&
You can assume this since you already checked in the caller.
+ qemuProcessStartManagedPRDaemon(vm) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+
+static int
+qemuRefreshPRManagerState(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virHashTablePtr info = NULL;
+ int ret = -1;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PR_MANAGER_HELPER) ||
+ !virDomainDefHasManagedPR(vm->def))
+ return 0;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ ret = qemuMonitorGetPRManagerInfo(priv->mon, &info);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ ret = -1;
+
+ if (ret < 0)
+ goto cleanup;
+
+ ret = qemuProcessRefreshPRManagerState(vm, info);
+
+ cleanup:
+ virHashFree(info);
+ return ret;
+}
+
+
static void
qemuRefreshRTC(virQEMUDriverPtr driver,
virDomainObjPtr vm)
@@ -7724,6 +7782,9 @@ qemuProcessReconnect(void *opaque)
if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
+ if (qemuRefreshPRManagerState(driver, obj) < 0)
+ goto error;
This is executed prior to qemuProcessUpdateDevices and thus if a disk
detach with the PR manager succeeds during the time libvirtd was gone
the above code will not be able to find the correct state and will kill
the VM.
+
/* If querying of guest's RTC failed, report error, but do not kill the domain.
*/
qemuRefreshRTC(driver, obj);
ACK if you move it to the correct place and simplify the restarting
code.