[Libguestfs] [PATCH 1/2] fuse: Add guestmount --fd option (RHBZ#1100498).

Richard W.M. Jones rjones at redhat.com
Fri May 23 10:52:38 UTC 2014


This implements the guestmount --fd option to allow you to run
guestmount captive under another process (typically using
`guestmount --fd=<FD> --no-fork').

See: https://bugzilla.redhat.com/show_bug.cgi?id=1100498
---
 fuse/guestmount.c   | 37 ++++++++++++++++++++++++++++++++++++-
 fuse/guestmount.pod |  7 +++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/fuse/guestmount.c b/fuse/guestmount.c
index 4f98471..88c6024 100644
--- a/fuse/guestmount.c
+++ b/fuse/guestmount.c
@@ -41,6 +41,7 @@
 
 #include "options.h"
 
+static int write_pipe_fd (int fd);
 static int write_pid_file (const char *pid_file, pid_t pid);
 
 #ifndef HAVE_FUSE_OPT_ADD_OPT_ESCAPED
@@ -111,6 +112,7 @@ usage (int status)
              "  --dir-cache-timeout  Set readdir cache timeout (default 5 sec)\n"
              "  -d|--domain guest    Add disks from libvirt guest\n"
              "  --echo-keys          Don't turn off echo for passphrases\n"
+             "  --fd=FD              Write to pipe FD when mountpoint is ready\n"
              "  --format[=raw|..]    Force disk format for -a option\n"
              "  --fuse-help          Display extra FUSE options\n"
              "  -i|--inspector       Automatically mount filesystems\n"
@@ -155,6 +157,7 @@ main (int argc, char *argv[])
     { "dir-cache-timeout", 1, 0, 0 },
     { "domain", 1, 0, 'd' },
     { "echo-keys", 0, 0, 0 },
+    { "fd", 1, 0, 0 },
     { "format", 2, 0, 0 },
     { "fuse-help", 0, 0, 0 },
     { "help", 0, 0, HELP_OPTION },
@@ -190,6 +193,7 @@ main (int argc, char *argv[])
   int do_fork = 1;
   char *fuse_options = NULL;
   char *pid_file = NULL;
+  int pipe_fd = -1;
 
   struct guestfs_mount_local_argv optargs;
 
@@ -237,6 +241,12 @@ main (int argc, char *argv[])
         pid_file = optarg;
       } else if (STREQ (long_options[option_index].name, "no-fork")) {
         do_fork = 0;
+      } else if (STREQ (long_options[option_index].name, "fd")) {
+        if (sscanf (optarg, "%d", &pipe_fd) != 1 || pipe_fd < 0) {
+          fprintf (stderr, _("%s: unable to parse --fd option value: %s\n"),
+                   program_name, optarg);
+          exit (EXIT_FAILURE);
+        }
       } else {
         fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                  program_name, long_options[option_index].name, option_index);
@@ -413,6 +423,8 @@ main (int argc, char *argv[])
     if (pid != 0) {             /* parent */
       if (write_pid_file (pid_file, pid) == -1)
         _exit (EXIT_FAILURE);
+      if (write_pipe_fd (pipe_fd) == -1)
+        _exit (EXIT_FAILURE);
 
       _exit (EXIT_SUCCESS);
     }
@@ -435,9 +447,11 @@ main (int argc, char *argv[])
     }
   }
   else {
-    /* not forking, write PID file anyway */
+    /* not forking, write PID file and pipe FD anyway */
     if (write_pid_file (pid_file, getpid ()) == -1)
       exit (EXIT_FAILURE);
+    if (write_pipe_fd (pipe_fd) == -1)
+      _exit (EXIT_FAILURE);
   }
 
   /* At the last minute, remove the libguestfs error handler.  In code
@@ -487,3 +501,24 @@ write_pid_file (const char *pid_file, pid_t pid)
 
   return 0;
 }
+
+static int
+write_pipe_fd (int fd)
+{
+  char c = 0;
+
+  if (fd < 0)
+    return 0;
+
+  if (write (fd, &c, 1) != 1) {
+    perror ("write (--fd option)");
+    return -1;
+  }
+
+  if (close (fd) == -1) {
+    perror ("close (--fd option)");
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod
index 05a3c1d..7eddc1c 100644
--- a/fuse/guestmount.pod
+++ b/fuse/guestmount.pod
@@ -212,6 +212,13 @@ echoing off so you cannot see what you are typing.  If you are not
 worried about Tempest attacks and there is no one else in the room
 you can specify this flag to see what you are typing.
 
+=item B<--fd=FD>
+
+Specify a pipe or eventfd file descriptor.  When the mountpoint is
+ready to be used, guestmount writes a single byte to this file
+descriptor.  This can be used in conjunction with I<--no-fork> in
+order to run guestmount captive under another process.
+
 =item B<--format=raw|qcow2|..>
 
 =item B<--format>
-- 
1.9.0




More information about the Libguestfs mailing list