Subject: bin/749: mount -a mounts things that are already mounted
To: None <gnats-admin@NetBSD.ORG>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 01/22/1995 17:50:03
>Number: 749
>Category: bin
>Synopsis: mount -a mounts things that are already mounted
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Jan 22 17:50:01 1995
>Originator: der Mouse
>Organization:
As little as I can get away with
>Release: NetBSD/sparc 1.0, present in -current as well
>Environment:
SPARC IPC, not that it matters
>Description:
mount -a will happily try to mount things that are already
mounted. This patch makes the -a flag check and not attempt to
mount things that appear to be already mounted. It also adds
-A, which behaves the way -a does now, not checking existing
mounts. It also adds -x and -X, which permit explicit
exclusions for -a to be provided.
These patches are for 1.0, but mount has changed little between
1.0 and -current (only the addition of the MNT_USER flag,
according to diffs I just did).
>How-To-Repeat:
Run mount -a and notice that it happily remounts things that
are already mounted, in cases (like NFS mounts) where this is
possible.
>Fix:
--- /sources/1.0-usr-src/./sbin/mount/mount.8 Wed Jun 8 15:02:42 1994
+++ /usr/src/./sbin/mount/mount.8 Wed Dec 14 17:45:28 1994
@@ -75,6 +75,23 @@
.Pp
The options are as follows:
.Bl -tag -width indent
+.It Fl a
+Causes
+.Nm mount
+to mount all filesystems listed in
+.Pa /etc/fstab ,
+except those which appear to be already mounted. This option is conservative;
+it is possible for it to fail to notice that a filesystem is already mounted.
+.Fl x
+or
+.Fl X
+can be used to deal with these cases.
+.It Fl A
+Like
+.Fl a
+except that
+.Nm mount
+makes no attempt to check whether filesystems are already mounted or not.
.It Fl d
Causes everything to be done except for the actual system call.
This option is useful in conjunction with the
@@ -235,6 +252,34 @@
The options specific to NFS filesystems are described in the
.Xr mount_nfs 8
manual page.
+.It Fl x Ar "mount-points"
+Exclude any filesystems mounted on the listed mount points from a
+.Fl a
+or
+.Fl A
+operation. (The argument is a comma-separated list; additionally, whitespace
+at the beginning of a pathname is ignored.) All remarks listed for
+.Fl X
+apply to each element of the list;
+.Nm mount
+behaves exactly as if multiple
+.Fl X
+options had been given, one for each element of the list.
+.It Fl X Ar "mount-point"
+Exclude any filesystems mounted on the given mount point from a
+.Fl a
+or
+.Fl A
+operation. Unlike
+.Fl x ,
+the argument is taken verbatim as a mount point; whitespace and commas have
+no special meaning. This option can be given multiple times and/or combined
+with
+.Fl x ;
+all such options accumulate a single list of excluded mount points. Note that
+the argument string must match the attempted mount point; symbolic links are
+expanded before mounting, but after checking the mount point against the
+exclusion list.
.Sh FILES
.Bl -tag -width /etc/fstab -compact
.It Pa /etc/fstab
--- /sources/1.0-usr-src/./sbin/mount/mount.c Sun Aug 28 22:38:00 1994
+++ /usr/src/./sbin/mount/mount.c Wed Dec 14 17:45:30 1994
@@ -59,6 +59,9 @@
int debug, verbose, skipvfs;
+static char **exclusions = 0;
+static int nexcl = 0;
+
int badvfsname __P((const char *, const char **));
char *catopt __P((char *, const char *));
struct statfs
@@ -71,6 +74,11 @@
int, const char *, const char *));
void prmount __P((struct statfs *));
void usage __P((void));
+int alreadymounted __P((struct fstab *));
+void set_exclude_list __P((const char *));
+void set_exclude __P((const char *));
+void set_exclude_ __P((const char *, int));
+int excluded __P((const char *));
/* From mount_ufs.c. */
int mount_ufs __P((int, char * const *));
@@ -104,17 +112,22 @@
struct statfs *mntbuf;
FILE *mountdfp;
pid_t pid;
- int all, ch, i, init_flags, mntsize, rval;
+ int all, All, ch, i, init_flags, mntsize, rval;
char *options;
all = init_flags = 0;
options = NULL;
vfslist = NULL;
vfstype = "ufs";
- while ((ch = getopt(argc, argv, "adfo:rwt:uv")) != EOF)
+ while ((ch = getopt(argc, argv, "Aadfo:rwt:uvx:X:")) != EOF)
switch (ch) {
case 'a':
all = 1;
+ All = 0;
+ break;
+ case 'A':
+ all = 1;
+ All = 1;
break;
case 'd':
debug = 1;
@@ -144,6 +157,12 @@
case 'w':
init_flags &= ~MNT_RDONLY;
break;
+ case 'x':
+ set_exclude_list(optarg);
+ break;
+ case 'X':
+ set_exclude(optarg);
+ break;
case '?':
default:
usage();
@@ -167,6 +186,10 @@
continue;
if (hasopt(fs->fs_mntops, "noauto"))
continue;
+ if (!All && alreadymounted(fs))
+ continue;
+ if (excluded(fs->fs_file))
+ continue;
if (mountfs(fs->fs_vfstype, fs->fs_spec,
fs->fs_file, init_flags, options,
fs->fs_mntops))
@@ -240,6 +263,79 @@
}
exit(rval);
+}
+
+int
+excluded(s)
+ const char *s;
+{
+ int i;
+
+ for (i=0;i<nexcl;i++) if (!strcmp(exclusions[i],s)) return(1);
+ return(0);
+}
+
+void
+set_exclude_(s,len)
+ const char *s;
+ int len;
+{
+ char *t;
+
+ t = malloc(len+1);
+ strncpy(t,s,len);
+ t[len] = '\0';
+ exclusions = realloc(exclusions,(nexcl+1)*sizeof(char *));
+ exclusions[nexcl++] = t;
+}
+
+void
+set_exclude_list(s)
+ const char *s;
+{
+ const char *t;
+ const char *t0;
+
+ t = s;
+ while (*t)
+ { while (*t && ((*t == ',') || (*t == ' '))) t ++;
+ t0 = t;
+ while (*t && (*t != ',')) t ++;
+ if (t > t0) set_exclude_(t0,t-t0);
+ }
+}
+
+void
+set_exclude(s)
+ const char *s;
+{
+ set_exclude_(s,strlen(s));
+}
+
+int
+alreadymounted(fs)
+ struct fstab *fs;
+{
+ int siz;
+ struct statfs *buf;
+ int i;
+
+ /* don't cache the result of getmntinfo because it can change from one call
+ to the next. This won't affect our results in most cases (unless a
+ filesystem is listed twice in fstab), but so what? It's cheap, and
+ mount -a isn't run often. */
+ siz = getmntinfo(&buf,MNT_NOWAIT);
+ if (siz == 0) err(1,"getmntinfo");
+ for (i=0;i<siz;i++)
+ { /* this check isn't perfect; for example, unionfs below mounts have
+ a mntfromname that doesn't match what was passed in. But it'll catch
+ the commonest cases - eg, NFS mounts - and the rest can be dealt with
+ by exclusions. */
+ if ( !strcmp(buf[i].f_mntfromname,fs->fs_spec) &&
+ !strcmp(buf[i].f_mntonname,fs->fs_file) &&
+ !strcmp(buf[i].f_fstypename,fs->fs_vfstype) ) return(1);
+ }
+ return(0);
}
int
der Mouse
mouse@collatz.mcrcim.mcgill.edu
>Audit-Trail:
>Unformatted: