1. Enhanced syntax for mount(8). The -o option now supports two 'meta'

options:

    -o fstab	brings in filesystem options specified in /etc/fstab
    -o current	incorporates the current set of options for the file
		system

   The rightmost option wins in the case of conflicting options being
   specified.

   E.g.:-

   # mount -u -o current,nosuid /home

   will preserve the current mount options while adding the 'nosuid' flag.

2. Rewording of manual page to be hopefully clearer; small -Wall
   cleanups.

Thanks to David Malone for his patience and willingness to work
multiple patches on request.

PR:		bin/6399
Submitted by:	David Malone <dwmalone@maths.tcd.ie>
This commit is contained in:
Joseph Koshy 1999-05-07 05:22:08 +00:00
parent 36cfb417de
commit 18af604492
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46619
4 changed files with 310 additions and 78 deletions

View file

@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)mount.8 8.8 (Berkeley) 6/16/94
.\" $Id: mount.8,v 1.24 1998/10/16 00:06:56 des Exp $
.\" $Id: mount.8,v 1.25 1999/04/08 13:59:42 ghelmer Exp $
.\"
.Dd June 16, 1994
.Dt MOUNT 8
@ -101,6 +101,8 @@ caution).
Options are specified with a
.Fl o
flag followed by a comma separated string of options.
In case of conflicting options being specified, the rightmost option
takes effect.
The following options are available:
.Bl -tag -width indent
.It async
@ -112,12 +114,23 @@ This is a
flag to set,
and should not be used unless you are prepared to recreate the file
system should your system crash.
.It current
When used with the
.Fl u
flag, this is the same as specifying the options currently in effect for
the mounted filesystem.
.It force
The same as
.Fl f ;
forces the revocation of write access when trying to downgrade
a filesystem mount status from read-write to read-only. Also
forces the R/W mount of an unclean filesystem (dangerous; use with caution).
.It fstab
When used with the
.Fl u
flag, this is the same as specifying all the options listed in the
.Xr fstab 5
file for the filesystem.
.It noatime
Do not update the file access time when reading from a file. This option
is useful on filesystems where there are large numbers of files and
@ -287,13 +300,9 @@ An attempt to change from read-write to read-only will fail if any
files on the filesystem are currently open for writing unless the
.Fl f
flag is also specified.
The set of options is determined by first extracting the options
for the file system from the
.Xr fstab 5
table,
then applying any options specified by the
.Fl o
argument,
The set of options is determined by applying the options specified
in the argument to
.Fl o
and finally applying the
.Fl r
or

View file

@ -42,7 +42,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95";
#endif
static const char rcsid[] =
"$Id: mount.c,v 1.28 1998/07/06 07:12:38 charnier Exp $";
"$Id: mount.c,v 1.29 1999/03/16 22:26:51 bde Exp $";
#endif /* not lint */
#include <sys/param.h>
@ -63,6 +63,10 @@ static const char rcsid[] =
#include "extern.h"
#include "pathnames.h"
/* `meta' options */
#define MOUNT_META_OPTION_FSTAB "fstab"
#define MOUNT_META_OPTION_CURRENT "current"
int debug, fstab_style, verbose;
char *catopt __P((char *, const char *));
@ -72,11 +76,14 @@ int hasopt __P((const char *, const char *));
int ismounted __P((struct fstab *, struct statfs *, int));
int isremountable __P((const char *));
void mangle __P((char *, int *, const char **));
char *update_options __P((char *, char *, int));
int mountfs __P((const char *, const char *, const char *,
int, const char *, const char *));
void remopt __P((char *, const char *));
void prmount __P((struct statfs *));
void putfsent __P((const struct statfs *));
void usage __P((void));
char *flags2opts __P((int));
/* Map from mount options to printable formats. */
static struct opt {
@ -99,7 +106,7 @@ static struct opt {
{ MNT_NOCLUSTERW, "noclusterw" },
{ MNT_SUIDDIR, "suiddir" },
{ MNT_SOFTDEP, "soft-updates" },
{ NULL }
{ 0, NULL }
};
/*
@ -224,10 +231,15 @@ main(argc, argv)
errx(1,
"unknown special file or file system %s",
*argv);
if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL)
if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) {
mntfromname = fs->fs_spec;
else
options = update_options(options, fs->fs_mntops,
mntbuf->f_flags);
} else {
mntfromname = mntbuf->f_mntfromname;
options = update_options(options, NULL,
mntbuf->f_flags);
}
rval = mountfs(mntbuf->f_fstypename, mntfromname,
mntbuf->f_mntonname, init_flags, options, 0);
break;
@ -524,6 +536,9 @@ catopt(s0, s1)
size_t i;
char *cp;
if (s1 == NULL || *s1 == '\0')
return s0;
if (s0 && *s0) {
i = strlen(s0) + strlen(s1) + 1 + 1;
if ((cp = malloc(i)) == NULL)
@ -548,7 +563,7 @@ mangle(options, argcp, argv)
argc = *argcp;
for (s = options; (p = strsep(&s, ",")) != NULL;)
if (*p != '\0')
if (*p != '\0') {
if (*p == '-') {
argv[argc++] = p;
p = strchr(p, '=');
@ -560,10 +575,97 @@ mangle(options, argcp, argv)
argv[argc++] = "-o";
argv[argc++] = p;
}
}
*argcp = argc;
}
char *
update_options(opts, fstab, curflags)
char *opts;
char *fstab;
int curflags;
{
char *o, *p;
char *cur;
char *expopt, *newopt, *tmpopt;
if (opts == NULL)
return strdup("");
fstab = strdup(fstab);
/* remove meta options from list */
remopt(fstab, MOUNT_META_OPTION_FSTAB);
remopt(fstab, MOUNT_META_OPTION_CURRENT);
cur = flags2opts(curflags);
/*
* Expand all meta-options passed to us first.
*/
expopt = NULL;
for (p = opts; (o = strsep(&p, ",")) != NULL;) {
if (strcmp(MOUNT_META_OPTION_FSTAB, o) == 0)
expopt = catopt(expopt, fstab);
else if (strcmp(MOUNT_META_OPTION_CURRENT, o) == 0)
expopt = catopt(expopt, cur);
else
expopt = catopt(expopt, o);
}
free(fstab);
free(cur);
free(opts);
/*
* Remove previous contradictory arguments. Given option "foo" we
* remove all the "nofoo" options. Given "nofoo" we remove "nonofoo"
* and "foo" - so we can deal with possible options like "notice".
*/
newopt = NULL;
for (p = expopt; (o = strsep(&p, ",")) != NULL;) {
if ((tmpopt = malloc( strlen(o) + 2 + 1 )) == NULL)
errx(1, "malloc failed");
strcpy(tmpopt, "no");
strcat(tmpopt, o);
remopt(newopt, tmpopt);
free(tmpopt);
if (strncmp("no", o, 2) == 0)
remopt(newopt, o+2);
newopt = catopt(newopt, o);
}
free(expopt);
return newopt;
}
void
remopt(string, opt)
char *string;
const char *opt;
{
char *o, *p, *r;
if (string == NULL || *string == '\0' || opt == NULL || *opt == '\0')
return;
r = string;
for (p = string; (o = strsep(&p, ",")) != NULL;) {
if (strcmp(opt, o) != 0) {
if (*r == ',' && *o != '\0')
r++;
while ((*r++ = *o++) != '\0')
;
*--r = ',';
}
}
*r = '\0';
}
void
usage()
{
@ -580,33 +682,12 @@ putfsent(ent)
const struct statfs *ent;
{
struct fstab *fst;
char *opts;
opts = flags2opts(ent->f_flags);
printf("%s\t%s\t%s %s", ent->f_mntfromname, ent->f_mntonname,
ent->f_fstypename, (ent->f_flags & MNT_RDONLY) ? "ro" : "rw");
/* XXX should use optnames[] - put shorter names in it. */
if (ent->f_flags & MNT_SYNCHRONOUS)
printf(",sync");
if (ent->f_flags & MNT_NOEXEC)
printf(",noexec");
if (ent->f_flags & MNT_NOSUID)
printf(",nosuid");
if (ent->f_flags & MNT_NODEV)
printf(",nodev");
if (ent->f_flags & MNT_UNION)
printf(",union");
if (ent->f_flags & MNT_ASYNC)
printf(",async");
if (ent->f_flags & MNT_NOATIME)
printf(",noatime");
if (ent->f_flags & MNT_NOCLUSTERR)
printf(",noclusterr");
if (ent->f_flags & MNT_NOCLUSTERW)
printf(",noclusterw");
if (ent->f_flags & MNT_NOSYMFOLLOW)
printf (",nosymfollow");
if (ent->f_flags & MNT_SUIDDIR)
printf(",suiddir");
ent->f_fstypename, opts);
free(opts);
if ((fst = getfsspec(ent->f_mntfromname)))
printf("\t%u %u\n", fst->fs_freq, fst->fs_passno);
@ -617,3 +698,29 @@ putfsent(ent)
else
printf("\t0 0\n");
}
char *
flags2opts(flags)
int flags;
{
char *res;
res = NULL;
res = catopt(res, (flags & MNT_RDONLY) ? "ro" : "rw");
if (flags & MNT_SYNCHRONOUS) res = catopt(res, "sync");
if (flags & MNT_NOEXEC) res = catopt(res, "noexec");
if (flags & MNT_NOSUID) res = catopt(res, "nosuid");
if (flags & MNT_NODEV) res = catopt(res, "nodev");
if (flags & MNT_UNION) res = catopt(res, "union");
if (flags & MNT_ASYNC) res = catopt(res, "async");
if (flags & MNT_NOATIME) res = catopt(res, "noatime");
if (flags & MNT_NOCLUSTERR) res = catopt(res, "noclusterr");
if (flags & MNT_NOCLUSTERW) res = catopt(res, "noclusterw");
if (flags & MNT_NOSYMFOLLOW) res = catopt(res, "nosymfollow");
if (flags & MNT_SUIDDIR) res = catopt(res, "suiddir");
return res;
}

