Subject: bin/4261: mount -a fails to skip existing mounts in some cases
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Drochner <drochner@zelz26.zel.kfa-juelich.de>
List: netbsd-bugs
Date: 10/11/1997 16:25:06
>Number: 4261
>Category: bin
>Synopsis: mount -a fails to skip existing mounts in some cases
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Oct 11 07:35:04 1997
>Last-Modified:
>Originator: Matthias Drochner
>Organization:
KFA Juelich
>Release: NetBSD/current, Oct 10 1997
>Environment:
NetBSD/current, Oct 10 1997
System: NetBSD zelz26 1.2G NetBSD 1.2G (GENERIC.KGDB) #132: Fri Oct 10 18:31:12 MEST 1997 drochner@zelz26:/mnt/sys/arch/i386/compile/GENERIC.KGDB i386
>Description:
In setups with union mounts, the code which determines if a given mount
lready exists may fail.
The code uses a statfs() on the mountpoint, for which of the 2 mounts
the information is returned is undefined.
In my setup it looks as follows:
/etc/fstab:
[...]
zelnfs:/netbsd/src /usr/src nfs ro 0 0
[...]
/altroot/src /usr/src union rw
[...]
mount -av recognizes all but these 2 filesystems as mounted
It shows up that fsstat() returned information for the union mount when
the nfs mount was checked and vice-versa.
fsstat() returns the information for the last mounted filesystem, thus
it cannot be used at this place.
>How-To-Repeat:
See above.
>Fix:
One possibility (using getmntinfo() instead):
*** mount.c.orig Sat Oct 11 15:58:49 1997
--- mount.c Sat Oct 11 15:58:25 1997
***************
*** 300,306 ****
};
const char *argv[100], **edir;
! struct statfs sf;
pid_t pid;
! int argc, i, status;
char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN];
#ifdef __GNUC__
--- 300,306 ----
};
const char *argv[100], **edir;
! struct statfs *sfp, sf;
pid_t pid;
! int argc, numfs, i, status;
char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN];
#ifdef __GNUC__
***************
*** 332,348 ****
flags |= MNT_UPDATE;
else if (skipmounted) {
! if (statfs(name, &sf) < 0) {
! warn("statfs %s", name);
return (1);
}
! /* XXX can't check f_mntfromname, thanks to mfs, union, etc. */
! if (strncmp(name, sf.f_mntonname, MNAMELEN) == 0 &&
! strncmp(vfstype, sf.f_fstypename, MFSNAMELEN) == 0) {
! if (verbose)
! (void)printf("%s on %s type %.*s: %s\n",
! sf.f_mntfromname, sf.f_mntonname,
! MFSNAMELEN, sf.f_fstypename,
! "already mounted");
! return (0);
}
}
--- 332,350 ----
flags |= MNT_UPDATE;
else if (skipmounted) {
! if ((numfs = getmntinfo(&sfp, MNT_WAIT)) == 0) {
! warn("getmntinfo");
return (1);
}
! for(i = 0; i < numfs; i++) {
! /* XXX can't check f_mntfromname, thanks to mfs, union, etc. */
! if (strncmp(name, sfp[i].f_mntonname, MNAMELEN) == 0 &&
! strncmp(vfstype, sfp[i].f_fstypename, MFSNAMELEN) == 0) {
! if (verbose)
! (void)printf("%s on %s type %.*s: %s\n",
! sfp[i].f_mntfromname, sfp[i].f_mntonname,
! MFSNAMELEN, sfp[i].f_fstypename,
! "already mounted");
! return (0);
! }
}
}
>Audit-Trail:
>Unformatted: