[Libguestfs] [PATCH 06/12] mount: Add mount_vfs_internal and umount_internal

Matthew Booth mbooth at redhat.com
Thu Feb 7 15:57:52 UTC 2013


These 2 internal functions allow mounting and unmounting of mountables
outside /sysroot.
---
 daemon/daemon.h |   8 +++++
 daemon/mount.c  | 103 +++++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/daemon/daemon.h b/daemon/daemon.h
index a94c338..78591a0 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -65,6 +65,14 @@ extern int xread (int sock, void *buf, size_t len)
 
 extern char *mountable_to_string (const mountable_t *mountable);
 
+/*-- in mount.c --*/
+
+extern int mount_vfs_internal (const char *options, const char *vfstype,
+                               const mountable_t *mountable,
+                               const char *mp, const char *user_mp, char **err);
+extern int umount_internal (const char *pathordevice,
+                            int force, int lazyunmount, char **err);
+
 /* Growable strings buffer. */
 struct stringsbuf {
   char **argv;
diff --git a/daemon/mount.c b/daemon/mount.c
index 484e45c..34510bd 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -126,31 +126,44 @@ int
 do_mount_vfs (const char *options, const char *vfstype,
               const mountable_t *mountable, const char *mountpoint)
 {
-  int r;
-  CLEANUP_FREE char *mp = NULL;
-  CLEANUP_FREE char *error = NULL;
-  struct stat statbuf;
-
   ABS_PATH (mountpoint, , return -1);
 
-  mp = sysroot_path (mountpoint);
+  CLEANUP_FREE char *mp = sysroot_path (mountpoint);
   if (!mp) {
     reply_with_perror ("malloc");
     return -1;
   }
 
   /* Check the mountpoint exists and is a directory. */
+  struct stat statbuf;
   if (stat (mp, &statbuf) == -1) {
     reply_with_perror ("mount: %s", mountpoint);
     return -1;
   }
+
   if (!S_ISDIR (statbuf.st_mode)) {
     reply_with_perror ("mount: %s: mount point is not a directory", mountpoint);
     return -1;
   }
 
+  CLEANUP_FREE char *err = NULL;
+  int r = mount_vfs_internal (options, vfstype, mountable,
+                              mp, mountpoint, &err);
+
+  if (r == -1) {
+    reply_with_error ("%s", err ? err : "malloc");
+  }
+
+  return r;
+}
+
+int
+mount_vfs_internal (const char *options, const char *vfstype,
+                    const mountable_t *mountable,
+                    const char *mp, const char *user_mp,
+                    char **err)
+{
   CLEANUP_FREE char *options_plus = NULL;
-  const char *device = mountable->device;
   switch (mountable->type) {
     case MOUNTABLE_DEVICE:
       break;
@@ -160,24 +173,34 @@ do_mount_vfs (const char *options, const char *vfstype,
         if (asprintf (&options_plus, "subvol=%s,%s",
                       mountable->volume, options) == -1)
         {
-          reply_with_perror ("asprintf");
+          /* No point trying to allocate more memory for an error message */
+          fprintf (stderr, "asprintf: %m\n");
           return -1;
         }
       }
       
       else {
         if (asprintf (&options_plus, "subvol=%s", mountable->volume) == -1) {
-          reply_with_perror ("asprintf");
+          /* No point trying to allocate more memory for an error message */
+          fprintf (stderr, "asprintf: %m\n");
           return -1;
         }
       }
       break;
 
     default:
-      reply_with_error ("Invalid mountable type: %i", mountable->type);
+      if (asprintf (err, "Invalid mountable type: %i", mountable->type) == -1)
+      {
+          /* No point trying to allocate more memory for an error message */
+          fprintf (stderr, "Invalid mountable type: %i", mountable->type);
+          fprintf (stderr, "asprintf: %m\n");
+      }
       return -1;
   }
 
+  CLEANUP_FREE char *error = NULL;
+  const char *device = mountable->device;
+  int r;
   if (vfstype)
     r = command (NULL, &error,
                  str_mount, "-o", options_plus ? options_plus : options,
@@ -186,9 +209,17 @@ do_mount_vfs (const char *options, const char *vfstype,
     r = command (NULL, &error,
                  str_mount, "-o", options_plus ? options_plus : options,
                  device, mp, NULL);
+
   if (r == -1) {
-    reply_with_error ("%s on %s (options: '%s'): %s",
-                      device, mountpoint, options, error);
+    if (asprintf (err, "%s on %s (options: '%s'): %s",
+                  device, user_mp, options_plus ? options_plus : options,
+                  error) == -1)
+    {
+        /* No point trying to allocate more memory for an error message */
+        fprintf (stderr, "%s on %s (options: '%s'): %s",
+                 device, user_mp, options_plus ? options_plus : options, error);
+        fprintf (stderr, "asprintf: %m\n");
+    }
     return -1;
   }
 
@@ -216,28 +247,35 @@ do_mount_options (const char *options, const mountable_t *mountable,
 
 /* Takes optional arguments, consult optargs_bitmask. */
 int
-do_umount (const char *pathordevice,
-           int force, int lazyunmount)
+do_umount (const char *pathordevice, int force, int lazyunmount)
 {
-  int r;
-  CLEANUP_FREE char *err = NULL;
-  CLEANUP_FREE char *buf = NULL;
-  int is_dev;
-  const char *argv[MAX_ARGS];
-  size_t i = 0;
+  CLEANUP_FREE char *buf = STREQLEN (pathordevice, "/dev/", 5) ?
+    strdup (pathordevice) : sysroot_path (pathordevice);
 
-  is_dev = STREQLEN (pathordevice, "/dev/", 5);
-  buf = is_dev ? strdup (pathordevice)
-               : sysroot_path (pathordevice);
   if (buf == NULL) {
     reply_with_perror ("malloc");
     return -1;
   }
 
-  if (!(optargs_bitmask & GUESTFS_UMOUNT_FORCE_BITMASK))
-    force = 0;
-  if (!(optargs_bitmask & GUESTFS_UMOUNT_LAZYUNMOUNT_BITMASK))
-    lazyunmount = 0;
+  if (!(optargs_bitmask & GUESTFS_UMOUNT_FORCE_BITMASK)) force = 0;
+  if (!(optargs_bitmask & GUESTFS_UMOUNT_LAZYUNMOUNT_BITMASK)) lazyunmount = 0;
+
+  CLEANUP_FREE char *err = NULL;
+  int r = umount_internal (buf, force, lazyunmount, &err);
+
+  if (r == -1) {
+    reply_with_error ("%s", err ? err : "malloc");
+  }
+
+  return r;
+}
+
+int
+umount_internal (const char *pathordevice, int force, int lazyunmount,
+                 char **err)
+{
+  const char *argv[MAX_ARGS];
+  size_t i = 0;
 
   /* Use the external /bin/umount program, so that /etc/mtab is kept
    * updated.
@@ -249,13 +287,18 @@ do_umount (const char *pathordevice,
   if (lazyunmount)
     ADD_ARG (argv, i, "-l");
 
-  ADD_ARG (argv, i, buf);
+  ADD_ARG (argv, i, pathordevice);
   ADD_ARG (argv, i, NULL);
 
-  r = commandv (NULL, &err, argv);
+  CLEANUP_FREE char *errout = NULL;
+  int r = commandv (NULL, &errout, argv);
 
   if (r == -1) {
-    reply_with_error ("%s: %s", pathordevice, err);
+    if (asprintf (err, "%s: %s", pathordevice, errout) == -1) {
+        /* No point trying to allocate more memory for an error message */
+        fprintf (stderr, "%s: %s\n", pathordevice, errout);
+        fprintf (stderr, "asprintf: %m\n");
+    }
     return -1;
   }
 
-- 
1.8.1




More information about the Libguestfs mailing list