diff --git a/src/fdstream.c b/src/fdstream.c index d2325aea55642bd7928a9ab13174380828292da9..2702ad7e43820b13e63db109310ad955e9f401e5 100644 --- a/src/fdstream.c +++ b/src/fdstream.c @@ -493,7 +493,8 @@ virFDStreamOpenFileInternal(virStreamPtr st, unsigned long long offset, unsigned long long length, int flags, - int mode) + int mode, + bool delete) { int fd = -1; int fds[2] = { -1, -1 }; @@ -502,8 +503,8 @@ virFDStreamOpenFileInternal(virStreamPtr st, int errfd = -1; pid_t pid = 0; - VIR_DEBUG("st=%p path=%s flags=%d offset=%llu length=%llu mode=%d", - st, path, flags, offset, length, mode); + VIR_DEBUG("st=%p path=%s flags=%d offset=%llu length=%llu mode=%d delete=%d", + st, path, flags, offset, length, mode, delete); if (flags & O_CREAT) fd = open(path, flags, mode); @@ -554,6 +555,14 @@ virFDStreamOpenFileInternal(virStreamPtr st, virCommandAddArgFormat(cmd, "%d", mode); virCommandAddArgFormat(cmd, "%llu", offset); virCommandAddArgFormat(cmd, "%llu", length); + virCommandAddArgFormat(cmd, "%u", delete); + + /* when running iohelper we don't want to delete file now, + * because a race condition may occur in which we delete it + * before iohelper even opens it. We want iohelper to remove + * the file instead. + */ + delete = false; if (flags == O_RDONLY) { childfd = fds[1]; @@ -583,6 +592,9 @@ virFDStreamOpenFileInternal(virStreamPtr st, if (virFDStreamOpenInternal(st, fd, cmd, errfd, length) < 0) goto error; + if (delete) + unlink(path); + return 0; error: @@ -601,7 +613,8 @@ int virFDStreamOpenFile(virStreamPtr st, const char *path, unsigned long long offset, unsigned long long length, - int flags) + int flags, + bool delete) { if (flags & O_CREAT) { streamsReportError(VIR_ERR_INTERNAL_ERROR, @@ -611,7 +624,7 @@ int virFDStreamOpenFile(virStreamPtr st, } return virFDStreamOpenFileInternal(st, path, offset, length, - flags, 0); + flags, 0, delete); } int virFDStreamCreateFile(virStreamPtr st, @@ -619,9 +632,11 @@ int virFDStreamCreateFile(virStreamPtr st, unsigned long long offset, unsigned long long length, int flags, - mode_t mode) + mode_t mode, + bool delete) { return virFDStreamOpenFileInternal(st, path, offset, length, - flags | O_CREAT, mode); + flags | O_CREAT, + mode, delete); } diff --git a/src/fdstream.h b/src/fdstream.h index 6b395b6775ff46e4d6563e45c27a6646ed981271..a66902b69c9a356a9ceb774864c4fe003838ed2a 100644 --- a/src/fdstream.h +++ b/src/fdstream.h @@ -37,12 +37,14 @@ int virFDStreamOpenFile(virStreamPtr st, const char *path, unsigned long long offset, unsigned long long length, - int flags); + int flags, + bool delete); int virFDStreamCreateFile(virStreamPtr st, const char *path, unsigned long long offset, unsigned long long length, int flags, - mode_t mode); + mode_t mode, + bool delete); #endif /* __VIR_FDSTREAM_H_ */ diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 1aadb027c019681c9ceab24e7c64d3e6d1437187..0939a1dd1944afe5cabf1a49df30a93362169aa2 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2691,7 +2691,8 @@ lxcDomainOpenConsole(virDomainPtr dom, goto cleanup; } - if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) + if (virFDStreamOpenFile(st, chr->source.data.file.path, + 0, 0, O_RDWR, false) < 0) goto cleanup; ret = 0; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7a3556f3296e32b8e3bb5f783bf7a9b5bf0b7db3..482f1771ecd11797059d4bacbfbff6da0ac69118 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7120,7 +7120,8 @@ qemuDomainOpenConsole(virDomainPtr dom, goto cleanup; } - if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) + if (virFDStreamOpenFile(st, chr->source.data.file.path, + 0, 0, O_RDWR, false) < 0) goto cleanup; ret = 0; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 903ecee8b08c232cd53c864a7576cd0723ea2c37..6542579c056c24374b3115242eda497f646a136d 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1592,7 +1592,7 @@ storageVolumeDownload(virStorageVolPtr obj, if (virFDStreamOpenFile(stream, vol->target.path, offset, length, - O_RDONLY) < 0) + O_RDONLY, false) < 0) goto out; ret = 0; @@ -1656,7 +1656,7 @@ storageVolumeUpload(virStorageVolPtr obj, if (virFDStreamOpenFile(stream, vol->target.path, offset, length, - O_WRONLY) < 0) + O_WRONLY, false) < 0) goto out; ret = 0; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index baef86c8345d78119c070cb626f68462929d58db..e7cd77a414da579a6ea59da9d44a836eb4fc42dd 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2130,7 +2130,8 @@ umlDomainOpenConsole(virDomainPtr dom, goto cleanup; } - if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) + if (virFDStreamOpenFile(st, chr->source.data.file.path, + 0, 0, O_RDWR, false) < 0) goto cleanup; ret = 0; diff --git a/src/util/iohelper.c b/src/util/iohelper.c index d5821b926d241632593d6d14b4bfa7beac76b3ae..f519d5a7a8e364e8d64eccb0c79f1576cd6e0052 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -146,6 +146,7 @@ int main(int argc, char **argv) unsigned long long length; int flags; int mode; + unsigned int delete; if (setlocale(LC_ALL, "") == NULL || bindtextdomain(PACKAGE, LOCALEDIR) == NULL || @@ -161,8 +162,8 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - if (argc != 6) { - fprintf(stderr, _("%s: syntax FILENAME FLAGS MODE OFFSET LENGTH\n"), argv[0]); + if (argc != 7) { + fprintf(stderr, _("%s: syntax FILENAME FLAGS MODE OFFSET LENGTH DELETE\n"), argv[0]); exit(EXIT_FAILURE); } @@ -186,10 +187,17 @@ int main(int argc, char **argv) fprintf(stderr, _("%s: malformed file length %s"), argv[0], argv[5]); exit(EXIT_FAILURE); } + if (virStrToLong_ui(argv[6], NULL, 10, &delete) < 0) { + fprintf(stderr, _("%s: malformed delete flag %s"), argv[0],argv[6]); + exit(EXIT_FAILURE); + } if (runIO(path, flags, mode, offset, length) < 0) goto error; + if (delete) + unlink(path); + return 0; error: diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 0f19d2779995056ae3c21f7e065df265a1f33faa..5bafb73c9ca793f481bf95d7b62c97234b39ac04 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2086,7 +2086,8 @@ xenUnifiedDomainOpenConsole(virDomainPtr dom, goto cleanup; } - if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) + if (virFDStreamOpenFile(st, chr->source.data.file.path, + 0, 0, O_RDWR, false) < 0) goto cleanup; ret = 0;