]> xenbits.xensource.com Git - libvirt.git/commitdiff
virFDStream: Add option for delete file after it's opening
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 5 Apr 2011 10:27:35 +0000 (12:27 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 13 May 2011 10:44:49 +0000 (12:44 +0200)
This is needed if we want to transfer a temporary file. If the
transfer is done with iohelper, we might run into a race condition,
where we unlink() file before iohelper is executed.

* src/fdstream.c, src/fdstream.h,
  src/util/iohelper.c: Add new option
* src/lxc/lxc_driver.c, src/qemu/qemu_driver.c,
  src/storage/storage_driver.c, src/uml/uml_driver.c,
  src/xen/xen_driver.c: Expand existing function calls

src/fdstream.c
src/fdstream.h
src/lxc/lxc_driver.c
src/qemu/qemu_driver.c
src/storage/storage_driver.c
src/uml/uml_driver.c
src/util/iohelper.c
src/xen/xen_driver.c

index d2325aea55642bd7928a9ab13174380828292da9..2702ad7e43820b13e63db109310ad955e9f401e5 100644 (file)
@@ -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);
 }
index 6b395b6775ff46e4d6563e45c27a6646ed981271..a66902b69c9a356a9ceb774864c4fe003838ed2a 100644 (file)
@@ -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_ */
index 1aadb027c019681c9ceab24e7c64d3e6d1437187..0939a1dd1944afe5cabf1a49df30a93362169aa2 100644 (file)
@@ -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;
index 7a3556f3296e32b8e3bb5f783bf7a9b5bf0b7db3..482f1771ecd11797059d4bacbfbff6da0ac69118 100644 (file)
@@ -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;
index 903ecee8b08c232cd53c864a7576cd0723ea2c37..6542579c056c24374b3115242eda497f646a136d 100644 (file)
@@ -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;
index baef86c8345d78119c070cb626f68462929d58db..e7cd77a414da579a6ea59da9d44a836eb4fc42dd 100644 (file)
@@ -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;
index d5821b926d241632593d6d14b4bfa7beac76b3ae..f519d5a7a8e364e8d64eccb0c79f1576cd6e0052 100644 (file)
@@ -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:
index 0f19d2779995056ae3c21f7e065df265a1f33faa..5bafb73c9ca793f481bf95d7b62c97234b39ac04 100644 (file)
@@ -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;