changeset 1509:22691dfb17b9 draft

Fix two mount bugs: 1) Don't skip a filesystem type when setting up loopback mount, 2) Don't stop checking filesystem types due to EBUSY, it may mean already mounted by another filesystem type you haven't tried yet.
author Rob Landley <rob@landley.net>
date Sun, 28 Sep 2014 18:22:34 -0500
parents b0ade326c855
children 4f3a5d600803
files toys/lsb/mount.c
diffstat 1 files changed, 18 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/toys/lsb/mount.c	Sun Sep 28 13:15:41 2014 -0500
+++ b/toys/lsb/mount.c	Sun Sep 28 18:22:34 2014 -0500
@@ -72,6 +72,7 @@
 // TODO what if you --bind mount a block device somewhere (file, dir, dev)
 // TODO "touch servername; mount -t cifs servername path"
 // TODO mount -o remount a user mount
+// TODO mount image.img sub (auto-loopback) then umount image.img
 
 // Strip flags out of comma separated list of options, return flags,.
 static long flag_opts(char *new, long flags, char **more)
@@ -136,6 +137,7 @@
 {
   FILE *fp = 0;
   int rc = EINVAL;
+  char *buf = 0;
 
   if (toys.optflags & FLAG_f) return;
 
@@ -167,10 +169,8 @@
     toys.exitval |= xrun((char *[]){"swapon", "--", dev, 0});
 
   for (;;) {
-    char *buf = 0;
-
     // If type wasn't specified, try all of them in order.
-    if (fp) {
+    if (fp && !buf) {
       size_t i;
 
       if (getline(&buf, &i, fp)<0) break;
@@ -178,6 +178,8 @@
       // skip nodev devices
       if (!isspace(*type)) {
         free(buf);
+        buf = 0;
+
         continue;
       }
       // trim whitespace
@@ -193,9 +195,6 @@
       fprintf(stderr, "'%s' is read-only", dev);
       flags |= MS_RDONLY;
     }
-    free(buf);
-
-    if (!rc) break;
 
     // Trying to autodetect loop mounts like bind mounts above (file on dir)
     // isn't good enough because "mount -t ext2 fs.img dir" is valid, but if
@@ -209,9 +208,7 @@
     // Solution: try the mount, let the kernel tell us it wanted a block
     // device, then do the loopback setup and retry the mount.
 
-    if (fp && errno == EINVAL) continue;
-
-    if (errno == ENOTBLK) {
+    if (rc && errno == ENOTBLK) {
       char *losetup[] = {"losetup", "-fs", dev, 0};
       int pipe, len;
       pid_t pid;
@@ -226,8 +223,18 @@
         dev = toybuf;
 
         continue;
-      } else error_msg("losetup failed %d", rc);
-    } else perror_msg("'%s'->'%s'", dev, dir);
+      }
+      error_msg("losetup failed %d", rc);
+
+      break;
+    }
+
+    free(buf);
+    buf = 0;
+    if (!rc) break;
+    if (fp && (errno == EINVAL || errno == EBUSY)) continue;
+
+    perror_msg("'%s'->'%s'", dev, dir);
 
     break;
   }