View file

@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)mount.8 8.8 (Berkeley) 6/16/94
.\" $Id: mount.8,v 1.24 1998/10/16 00:06:56 des Exp $
.\" $Id: mount.8,v 1.25 1999/04/08 13:59:42 ghelmer Exp $
.\"
.Dd June 16, 1994
.Dt MOUNT 8
@ -101,6 +101,8 @@ caution).
Options are specified with a
.Fl o
flag followed by a comma separated string of options.
In case of conflicting options being specified, the rightmost option
takes effect.
The following options are available:
.Bl -tag -width indent
.It async
@ -112,12 +114,23 @@ This is a
flag to set,
and should not be used unless you are prepared to recreate the file
system should your system crash.
.It current
When used with the
.Fl u
flag, this is the same as specifying the options currently in effect for
the mounted filesystem.
.It force
The same as
.Fl f ;
forces the revocation of write access when trying to downgrade
a filesystem mount status from read-write to read-only. Also
forces the R/W mount of an unclean filesystem (dangerous; use with caution).
.It fstab
When used with the
.Fl u
flag, this is the same as specifying all the options listed in the
.Xr fstab 5
file for the filesystem.
.It noatime
Do not update the file access time when reading from a file. This option
is useful on filesystems where there are large numbers of files and
@ -287,13 +300,9 @@ An attempt to change from read-write to read-only will fail if any
files on the filesystem are currently open for writing unless the
.Fl f
flag is also specified.
The set of options is determined by first extracting the options
for the file system from the
.Xr fstab 5
table,
then applying any options specified by the
.Fl o
argument,
The set of options is determined by applying the options specified
in the argument to
.Fl o
and finally applying the
.Fl r
or

