aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2010-04-21 11:42:50 +0100
committerDaniel P. Berrange <berrange@redhat.com>2010-04-28 13:47:49 +0100
commitae42979a74a2a137e179709754f4642edb114a92 (patch)
treedf4d0593966fe9702d612f25465b2ea57e8054c5
parentFix crash when cleaning up from failed save attempt (diff)
downloadlibvirt-ae42979a74a2a137e179709754f4642edb114a92.tar.gz
libvirt-ae42979a74a2a137e179709754f4642edb114a92.tar.bz2
libvirt-ae42979a74a2a137e179709754f4642edb114a92.zip
Avoid create/unlink with block devs used for QEMU save
It is possible to use block devices with domain save/restore. Upon failure QEMU unlinks the path being saved to. This isn't good when it is a block device ! * src/qemu/qemu_driver.c: Don't unlink block devices if save fails
-rw-r--r--src/qemu/qemu_driver.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 180f2d67d..c485e8fb8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4713,6 +4713,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
int rc;
virDomainEventPtr event = NULL;
qemuDomainObjPrivatePtr priv;
+ struct stat sb;
+ int is_reg = 0;
memset(&header, 0, sizeof(header));
memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
@@ -4767,6 +4769,20 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
}
header.xml_len = strlen(xml) + 1;
+ /* path might be a pre-existing block dev, in which case
+ * we need to skip the create step, and also avoid unlink
+ * in the failure case */
+ if (stat(path, &sb) < 0) {
+ /* Avoid throwing an error here, since it is possible
+ * that with NFS we can't actually stat() the file.
+ * The subsequent codepaths will still raise an error
+ * if a truely fatal problem is hit */
+ is_reg = 1;
+ } else {
+ is_reg = S_ISREG(sb.st_mode);
+ }
+
+
/* Setup hook data needed by virFileOperation hook function */
hdata.dom = dom;
hdata.path = path;
@@ -4776,7 +4792,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
/* Write header to file, followed by XML */
/* First try creating the file as root */
- if ((rc = virFileOperation(path, O_CREAT|O_TRUNC|O_WRONLY,
+ if (is_reg &&
+ (rc = virFileOperation(path, O_CREAT|O_TRUNC|O_WRONLY,
S_IRUSR|S_IWUSR,
getuid(), getgid(),
qemudDomainSaveFileOpHook, &hdata,
@@ -4941,7 +4958,7 @@ endjob:
cleanup:
VIR_FREE(xml);
- if (ret != 0)
+ if (ret != 0 && is_reg)
unlink(path);
if (vm)
virDomainObjUnlock(vm);