[libvirt] [PATCH v4 6/8] virFDStream: Add option for delete file after it's opening

Daniel P. Berrange berrange at redhat.com
Fri May 13 09:18:21 UTC 2011


On Thu, May 12, 2011 at 06:29:13PM +0200, Michal Privoznik wrote:
> 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               |   29 ++++++++++++++++++++++-------
>  src/fdstream.h               |    6 ++++--
>  src/lxc/lxc_driver.c         |    3 ++-
>  src/qemu/qemu_driver.c       |    3 ++-
>  src/storage/storage_driver.c |    4 ++--
>  src/uml/uml_driver.c         |    3 ++-
>  src/util/iohelper.c          |   12 ++++++++++--
>  src/xen/xen_driver.c         |    3 ++-
>  8 files changed, 46 insertions(+), 17 deletions(-)
> 
> diff --git a/src/fdstream.c b/src/fdstream.c
> index d2325ae..2702ad7 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 6b395b6..a66902b 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 1aadb02..0939a1d 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 7a3556f..482f177 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 903ecee..6542579 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 baef86c..e7cd77a 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 d5821b9..f519d5a 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 0f19d27..5bafb73 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;

ACK


Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list