aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/qemu/qemu_driver.c')
-rw-r--r--src/qemu/qemu_driver.c77
1 files changed, 71 insertions, 6 deletions
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e8fe37b67..c8dabd3e2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4568,6 +4568,12 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr
struct timeval now;
int rc;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit during migration"));
+ goto cleanup;
+ }
+
if (priv->jobSignals & QEMU_JOB_SIGNAL_CANCEL) {
priv->jobSignals ^= QEMU_JOB_SIGNAL_CANCEL;
VIR_DEBUG0("Cancelling migration at client request");
@@ -4595,6 +4601,15 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr
VIR_WARN0("Unable to set migration downtime");
}
+ /* Repeat check because the job signals might have caused
+ * guest to die
+ */
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit during migration"));
+ goto cleanup;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorGetMigrationStatus(priv->mon,
&status,
@@ -4793,6 +4808,12 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
goto endjob;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ goto endjob;
+ }
}
/* Get XML for the domain */
@@ -5308,6 +5329,12 @@ static int qemudDomainCoreDump(virDomainPtr dom,
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
paused = 1;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ goto endjob;
+ }
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -5340,7 +5367,7 @@ endjob:
/* Since the monitor is always attached to a pty for libvirt, it
will support synchronous operations so we always get here after
the migration is complete. */
- else if (resume && paused) {
+ else if (resume && paused && priv->mon) {
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuMonitorStartCPUs(priv->mon, dom->conn) < 0) {
if (virGetLastError() == NULL)
@@ -5377,15 +5404,15 @@ static int qemudDomainHotplugVcpus(virDomainObjPtr vm, unsigned int nvcpus)
int i, rc;
int ret = -1;
+ qemuDomainObjEnterMonitor(vm);
+
/* We need different branches here, because we want to offline
* in reverse order to onlining, so any partial fail leaves us in a
* reasonably sensible state */
if (nvcpus > vm->def->vcpus) {
for (i = vm->def->vcpus ; i < nvcpus ; i++) {
/* Online new CPU */
- qemuDomainObjEnterMonitor(vm);
rc = qemuMonitorSetCPU(priv->mon, i, 1);
- qemuDomainObjExitMonitor(vm);
if (rc == 0)
goto unsupported;
if (rc < 0)
@@ -5396,9 +5423,7 @@ static int qemudDomainHotplugVcpus(virDomainObjPtr vm, unsigned int nvcpus)
} else {
for (i = vm->def->vcpus - 1 ; i >= nvcpus ; i--) {
/* Offline old CPU */
- qemuDomainObjEnterMonitor(vm);
rc = qemuMonitorSetCPU(priv->mon, i, 0);
- qemuDomainObjExitMonitor(vm);
if (rc == 0)
goto unsupported;
if (rc < 0)
@@ -5411,6 +5436,7 @@ static int qemudDomainHotplugVcpus(virDomainObjPtr vm, unsigned int nvcpus)
ret = 0;
cleanup:
+ qemuDomainObjExitMonitor(vm);
return ret;
unsupported:
@@ -6960,6 +6986,15 @@ qemuDomainFindOrCreateSCSIDiskController(struct qemud_driver *driver,
VIR_FREE(cont);
return NULL;
}
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ /* cont doesn't need freeing here, since the reference
+ * now held in def->controllers */
+ return NULL;
+ }
+
return cont;
}
@@ -7236,6 +7271,12 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
goto cleanup;
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ goto cleanup;
+ }
}
/* FIXME - need to support vhost-net here (5th arg) */
@@ -7261,6 +7302,12 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
close(tapfd);
tapfd = -1;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ goto cleanup;
+ }
+
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
if (!(nicstr = qemuBuildNicDevStr(net, vlan)))
goto try_remove;
@@ -7309,6 +7356,9 @@ cleanup:
return ret;
try_remove:
+ if (!priv->mon)
+ goto cleanup;
+
if (vlan < 0) {
VIR_WARN0(_("Unable to remove network backend"));
} else {
@@ -7325,6 +7375,9 @@ try_remove:
goto cleanup;
try_tapfd_close:
+ if (!priv->mon)
+ goto cleanup;
+
if (tapfd_name) {
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuMonitorCloseFileHandle(priv->mon, tapfd_name) < 0)
@@ -10132,6 +10185,12 @@ static int doTunnelMigrate(virDomainPtr dom,
goto finish;
}
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ goto cleanup;
+ }
+
/* From this point onwards we *must* call cancel to abort the
* migration on source if anything goes wrong */
@@ -10167,7 +10226,7 @@ static int doTunnelMigrate(virDomainPtr dom,
retval = doTunnelSendAll(st, client_sock);
cancel:
- if (retval != 0) {
+ if (retval != 0 && priv->mon) {
qemuDomainObjEnterMonitorWithDriver(driver, vm);
qemuMonitorMigrateCancel(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
@@ -10442,6 +10501,12 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
* object, but if no, clean up the empty qemu process.
*/
if (retcode == 0) {
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest unexpectedly quit"));
+ goto cleanup;
+ }
+
if (flags & VIR_MIGRATE_PERSIST_DEST) {
if (vm->persistent)
newVM = 0;