|
|
c401cc |
From feb15e85c1f12d31dc2db7bbaabcfb4ad93ccb03 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <feb15e85c1f12d31dc2db7bbaabcfb4ad93ccb03@dist-git>
|
|
|
c401cc |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
c401cc |
Date: Wed, 26 Feb 2014 14:55:19 +0100
|
|
|
c401cc |
Subject: [PATCH] qemu: snapshot: Avoid libvirtd crash when qemu crashes while
|
|
|
c401cc |
snapshotting
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
|
|
|
c401cc |
|
|
|
c401cc |
We shouldn't access the domain definition while we are in the monitor
|
|
|
c401cc |
section as the domain is unlocked. Additionally after we exit from the
|
|
|
c401cc |
monitor we need to check if the VM is still alive. Not doing so resulted
|
|
|
c401cc |
in a crash if qemu exits while attempting to do an external VM snapshot.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit 55bbb011b965c7962933604c70f61cef45e8ec04)
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/qemu/qemu_driver.c | 53 ++++++++++++++++++++++++++++++++++++++------------
|
|
|
c401cc |
1 file changed, 41 insertions(+), 12 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
c401cc |
index 2fe128e..fe55fed 100644
|
|
|
c401cc |
--- a/src/qemu/qemu_driver.c
|
|
|
c401cc |
+++ b/src/qemu/qemu_driver.c
|
|
|
c401cc |
@@ -12489,7 +12489,8 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
virDomainDiskDefPtr disk,
|
|
|
c401cc |
virDomainDiskDefPtr persistDisk,
|
|
|
c401cc |
virJSONValuePtr actions,
|
|
|
c401cc |
- bool reuse)
|
|
|
c401cc |
+ bool reuse,
|
|
|
c401cc |
+ enum qemuDomainAsyncJob asyncJob)
|
|
|
c401cc |
{
|
|
|
c401cc |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
c401cc |
char *device = NULL;
|
|
|
c401cc |
@@ -12541,8 +12542,25 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
/* create the actual snapshot */
|
|
|
c401cc |
if (snap->format)
|
|
|
c401cc |
formatStr = virStorageFileFormatTypeToString(snap->format);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ /* The monitor is only accessed if qemu doesn't support transactions.
|
|
|
c401cc |
+ * Otherwise the following monitor command only constructs the command.
|
|
|
c401cc |
+ */
|
|
|
c401cc |
+ if (!actions &&
|
|
|
c401cc |
+ qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
ret = qemuMonitorDiskSnapshot(priv->mon, actions, device, source,
|
|
|
c401cc |
formatStr, reuse);
|
|
|
c401cc |
+ if (!actions) {
|
|
|
c401cc |
+ qemuDomainObjExitMonitor(driver, vm);
|
|
|
c401cc |
+ if (!virDomainObjIsActive(vm)) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
c401cc |
+ _("domain crashed while taking the snapshot"));
|
|
|
c401cc |
+ ret = -1;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
virDomainAuditDisk(vm, disk->src, source, "snapshot", ret >= 0);
|
|
|
c401cc |
if (ret < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
@@ -12648,9 +12666,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
* Based on earlier qemuDomainSnapshotPrepare, all
|
|
|
c401cc |
* disks in this list are now either SNAPSHOT_NO, or
|
|
|
c401cc |
* SNAPSHOT_EXTERNAL with a valid file name and qcow2 format. */
|
|
|
c401cc |
- if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
-
|
|
|
c401cc |
for (i = 0; i < snap->def->ndisks; i++) {
|
|
|
c401cc |
virDomainDiskDefPtr persistDisk = NULL;
|
|
|
c401cc |
|
|
|
c401cc |
@@ -12660,24 +12675,36 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
int indx = virDomainDiskIndexByName(vm->newDef,
|
|
|
c401cc |
vm->def->disks[i]->dst,
|
|
|
c401cc |
false);
|
|
|
c401cc |
- if (indx >= 0) {
|
|
|
c401cc |
+ if (indx >= 0)
|
|
|
c401cc |
persistDisk = vm->newDef->disks[indx];
|
|
|
c401cc |
- persist = true;
|
|
|
c401cc |
- }
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
|
|
|
c401cc |
&snap->def->disks[i],
|
|
|
c401cc |
vm->def->disks[i],
|
|
|
c401cc |
persistDisk, actions,
|
|
|
c401cc |
- reuse);
|
|
|
c401cc |
+ reuse, asyncJob);
|
|
|
c401cc |
if (ret < 0)
|
|
|
c401cc |
break;
|
|
|
c401cc |
}
|
|
|
c401cc |
if (actions) {
|
|
|
c401cc |
- if (ret == 0)
|
|
|
c401cc |
- ret = qemuMonitorTransaction(priv->mon, actions);
|
|
|
c401cc |
+ if (ret == 0) {
|
|
|
c401cc |
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
|
|
|
c401cc |
+ ret = qemuMonitorTransaction(priv->mon, actions);
|
|
|
c401cc |
+ qemuDomainObjExitMonitor(driver, vm);
|
|
|
c401cc |
+ if (!virDomainObjIsActive(vm)) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
c401cc |
+ _("domain crashed while taking the snapshot"));
|
|
|
c401cc |
+ ret = -1;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ } else {
|
|
|
c401cc |
+ /* failed to enter monitor, clean stuff up and quit */
|
|
|
c401cc |
+ ret = -1;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
virJSONValueFree(actions);
|
|
|
c401cc |
+
|
|
|
c401cc |
if (ret < 0) {
|
|
|
c401cc |
/* Transaction failed; undo the changes to vm. */
|
|
|
c401cc |
bool need_unlink = !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT);
|
|
|
c401cc |
@@ -12691,8 +12718,11 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
int indx = virDomainDiskIndexByName(vm->newDef,
|
|
|
c401cc |
vm->def->disks[i]->dst,
|
|
|
c401cc |
false);
|
|
|
c401cc |
- if (indx >= 0)
|
|
|
c401cc |
+ if (indx >= 0) {
|
|
|
c401cc |
persistDisk = vm->newDef->disks[indx];
|
|
|
c401cc |
+ persist = true;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
qemuDomainSnapshotUndoSingleDiskActive(driver, vm,
|
|
|
c401cc |
@@ -12703,7 +12733,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
|
|
|
c401cc |
}
|
|
|
c401cc |
}
|
|
|
c401cc |
}
|
|
|
c401cc |
- qemuDomainObjExitMonitor(driver, vm);
|
|
|
c401cc |
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
|
|
|
c401cc |
--
|
|
|
c401cc |
1.9.0
|
|
|
c401cc |
|