View file

@ -42,7 +42,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95";
#endif
static const char rcsid[] =
"$Id: mount.c,v 1.28 1998/07/06 07:12:38 charnier Exp $";
"$Id: mount.c,v 1.29 1999/03/16 22:26:51 bde Exp $";
#endif /* not lint */
#include <sys/param.h>
@ -63,6 +63,10 @@ static const char rcsid[] =
#include "extern.h"
#include "pathnames.h"
/* `meta' options */
#define MOUNT_META_OPTION_FSTAB "fstab"
#define MOUNT_META_OPTION_CURRENT "current"
int debug, fstab_style, verbose;
char *catopt __P((char *, const char *));
@ -72,11 +76,14 @@ int hasopt __P((const char *, const char *));
int ismounted __P((struct fstab *, struct statfs *, int));
int isremountable __P((const char *));
void mangle __P((char *, int *, const char **));
char *update_options __P((char *, char *, int));
int mountfs __P((const char *, const char *, const char *,
int, const char *, const char *));
void remopt __P((char *, const char *));
void prmount __P((struct statfs *));
void putfsent __P((const struct statfs *));
void usage __P((void));
char *flags2opts __P((int));
/* Map from mount options to printable formats. */
static struct opt {
@ -99,7 +106,7 @@ static struct opt {
{ MNT_NOCLUSTERW, "noclusterw" },
{ MNT_SUIDDIR, "suiddir" },
{ MNT_SOFTDEP, "soft-updates" },
{ NULL }
{ 0, NULL }
};
/*
@ -224,10 +231,15 @@ main(argc, argv)
errx(1,
"unknown special file or file system %s",
*argv);
if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL)
if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) {
mntfromname = fs->fs_spec;
else
options = update_options(options, fs->fs_mntops,
mntbuf->f_flags);
} else {
mntfromname = mntbuf->f_mntfromname;
options = update_options(options, NULL,
mntbuf->f_flags);
}
rval = mountfs(mntbuf->f_fstypename, mntfromname,
mntbuf->f_mntonname, init_flags, options, 0);
break;
@ -524,6 +536,9 @@ catopt(s0, s1)
size_t i;
char *cp;
if (s1 == NULL || *s1 == '\0')
return s0;
if (s0 && *s0) {
i = strlen(s0) + strlen(s1) + 1 + 1;
if ((cp = malloc(i)) == NULL)
@ -548,7 +563,7 @@ mangle(options, argcp, argv)
argc = *argcp;
for (s = options; (p = strsep(&s, ",")) != NULL;)
if (*p != '\0')
if (*p != '\0') {
if (*p == '-') {
argv[argc++] = p;
p = strchr(p, '=');
@ -560,10 +575,97 @@ mangle(options, argcp, argv)
argv[argc++] = "-o";
argv[argc++] = p;
}
}
*argcp = argc;
}
char *
update_options(opts, fstab, curflags)
char *opts;
char *fstab;
int curflags;
{
char *o, *p;
char *cur;
char *expopt, *newopt, *tmpopt;
if (opts == NULL)
return strdup("");
fstab = strdup(fstab);
/* remove meta options from list */
remopt(fstab, MOUNT_META_OPTION_FSTAB);
remopt(fstab, MOUNT_META_OPTION_CURRENT);
cur = flags2opts(curflags);
/*
* Expand all meta-options passed to us first.
*/
expopt = NULL;
for (p = opts; (o = strsep(&p, ",")) != NULL;) {
if (strcmp(MOUNT_META_OPTION_FSTAB, o) == 0)
expopt = catopt(expopt, fstab);
else if (strcmp(MOUNT_META_OPTION_CURRENT, o) == 0)
expopt = catopt(expopt, cur);
else
expopt = catopt(expopt, o);
}
free(fstab);
free(cur);
free(opts);
/*
* Remove previous contradictory arguments. Given option "foo" we
* remove all the "nofoo" options. Given "nofoo" we remove "nonofoo"
* and "foo" - so we can deal with possible options like "notice".
*/
newopt = NULL;
for (p = expopt; (o = strsep(&p, ",")) != NULL;) {
if ((tmpopt = malloc( strlen(o) + 2 + 1 )) == NULL)
errx(1, "malloc failed");
strcpy(tmpopt, "no");
strcat(tmpopt, o);
remopt(newopt, tmpopt);
free(tmpopt);
if (strncmp("no", o, 2) == 0)
remopt(newopt, o+2);
newopt = catopt(newopt, o);
}
free(expopt);
return newopt;
}
void
remopt(string, opt)
char *string;
const char *opt;
{
char *o, *p, *r;
if (string == NULL || *string == '\0' || opt == NULL || *opt == '\0')
return;
r = string;
for (p = string; (o = strsep(&p, ",")) != NULL;) {
if (strcmp(opt, o) != 0) {
if (*r == ',' && *o != '\0')
r++;
while ((*r++ = *o++) != '\0')
;
*--r = ',';
}
}
*r = '\0';
}
void
usage()
{
@ -580,33 +682,12 @@ putfsent(ent)
const struct statfs *ent;
{
struct fstab *fst;
char *opts;
opts = flags2opts(ent->f_flags);
printf("%s\t%s\t%s %s", ent->f_mntfromname, ent->f_mntonname,
ent->f_fstypename, (ent->f_flags & MNT_RDONLY) ? "ro" : "rw");
/* XXX should use optnames[] - put shorter names in it. */
if (ent->f_flags & MNT_SYNCHRONOUS)
printf(",sync");
if (ent->f_flags & MNT_NOEXEC)
printf(",noexec");
if (ent->f_flags & MNT_NOSUID)
printf(",nosuid");
if (ent->f_flags & MNT_NODEV)
printf(",nodev");
if (ent->f_flags & MNT_UNION)
printf(",union");
if (ent->f_flags & MNT_ASYNC)
printf(",async");
if (ent->f_flags & MNT_NOATIME)
printf(",noatime");
if (ent->f_flags & MNT_NOCLUSTERR)
printf(",noclusterr");
if (ent->f_flags & MNT_NOCLUSTERW)
printf(",noclusterw");
if (ent->f_flags & MNT_NOSYMFOLLOW)
printf (",nosymfollow");
if (ent->f_flags & MNT_SUIDDIR)
printf(",suiddir");
ent->f_fstypename, opts);
free(opts);
if ((fst = getfsspec(ent->f_mntfromname)))
printf("\t%u %u\n", fst->fs_freq, fst->fs_passno);
@ -617,3 +698,29 @@ putfsent(ent)
else
printf("\t0 0\n");
}
char *
flags2opts(flags)
int flags;
{
char *res;
res = NULL;
res = catopt(res, (flags & MNT_RDONLY) ? "ro" : "rw");
if (flags & MNT_SYNCHRONOUS) res = catopt(res, "sync");
if (flags & MNT_NOEXEC) res = catopt(res, "noexec");
if (flags & MNT_NOSUID) res = catopt(res, "nosuid");
if (flags & MNT_NODEV) res = catopt(res, "nodev");
if (flags & MNT_UNION) res = catopt(res, "union");
if (flags & MNT_ASYNC) res = catopt(res, "async");
if (flags & MNT_NOATIME) res = catopt(res, "noatime");
if (flags & MNT_NOCLUSTERR) res = catopt(res, "noclusterr");
if (flags & MNT_NOCLUSTERW) res = catopt(res, "noclusterw");
if (flags & MNT_NOSYMFOLLOW) res = catopt(res, "nosymfollow");
if (flags & MNT_SUIDDIR) res = catopt(res, "suiddir");
return res;
}