[PATCH] mount: remount doesn't care about loop=

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The command

   # mount -oremount <spec> <dir>

doesn't read fstab or mtab. This is expected behaviour. Unfortunately,
we have to care about the internal loop= option which is generated and
maintained by mount(8)/umount(8). The loop= option has to be persistent.

How to reproduce this bug:

 # mount -o loop       /home/images/vfat.img /mnt/img; grep vfat /etc/mtab; \
   mount -o remount,ro /home/images/vfat.img /mnt/img; grep vfat /etc/mtab;

 /home/images/vfat.img /mnt/img vfat rw,loop=/dev/loop0 0 0
 /home/images/vfat.img /mnt/img vfat ro 0 0

Reported-By: David Chinner <dgc@xxxxxxx>
Signed-off-by: Karel Zak <kzak@xxxxxxxxxx>
---
 mount/fstab.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 mount/mount.8 |   21 ++++++++++++++
 2 files changed, 104 insertions(+), 1 deletions(-)

diff --git a/mount/fstab.c b/mount/fstab.c
index 108010f..ae860da 100644
--- a/mount/fstab.c
+++ b/mount/fstab.c
@@ -669,6 +669,86 @@ lock_mtab (void) {
 	}
 }
 
+static char *
+get_option(const char *optname, const char *src, size_t *len)
+{
+	char *opt, *end;
+	size_t sz;
+
+	if (!src)
+		return NULL;
+
+	opt = strstr(src, optname);
+	if (!opt)
+		return NULL;
+
+	end = strchr(opt, ',');
+	sz = end ? end - opt : strlen(opt);
+
+	if (len)
+		*len = sz;
+
+	if ((opt == src || *(opt - 1) == ',') &&
+	    (*(opt + sz) == '\0' || *(opt + sz) == ','))
+		return opt;
+
+	return NULL;
+}
+
+static int
+cpy_option(const char *optname, char *dest, const char *src)
+{
+	char *opt;
+	size_t sz;
+
+	opt = get_option(optname, src, &sz);
+	if (!opt)
+		/* the option doesn't exist */
+		return 0;
+
+	if (get_option(optname, dest, NULL))
+		/* the options is already in dest */
+		return 0;
+
+	if (*dest) {
+		dest = dest + strlen(dest);
+		*dest++ = ',';		/* separator */
+	}
+	memcpy(dest, opt, sz);	/* copy option */
+	*(dest + sz) = '\0';	/* terminator */
+
+	return 1;
+}
+
+/* Generates (and allocates) new options for remount
+ *
+ * We cannot blindly replace the old options, otherwise we will lost some
+ * internally generated stuff (e.g loop=).
+ */
+static char *
+mk_remount_opts(const char *old, const char *instead)
+{
+	char *new;
+	size_t sz;
+
+	if (old == NULL && instead == NULL)
+		return NULL;
+	if (!old)
+		return xstrdup(instead);
+
+	/* max size of new options is:
+	 * old + new + '\0' + separator (for each copied option)
+	 */
+	sz = strlen(old) + (instead ? strlen(instead) : 0) + 2;
+	new = xmalloc(sz);
+	if (instead)
+		strncpy(new, instead, sz);
+
+	cpy_option("loop=", new, old);
+
+	return new;
+}
+
 /*
  * Update the mtab.
  *  Used by umount with null INSTEAD: remove the last DIR entry.
@@ -721,8 +801,10 @@ update_mtab (const char *dir, struct my_mntent *instead) {
 			}
 		} else if (!strcmp(mc->m.mnt_dir, instead->mnt_dir)) {
 			/* A remount */
+			char *opts = mk_remount_opts(mc->m.mnt_opts,
+					instead->mnt_opts);
 			my_free(mc->m.mnt_opts);
-			mc->m.mnt_opts = xstrdup(instead->mnt_opts);
+			mc->m.mnt_opts = opts;
 		} else {
 			/* A move */
 			my_free(mc->m.mnt_dir);
diff --git a/mount/mount.8 b/mount/mount.8
index bb6b3f1..42d3e55 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -679,6 +679,27 @@ This option implies the options
 Attempt to remount an already-mounted file system.  This is commonly
 used to change the mount flags for a file system, especially to make a
 readonly file system writeable. It does not change device or mount point.
+
+The remount functionality follows the standard way how the mount command works
+with options from fstab. It means the mount command doesn't read fstab (or
+mtab) only when a
+.IR device
+and
+.IR dir
+are fully specified.
+
+.BR "mount -o remount,rw /dev/foo /dir"
+
+After this call all old mount options are replaced and arbitrary stuff from
+fstab is ignored, except the loop= option which is internally generated and
+maintained by the mount command.
+
+.BR "mount -o remount,rw  /dir"
+
+After this call mount reads fstab (or mtab) and merges these options with
+options from command line (
+.B -o
+).
 .TP
 .B ro
 Mount the file system read-only.
-- 
1.5.4.1

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux