diff options
author | 2010-04-21 11:42:50 +0100 | |
---|---|---|
committer | 2010-04-28 13:47:49 +0100 | |
commit | ae42979a74a2a137e179709754f4642edb114a92 (patch) | |
tree | df4d0593966fe9702d612f25465b2ea57e8054c5 | |
parent | Fix crash when cleaning up from failed save attempt (diff) | |
download | libvirt-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.c | 21 |
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); |