Subject: bin/8791: mountd is bozotic
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mrg@eterna.com.au>
List: netbsd-bugs
Date: 11/13/1999 20:33:52
>Number:         8791
>Category:       bin
>Synopsis:       mountd is bozotic
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Nov 13 20:33:01 1999
>Last-Modified:
>Originator:     matthew green
>Organization:
people's front against (bozotic) www (softwar foundation)
>Release:        <NetBSD-current source date>19991109
>Environment:
	
System: NetBSD towers-of-dub.eterna.com.au 1.4M NetBSD 1.4M (_towers_) #25: Wed Nov 10 23:51:03 EST 1999 mrg@towers-of-dub.eterna.com.au:/orb/y/_towers_ alpha


>Description:

	before re-reading the exports list (such as on SIGHUP), NetBSD
	mountd(8) traveses the current mount list removing export from
	all these filesystems, then it goes and re-exports them as it
	processes /etc/exports.

	this leaves a nice time when file systems are not exported and
	thus can cause clients to fail.  i have had countless builds
	fail because of this over the years.  it recently started 
	affected my mp3 player -- things got serious.

>How-To-Repeat:

	run "make bulid" on a machine using /usr/src over NFS to a
	NetBSD server.  run "kill -HUP <mountd.pid>" a Lot until
	the make build breaks due to failed permissions check. a
	slower NFS server will probably make it easier to reproduce.

>Fix:
	
	restructre the code so that it only un-exports file systems
	that require this.  this was surprisingly simple and i was
	unable to reproduce the lossage previously encountered
	with this change (indeed, running it in debug mode showed
	what is now correct operation).


Index: mountd.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mountd/mountd.c,v
retrieving revision 1.57
diff -p -c -r1.57 mountd.c
*** mountd.c	1999/09/10 16:20:22	1.57
--- mountd.c	1999/11/14 04:21:36
*************** get_exportlist(n)
*** 823,863 ****
  	grphead = NULL;
  
  	/*
! 	 * And delete exports that are in the kernel for all local
! 	 * file systems.
! 	 * XXX: Should know how to handle all local exportable file systems
! 	 *      instead of just MOUNT_FFS.
  	 */
  	num = getmntinfo(&fsp, MNT_NOWAIT);
- 	for (i = 0; i < num; i++) {
- 		union {
- 			struct ufs_args ua;
- 			struct iso_args ia;
- 			struct mfs_args ma;
- 			struct msdosfs_args da;
- 			struct adosfs_args aa;
- 		} targs;
- 
- 		if (!strncmp(fsp->f_fstypename, MOUNT_MFS, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_FFS, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_EXT2FS, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_MSDOS, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_ADOSFS, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_NULL, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_UMAP, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_UNION, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_CD9660, MFSNAMELEN) ||
- 		    !strncmp(fsp->f_fstypename, MOUNT_NTFS, MFSNAMELEN)) {
- 			bzero((char *) &targs, sizeof(targs));
- 			targs.ua.fspec = NULL;
- 			targs.ua.export.ex_flags = MNT_DELEXPORT;
- 			if (mount(fsp->f_fstypename, fsp->f_mntonname,
- 			    fsp->f_flags | MNT_UPDATE, &targs) == -1)
- 				syslog(LOG_ERR, "Can't delete exports for %s",
- 				    fsp->f_mntonname);
- 		}
- 		fsp++;
- 	}
  
  	/*
  	 * Read in the exports file and build the list, calling
--- 823,831 ----
  	grphead = NULL;
  
  	/*
! 	 * save off the current export lists for later
  	 */
  	num = getmntinfo(&fsp, MNT_NOWAIT);
  
  	/*
  	 * Read in the exports file and build the list, calling
*************** nextline:
*** 1035,1040 ****
--- 1003,1061 ----
  		free(line);
  	}
  	(void)fclose(exp_file);
+ 
+ 	/*
+ 	 * Ok, remove any filesystems that existed before that should
+ 	 * not be there anymore.
+ 	 */
+ 	/*
+ 	 * XXX: Should know how to handle all local exportable file systems
+ 	 *      instead of just MOUNT_FFS.
+ 	 */
+ 	for (i = 0; i < num; i++, fsp++) {
+ 		union {
+ 			struct ufs_args ua;
+ 			struct iso_args ia;
+ 			struct mfs_args ma;
+ 			struct msdosfs_args da;
+ 			struct adosfs_args aa;
+ 		} targs;
+ 
+ 		if (debug)
+ 			(void)fprintf(stderr,
+ 			    "seeing if we want to delete %s.\n",
+ 			    fsp->f_mntonname);
+ 		/*
+ 		 * If we can find it in our internal list, we do not
+ 		 * want to delete it from the kernel.
+ 		 */
+ 		if (ex_search(&fsp->f_fsid))
+ 			continue;
+ 
+ 		if (!strncmp(fsp->f_fstypename, MOUNT_MFS, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_FFS, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_EXT2FS, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_MSDOS, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_ADOSFS, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_NULL, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_UMAP, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_UNION, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_CD9660, MFSNAMELEN) ||
+ 		    !strncmp(fsp->f_fstypename, MOUNT_NTFS, MFSNAMELEN)) {
+ 			if (debug)
+ 				(void)fprintf(stderr,
+ 				    "Deleting export for mount %s.\n",
+ 				    fsp->f_mntonname);
+ 
+ 			bzero((char *) &targs, sizeof(targs));
+ 			targs.ua.fspec = NULL;
+ 			targs.ua.export.ex_flags = MNT_DELEXPORT;
+ 			if (mount(fsp->f_fstypename, fsp->f_mntonname,
+ 			    fsp->f_flags | MNT_UPDATE, &targs) == -1)
+ 				syslog(LOG_ERR, "Can't delete exports for %s",
+ 				    fsp->f_mntonname);
+ 		}
+ 	}
  }
  
  /*
>Audit-Trail:
>Unformatted: