Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Apr 98 23:01:13 +0100 (BST)
From:      dwmalone@maths.tcd.ie
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   bin/6399: Mount doesn't behave as described in the man page.
Message-ID:  <9804232301.aa28604@walton.maths.tcd.ie>

next in thread | raw e-mail | index | archive | help

>Number:         6399
>Category:       bin
>Synopsis:       When using "-u" mount doesn't start from the fstab options.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 23 15:10:01 PDT 1998
>Last-Modified:
>Originator:     David Malone
>Organization:
School of Maths, Trinity College, Dublin.
>Release:        FreeBSD 2.2.6-STABLE i386
>Environment:

	2.2-STABLE or 3.0-CURRENT

>Description:

	Because there is no syntax for adding or removing mount options
	mount -u begins from no options rather than those listed in fstab.
	This isn't what the man page says.

	Also the man page claims that saying "-o update" is the same as
	-u, which doesn't seem to be the case. Saying "-o update" does
	actually start with the options in fstab.

>How-To-Repeat:

	Experimenting with mount -d with demo the problem.

>Fix:
	
	I've included a patch which changes "mount -u".  It only changes
	the effect when conflicting options are given. In this case the
	rightmost option wins out. For example:

		mount -u -o sync,noatime,nosync

	is equivelent to:

		mount -u -o noatime,nosync

	Previously I think the default option won out. It also adds two
	new options "-o fstab" and "-o cur". The first is equivelent to
	giving all the options in fstab and the second is equivelent to
	the options currently in effect (as listed by mount -p).

	These options allow you to do things like:

		mount -u -o fstab,noatime /usr
		checksum stuff
		mount -u -o fstab /usr

	The mount source code is in a bit of a mess as it takes its
	option names from about 3 different places, however I didn't
	think it was my place to fix this ;-)

	My man page patch doesn't mention that mount -u is actually
	different from mount -o update, 'cos I'm not sure which is
	"correct". The patch is for 2.2, if people want similar code
	for current I can cook some up.


diff -cwr /usr/src/sbin/mount/mount.8 ./mount.8
*** /usr/src/sbin/mount/mount.8	Thu Dec  4 23:04:38 1997
--- ./mount.8	Sat Apr 18 22:03:55 1998
***************
*** 108,119 ****
--- 108,132 ----
  flag to set,
  and should not be used unless you are prepared to recreate the file
  system should your system crash.
+ .It cur
+ When using the
+ .Fl u
+ flag this is the same as giving the options currently in effect. To
+ see what these options are you can use the
+ .Fl p
+ flag.
  .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 using the
+ .Fl u
+ this is the same as giving 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
***************
*** 253,263 ****
  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
! table,
! then applying any options specified by the
  .Fl o
  argument,
  and finally applying the
--- 266,273 ----
  files on the filesystem are currently open for writing unless the
  .Fl f
  flag is also specified.
! The set of options is determined by
! applying any options specified by the
  .Fl o
  argument,
  and finally applying the
diff -cwr /usr/src/sbin/mount/mount.c ./mount.c
*** /usr/src/sbin/mount/mount.c	Thu Mar  5 00:59:24 1998
--- ./mount.c	Thu Apr 23 22:30:47 1998
***************
*** 71,81 ****
--- 71,84 ----
  const char
        **makevfslist __P((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((const char *, const char *, int));
  void	usage __P((void));
  void	putfsent __P((const struct statfs *));
+ char   *flags2opts __P((int));
  
  /* From mount_ufs.c. */
  int	mount_ufs __P((int, char * const *));
***************
*** 215,220 ****
--- 218,224 ----
  				errx(1, "can't find fstab entry for %s.",
  				    *argv);
  			/* If it's an update, ignore the fstab file options. */
+ 			options = update_options(options,fs->fs_mntops,mntbuf->f_flags);
  			fs->fs_mntops = NULL;
  			mntonname = mntbuf->f_mntonname;
  		} else {
***************
*** 547,552 ****
--- 551,625 ----
  	*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("");
+ 
+ 	remopt(fstab,"fstab");
+ 	remopt(fstab,"cur");
+ 	cur = flags2opts(curflags);
+ 
+ 	expopt = NULL;
+ 	for ( p = opts; (o = strsep(&p, ",")) != NULL; ) {
+ 		if (strcmp("fstab",o) == 0)
+ 			expopt = catopt(expopt,fstab);
+ 		else if (strcmp("cur",o) == 0)
+ 			expopt = catopt(expopt,cur);
+ 		else
+ 			expopt = catopt(expopt,o);
+ 	}
+ 	free(cur);
+ 	free(opts);
+ 
+ 	newopt = NULL;
+ 	for ( p = expopt; (o = strsep(&p, ",")) != NULL; ) {
+ 		if ( (tmpopt = malloc( strlen(o) + 2 + 1 )) == NULL)
+ 			err(1,NULL);
+ 	
+ 		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()
  {
***************
*** 565,596 ****
      const struct statfs	    *ent;
  {
      struct fstab    *fst;
  
      printf ("%s\t%s\t%s %s",
  	    ent->f_mntfromname, ent->f_mntonname,
  	    mnttype[ent->f_type],
! 	    (ent->f_flags & MNT_RDONLY) ? "ro" : "rw");
! 
!     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 (fst = getfsspec (ent->f_mntfromname))
  	printf ("\t%u %u\n", fst->fs_freq, fst->fs_passno);
--- 638,651 ----
      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,
  	    mnttype[ent->f_type],
!             opts);
!     free(opts);
  
      if (fst = getfsspec (ent->f_mntfromname))
  	printf ("\t%u %u\n", fst->fs_freq, fst->fs_passno);
***************
*** 600,603 ****
--- 655,677 ----
  	printf ("\t1 1\n");
      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");
  }

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9804232301.aa28604>