bin/89782: [PATCH] avoid double mounts if the mount point is a
andreas at syndrom23.de
Thu Dec 1 03:00:29 GMT 2005
>Synopsis: [PATCH] avoid double mounts if the mount point is a symlink
>Arrival-Date: Thu Dec 01 03:00:13 GMT 2005
>Originator: Andreas Kohn
>Release: FreeBSD 7.0-CURRENT i386
System: FreeBSD 7.0-CURRENT #6: Tue Nov 29 03:37:45 CET 2005
root at xentros.syndrom23.de:/usr/obj/usr/src/sys/XENTROS
My /etc/fstab contains the following line
linprocfs /compat/linux/proc linprocfs ....,
which is suggested by java/jdk15 port for instance.
mount checks if a file system is mounted before mounting it with
mount -a and others, but doesn't consider symlinks. /compat is a link to /usr/compat, and so the check in ismounted() does not detect that linprocfs is mounted, and will mount it twice if mount -a is called twice.
This could for example happen if you boot to single user, mount -a your devices and then exit single user mode to multiuser mode (somewhere in the process mount -a will be called).
Add a line to /etc/fstab that has a mountpoint that is a symlink.
Call mount /this/mountpoint multiple times, and observe that this mount is shown multiple times in mount output.
The fix here uses realpath to resolve the mountpoint from /etc/fstab
into a non-symlink path, and compares that path to struct statfs->f_mntonname. It fixes the problem for me.
Alternative approaches would be to discourage the use of symlinks for mountpoints. This would then require to rewrite all ports that use /compat/linux instead of /usr/compat/linux etc.
rodrigc@ Cc'ed, because he was working on mount recently. I do not know if this repeated mounting may be a regression.
--- mount-symlinks.diff begins here ---
RCS file: /storage/freebsd/cvs/src/sbin/mount/mount.c,v
retrieving revision 1.76
diff -u -r1.76 mount.c
--- sbin/mount/mount.c 24 Nov 2005 17:35:05 -0000 1.76
+++ sbin/mount/mount.c 30 Nov 2005 17:21:14 -0000
@@ -392,13 +392,18 @@
ismounted(struct fstab *fs, struct statfs *mntbuf, int mntsize)
+ char realfsfile[PATH_MAX];
if (fs->fs_file == '/' && fs->fs_file == '\0')
/* the root file system can always be remounted */
+ /* The user may have specified a symlink in fstab, resolve the path */
+ if (realpath(fs->fs_file, realfsfile) == NULL)
+ err(1, "%s cannot be resolved to a path", fs->fs_file);
for (i = mntsize - 1; i >= 0; --i)
- if (strcmp(fs->fs_file, mntbuf[i].f_mntonname) == 0 &&
+ if (strcmp(realfsfile, mntbuf[i].f_mntonname) == 0 &&
strcmp(fs->fs_spec, mntbuf[i].f_mntfromname) == 0))
--- mount-symlinks.diff ends here ---
More information about the freebsd-bugs