[Libguestfs] [PATCH 09/10] fuse: Use command mini-library to run the fusermount command.

Richard W.M. Jones rjones at redhat.com
Thu Oct 18 21:14:10 UTC 2012


From: "Richard W.M. Jones" <rjones at redhat.com>

---
 src/fuse.c | 89 ++++++++++++++++++++------------------------------------------
 1 file changed, 28 insertions(+), 61 deletions(-)

diff --git a/src/fuse.c b/src/fuse.c
index 7342e5c..76d008a 100644
--- a/src/fuse.c
+++ b/src/fuse.c
@@ -1044,17 +1044,19 @@ guestfs___free_fuse (guestfs_h *g)
   free_dir_caches (g);
 }
 
-static int do_fusermount (guestfs_h *g, const char *localmountpoint, int error_fd);
-
 int
 guestfs__umount_local (guestfs_h *g,
                        const struct guestfs_umount_local_argv *optargs)
 {
+  int ret = -1;
   size_t i, tries;
   char *localmountpoint;
   char *fusermount_log = NULL;
-  int error_fd = -1;
-  int ret = -1;
+  struct command *cmd = NULL;
+  int r;
+  FILE *fp;
+  char error_message[4096];
+  size_t n;
 
   /* How many times should we try the fusermount command? */
   if (optargs->bitmask & GUESTFS_UMOUNT_LOCAL_RETRY_BITMASK)
@@ -1081,22 +1083,22 @@ guestfs__umount_local (guestfs_h *g,
    * all 'tries' have failed do we print the contents of this file.  A
    * temporary failure when retry == true will not cause any error.
    */
-  fusermount_log = safe_asprintf (g, "%s/fusermount.log", g->tmpdir);
-  error_fd = open (fusermount_log,
-                   O_RDWR|O_CREAT|O_TRUNC|O_NOCTTY /* not O_CLOEXEC */,
-                   0600);
-  if (error_fd == -1) {
-    perrorf (g, _("open: %s"), fusermount_log);
-    goto out;
-  }
+  fusermount_log = safe_asprintf (g, "%s/fusermount%d", g->tmpdir, ++g->unique);
 
   for (i = 0; i < tries; ++i) {
-    int r;
-
-    r = do_fusermount (g, localmountpoint, error_fd);
+    cmd = guestfs___new_command (g);
+    guestfs___cmd_add_string_unquoted (cmd, "fusermount -u ");
+    guestfs___cmd_add_string_quoted   (cmd, localmountpoint);
+    guestfs___cmd_add_string_unquoted (cmd, " > ");
+    guestfs___cmd_add_string_quoted   (cmd, fusermount_log);
+    guestfs___cmd_add_string_unquoted (cmd, " 2>&1");
+    guestfs___cmd_clear_capture_errors (cmd);
+    r = guestfs___cmd_run (cmd);
+    guestfs___cmd_close (cmd);
+    cmd = NULL;
     if (r == -1)
       goto out;
-    if (r) {
+    if (WIFEXITED (r) && WEXITSTATUS (r) == EXIT_SUCCESS) {
       /* External fusermount succeeded.  Note that the original thread
        * is responsible for setting g->localmountpoint to NULL.
        */
@@ -1108,26 +1110,25 @@ guestfs__umount_local (guestfs_h *g,
   }
 
   if (ret == -1) {              /* fusermount failed */
-    char error_message[4096];
-    ssize_t n;
-
     /* Get the error message from the log file. */
-    if (lseek (error_fd, 0, SEEK_SET) >= 0 &&
-        (n = read (error_fd, error_message, sizeof error_message - 1)) > 0) {
+    fp = fopen (fusermount_log, "r");
+    if (fp != NULL) {
+      n = fread (error_message, 1, sizeof error_message, fp);
       while (n > 0 && error_message[n-1] == '\n')
         n--;
       error_message[n] = '\0';
+      fclose (fp);
+      error (g, _("fusermount failed: %s: %s"), localmountpoint, error_message);
     } else {
-      snprintf (error_message, sizeof error_message,
-                "(fusermount error could not be preserved)");
+      perrorf (g,
+               _("fusermount failed: %s: "
+                 "original error could not be preserved"), localmountpoint);
     }
-
-    error (g, _("fusermount failed: %s: %s"), localmountpoint, error_message);
-    goto out;
   }
 
  out:
-  if (error_fd >= 0) close (error_fd);
+  if (cmd)
+    guestfs___cmd_close (cmd);
   if (fusermount_log) {
     unlink (fusermount_log);
     free (fusermount_log);
@@ -1136,40 +1137,6 @@ guestfs__umount_local (guestfs_h *g,
   return ret;
 }
 
-static int
-do_fusermount (guestfs_h *g, const char *localmountpoint, int error_fd)
-{
-  pid_t pid;
-  int status;
-
-  pid = fork ();
-  if (pid == -1) {
-    perrorf (g, "fork");
-    return -1;
-  }
-
-  if (pid == 0) {               /* child */
-    /* Ensure stdout and stderr point to the error_fd. */
-    dup2 (error_fd, STDOUT_FILENO);
-    dup2 (error_fd, STDERR_FILENO);
-    close (error_fd);
-    execlp ("fusermount", "fusermount", "-u", localmountpoint, NULL);
-    perror ("exec: fusermount");
-    _exit (EXIT_FAILURE);
-  }
-
-  /* Parent. */
-  if (waitpid (pid, &status, 0) == -1) {
-    perrorf (g, "waitpid");
-    return -1;
-  }
-
-  if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
-    return 0;                   /* it failed to unmount the mountpoint */
-
-  return 1;                     /* unmount was successful */
-}
-
 /* Functions handling the directory cache.
  *
  * Note on attribute caching: FUSE can cache filesystem attributes for
-- 
1.7.11.4




More information about the Libguestfs mailing list