hi, On Wed, 28 Nov 2001, Friedrisch Muller wrote: > Mounting local filesystems: mount: invalid option -- O <Here comes > usage for mount.> this is the problem i mentioned the other day. redhat has patched mount to add a few new options. therefore, you have at least three options: 1. modify the startup script to remove the mount commands that deal with nodev 2. i think jari is going to incorporate the netdev patch into his patch. then you can repatch and rebuild mount, etc. 3. i have an untested modified redhat nodev patch which should apply cleanly after jari's patch. it is attached. just pply this patch and rebuild mount, etc. - brett
--- mount/mount.c.orig Mon Nov 26 08:27:39 2001 +++ mount/mount.c Mon Nov 26 08:42:07 2001 @@ -37,6 +37,8 @@ * 2000-05-11 Mark A. Peloquin <peloquin@us.ibm.com> * - check_special_mountprog now returns correct status * 2000-11-08 aeb: accept nonnumeric uid=, gid= options + * 2001-07-13 Michael K. Johnson <johnsonm@redhat.com> + * - implemented -a -O */ #include <unistd.h> @@ -122,10 +124,11 @@ #define MS_USERS 0x40000000 #define MS_USER 0x20000000 #define MS_OWNER 0x10000000 +#define MS_NETDEV 0x00020000 #define MS_LOOP 0x00010000 /* Options that we keep the mount system call from seeing. */ -#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_LOOP) +#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_NETDEV|MS_LOOP) /* Options that we keep from appearing in the options field in the mtab. */ #define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER) @@ -158,6 +161,7 @@ { "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */ { "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */ { "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */ + { "_netdev", 0, 0, MS_NETDEV }, /* Device accessibly only via network */ /* add new options here */ #ifdef MS_NOSUB { "sub", 0, 1, MS_NOSUB }, /* allow submounts */ @@ -1180,7 +1184,7 @@ #define DISKMAJOR(m) (((int) m) & ~0xf) static int -mount_all (char *types, char *options) { +mount_all (char *types, char *options, char *test_opts) { struct mntentchn *mc, *mc0, *mtmp; int status = 0; struct stat statbuf; @@ -1201,6 +1205,7 @@ mc0 = fstab_head(); for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) { if (matching_type (mc->m.mnt_type, types) + && matching_opts (mc->m.mnt_opts, test_opts) && !streq (mc->m.mnt_dir, "/") && !streq (mc->m.mnt_dir, "root")) { if (mounted (mc->m.mnt_fsname, mc->m.mnt_dir)) { @@ -1308,6 +1313,7 @@ { "read-write", 0, 0, 'w' }, { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, + { "test-opts", 1, 0, 'O' }, { "types", 1, 0, 't' }, { "bind", 0, 0, 128 }, { "replace", 0, 0, 129 }, @@ -1330,7 +1336,7 @@ "So far the informational part. Next the mounting.\n" "The command is `mount [-t fstype] something somewhere'.\n" "Details found in /etc/fstab may be omitted.\n" - " mount -a : mount all stuff from /etc/fstab\n" + " mount -a [-t|-O] ... : mount all stuff from /etc/fstab\n" " mount device : mount device at the known place\n" " mount directory : mount known device here\n" " mount -t type dev dir : ordinary mount command\n" @@ -1354,7 +1360,7 @@ int main (int argc, char *argv[]) { int c, result = 0, specseen; - char *options = NULL, *spec, *node; + char *options = NULL, *test_opts = NULL, *spec, *node; char *volumelabel = NULL; char *uuid = NULL; char *types = NULL; @@ -1377,7 +1383,7 @@ initproctitle(argc, argv); #endif - while ((c = getopt_long (argc, argv, "afFhlL:no:p:rsU:vVwt:", + while ((c = getopt_long (argc, argv, "afFhlL:no:O:p:rsU:vVwt:", longopts, NULL)) != EOF) { switch (c) { case 'a': /* mount everything in fstab */ @@ -1407,6 +1413,12 @@ else options = xstrdup(optarg); break; + case 'O': /* with -t: mount only if (not) opt */ + if (test_opts) + test_opts = xstrconcat3(test_opts, ",", optarg); + else + test_opts = xstrdup(optarg); + break; case 'p': /* read passphrase from given fd */ { extern int passFD_number; sscanf(optarg, "%d", &passFD_number); } break; @@ -1501,7 +1513,7 @@ switch (argc+specseen) { case 0: /* mount -a */ - result = mount_all (types, options); + result = mount_all (types, options, test_opts); if (result == 0 && verbose) error(_("nothing was mounted")); break; --- mount/sundries.c.netdev Mon Jun 11 08:18:54 2001 +++ mount/sundries.c Mon Jul 16 15:58:35 2001 @@ -185,6 +185,83 @@ return no; } +/* Returns 1 if needle found or noneedle not found in haystack + * Otherwise returns 0 + */ +static int +check_option(const char *haystack, const char *needle) { + const char *p, *r; + int len, needle_len, this_len; + int no; + + no = 0; + if (!strncmp(needle, "no", 2)) { + no = 1; + needle += 2; + } + needle_len = strlen(needle); + len = strlen(haystack); + + for (p = haystack; p < haystack+len; p++) { + r = strchr(p, ','); + if (r) { + this_len = r-p; + } else { + this_len = strlen(p); + } + if (this_len != needle_len) { + p += this_len; + continue; + } + if (strncmp(p, needle, this_len) == 0) + return !no; /* foo or nofoo was found */ + p += this_len; + } + + return no; /* foo or nofoo was not found */ +} + + +/* Returns 1 if each of the test_opts options agrees with the entire + * list of options. + * Returns 0 if any noopt is found in test_opts and opt is found in options. + * Returns 0 if any opt is found in test_opts but is not found in options. + * Unlike fs type matching, nonetdev,user and nonetdev,nouser have + * DIFFERENT meanings; each option is matched explicitly as specified. + */ +int +matching_opts (const char *options, const char *test_opts) { + const char *p, *r; + char *q; + int len, this_len; + + if (test_opts == NULL) + return 1; + + len = strlen(test_opts); + q = alloca(len+1); + if (q == NULL) + die (EX_SYSERR, _("not enough memory")); + + for (p = test_opts; p < test_opts+len; p++) { + r = strchr(p, ','); + if (r) { + this_len = r-p; + } else { + this_len = strlen(p); + } + if (!this_len) continue; /* if two ',' appear in a row */ + strncpy(q, p, this_len); + q[this_len] = '\0'; + if (!check_option(options, q)) + return 0; /* any match failure means failure */ + p += this_len; + } + + /* no match failures in list means success */ + return 1; +} + /* Make a canonical pathname from PATH. Returns a freshly malloced string. It is up the *caller* to ensure that the PATH is sensible. i.e. canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.'' --- mount/mount.8.orig Mon Nov 26 08:45:51 2001 +++ mount/mount.8 Mon Nov 26 08:52:00 2001 @@ -35,6 +35,7 @@ .\" 990111, aeb: documented /sbin/mount.smbfs .\" 990730, Yann Droneaud <lch@multimania.com>: updated page .\" 991214, Elrond <Elrond@Wunder-Nett.org>: added some docs on devpts +.\" 010714, Michael K. Johnson <johnsonm@redhat.com> added -O .\" 010725, Nikita Danilov <NikitaDanilov@Yahoo.COM>: reiserfs options .\" .TH MOUNT 8 "May 23 2001" "Linux 2.0" "Linux Programmer's Manual" @@ -43,7 +44,7 @@ .SH SYNOPSIS .BI "mount [\-lhV]" .LP -.BI "mount \-a [\-fFnrsvw] [\-t " vfstype ] +.BI "mount \-a [\-fFnrsvw] [\-t " vfstype ] [\-O " optlist ] .br .BI "mount [\-fnrsvw] [\-o " options " [,...]] " "device " | " dir" .br @@ -138,12 +139,12 @@ (i) The command .RS .br -.BI "mount \-a [-t" " type" ] +.BI "mount \-a [\-t" " type" ] [\-O " optlist ] .RE (usually given in a bootscript) causes all file systems mentioned in .I fstab -(of the proper type) to be mounted as indicated, except for those -whose line contains the +(of the proper type and/or having or not having the proper options) +to be mounted as indicated, except for those whose line contains the .B noauto keyword. Adding the .B \-F @@ -441,6 +442,67 @@ .IR ext . .RE .TP +.B \-O +Used in conjunction with +.BR \-a , +to limit the set of filesystems to which the +.B \-a +is applied. Like +.B \-t +in this regard except that it is useless except in the context of +.B \-a . +For example, the command: +.RS +.RS +.B "mount \-a \-O no_netdev" +.RE +mounts all file systems except those which have the option +.I _netdev +specified in the options field in the +.I /etc/fstab +file. + +It is different from +.B \-t +in that each option is matched exactly; a leading +.B no +at the beginning of one option does not negate the rest. That is, while +.RS +.B "mount \-a \-t nomsdos,ext" +.RE +mounts filesystems that are neither msdos nor ext (the +.B no +applies to both msdos and ext2 filesystem types), +.RS +.B "mount \-a \-O no_netdev,user" +.RE +mounts all filesystems that do +.I not +have the +.B _netdev +option and +.I do +have the +.B user +option. In order to specify +.IR "neither _netdev nor user options" , +use: +.RS +.B "mount \-a \-O no_netdev,nouser" +.RE + +The +.B \-t +and +.B \-O +options are cumulative in effect; that is, the command +.RS +.B "mount \-a \-t ext2 \-O _netdev" +.RE +mounts all ext2 filesystems with the _netdev option, not all filesystems +that are either ext2 or have the _netdev option specified. +.RE +.TP .B \-o Options are specified with a .B \-o @@ -474,6 +536,11 @@ .B exec Permit execution of binaries. .TP +.B _netdev +The filesystem resides on a device that requires network access +(used to prevent the system from attempting to mount these filesystems +until the network has been enabled on the system). +.TP .B noatime Do not update inode access times on this file system (e.g, for faster access on the news spool to speed up news servers). --- mount/fstab.5.orig Mon Nov 26 08:52:48 2001 +++ mount/fstab.5 Mon Nov 26 08:55:20 2001 @@ -38,6 +38,7 @@ .\" Wed Jul 26 00:00:00 1995: Updated some nfs stuff, joey@infodrom.north.de .\" Tue Apr 2 00:38:28 1996: added info about "noauto", "user", etc. .\" Tue Jun 15 20:02:18 1999: added LABEL and UUID +.\" Sat Jul 14 2001: Michael K. Johnson <johnsonm@redhat.com> added -O .\" .TH FSTAB 5 "15 June 1999" "Linux 2.2" "Linux Programmer's Manual" .SH NAME @@ -151,9 +152,12 @@ For documentation on all nfs-specific options have a look at .BR nfs (5). Common for all types of file system are the options ``noauto'' -(do not mount when "mount -a" is given, e.g., at boot time), ``user'' -(allow a user to mount), and ``owner'' -(allow device owner to mount). For more details, see +(do not mount when "mount -a" is given, e.g., at boot time), +``user'' (allow a user to mount), +``owner'' (allow device owner to mount), and +``_netdev'' (device requires network to be available). +The ``owner'' and ``_netdev'' options are Linux-specific. +For more details, see .BR mount (8). The fifth field, --- mount/sundries.h.orig Mon Nov 26 08:56:39 2001 +++ mount/sundries.h Mon Nov 26 08:57:03 2001 @@ -25,6 +25,7 @@ char *realpath (const char *path, char *resolved_path); void error (const char *fmt, ...); int matching_type (const char *type, const char *types); +int matching_opts (const char *options, const char *test_opts); void *xmalloc (size_t size); char *xstrdup (const char *s); char *xstrndup (const char *s, int n); --- mount/umount.c.orig Mon Nov 26 08:57:44 2001 +++ mount/umount.c Mon Nov 26 09:02:36 2001 @@ -23,6 +23,7 @@ * in mtab, try them all, with last one tried first * - Differentiate "user" and "users" key words in fstab * 001202: aeb - remove at most one line from /etc/mtab + * 010716: Michael K. Johnson <johnsonm@redhat.com>: -a -O * 010914: Jamie Strandboge - use tcp if that was used for mount * 011005: hch - add lazy umount support */ @@ -415,7 +416,7 @@ in any case it's important to umount mtab entries in reverse order to mount, e.g. /usr/spool before /usr. */ static int -umount_all (char *types) { +umount_all (char *types, char *test_opts) { struct mntentchn *mc, *hd; int errors = 0; @@ -423,7 +424,8 @@ if (!hd->prev) die (2, _("umount: cannot find list of filesystems to unmount")); for (mc = hd->prev; mc != hd; mc = mc->prev) { - if (matching_type (mc->m.mnt_type, types)) { + if (matching_type (mc->m.mnt_type, types) + && matching_opts (mc->m.mnt_opts, test_opts)) { errors |= umount_one (mc->m.mnt_fsname, mc->m.mnt_dir, mc->m.mnt_type, mc->m.mnt_opts, mc); } @@ -440,6 +442,7 @@ { "force", 0, 0, 'f' }, { "help", 0, 0, 'h' }, { "no-mtab", 0, 0, 'n' }, + { "test-opts", 1, 0, 'O' }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { "read-only", 0, 0, 'r' }, @@ -451,7 +454,7 @@ usage (FILE *fp, int n) { fprintf (fp, _("Usage: umount [-hV]\n" - " umount -a [-f] [-r] [-n] [-v] [-t vfstypes]\n" + " umount -a [-f] [-r] [-n] [-v] [-t vfstypes] [-O opts]\n" " umount [-f] [-r] [-n] [-v] special | node...\n")); exit (n); } @@ -584,7 +587,7 @@ main (int argc, char *argv[]) { int c; int all = 0; - char *types = NULL; + char *types = NULL, *test_opts = NULL; int result = 0; sanitize_env(); @@ -592,7 +595,7 @@ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((c = getopt_long (argc, argv, "adfhlnrt:vV", + while ((c = getopt_long (argc, argv, "adfhlnO:rt:vV", longopts, NULL)) != EOF) switch (c) { case 'a': /* umount everything */ @@ -614,6 +617,9 @@ case 'n': /* do not write in /etc/mtab */ ++nomtab; break; + case 'O': /* specify file system options */ + test_opts = optarg; + break; case 'r': /* remount read-only if umount fails */ ++remount; break; @@ -645,7 +651,7 @@ if (all) { if (types == NULL) types = "noproc"; - result = umount_all (types); + result = umount_all (types, test_opts); } else if (argc < 1) { usage (stderr, 2); } else while (argc--) { --- mount/umount.8.orig Mon Nov 26 09:03:24 2001 +++ mount/umount.8 Mon Nov 26 09:04:32 2001 @@ -29,7 +29,7 @@ .SH SYNOPSIS .BI "umount [\-hV]" .LP -.BI "umount -a [\-dflnrv] [\-t " vfstype ] +.BI "umount -a [\-nrv] [\-t " vfstype "] [\-O " options ] .br .BI "umount [\-dflnrv] " "dir " | " device " [...] .SH DESCRIPTION @@ -90,6 +90,15 @@ .B no to specify the file system types on which no action should be taken. .TP +.BI \-O " options" +Indicate that the actions should only be taken on file systems with +the specified options in +.IR /etc/fstab . +More than option type may be specified in a comma separated +list. Each option can be prefixed with +.B no +to specify options for which no action should be taken. +.TP .B \-f Force unmount (in case of an unreachable NFS system). (Requires kernel 2.1.116 or later.)