Backout revision 1.58-1.61; Since we currently only have a way to unexport
per mount point, the way ``try to export and unexport an unnecessary mount point later'' may leave unwanted information in the kernel, and doesn't work if a mount point is default exported or publically exported. To fix the race condtion, we need another way.
This commit is contained in:
parent
4316d096db
commit
700450f288
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: mountd.c,v 1.61 2000/02/16 01:27:14 dante Exp $ */
|
||||
/* $NetBSD: mountd.c,v 1.62 2000/02/16 04:08:40 enami Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 2000
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
@ -51,7 +51,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: mountd.c,v 1.61 2000/02/16 01:27:14 dante Exp $");
|
||||
__RCSID("$NetBSD: mountd.c,v 1.62 2000/02/16 04:08:40 enami Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -176,15 +176,6 @@ struct fhreturn {
|
||||
nfsfh_t fhr_fh;
|
||||
};
|
||||
|
||||
union mount_args {
|
||||
struct ufs_args ua;
|
||||
struct iso_args ia;
|
||||
struct mfs_args ma;
|
||||
struct msdosfs_args da;
|
||||
struct adosfs_args aa;
|
||||
};
|
||||
|
||||
|
||||
/* Global defs */
|
||||
static char *add_expdir __P((struct dirlist **, char *, int));
|
||||
static void add_dlist __P((struct dirlist **, struct dirlist *,
|
||||
@ -200,9 +191,6 @@ static int do_mount __P((const char *, size_t, struct exportlist *,
|
||||
static int do_opt __P((const char *, size_t, char **, char **,
|
||||
struct exportlist *, struct grouplist *, int *, int *, struct ucred *));
|
||||
static struct exportlist *ex_search __P((fsid_t *));
|
||||
static int mount_unexport __P((struct statfs *));
|
||||
static int mount_export __P((char *, int, struct statfs *,
|
||||
union mount_args *));
|
||||
static int parse_directory __P((const char *, size_t, struct grouplist *,
|
||||
int, char *, struct exportlist **, struct statfs *));
|
||||
static int parse_host_netgroup __P((const char *, size_t, struct exportlist *,
|
||||
@ -835,9 +823,41 @@ get_exportlist(n)
|
||||
grphead = NULL;
|
||||
|
||||
/*
|
||||
* save off the current export lists for later
|
||||
* 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
|
||||
@ -1015,32 +1035,6 @@ nextline:
|
||||
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++) {
|
||||
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 (mount_unexport(fsp) == -1) {
|
||||
syslog(LOG_ERR, "Can't delete exports for %s",
|
||||
fsp->f_mntonname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1659,92 +1653,6 @@ estrdup(s)
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
mount_unexport(fsp)
|
||||
struct statfs *fsp;
|
||||
{
|
||||
union mount_args 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)) {
|
||||
if (debug)
|
||||
(void)fprintf(stderr,
|
||||
"Deleting export for mount %s.\n",
|
||||
fsp->f_mntonname);
|
||||
|
||||
memset(&targs, 0, sizeof(targs));
|
||||
targs.ua.fspec = NULL;
|
||||
targs.ua.export.ex_flags = MNT_DELEXPORT;
|
||||
return (mount(fsp->f_fstypename, fsp->f_mntonname,
|
||||
fsp->f_flags | MNT_UPDATE, &targs));
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
#define MNTD_EXPORTED 0
|
||||
#define MNTD_NO_PERM 1
|
||||
#define MNTD_NO_REMOUNT 2
|
||||
#define MNTD_UNSUCC 3
|
||||
|
||||
static int
|
||||
mount_export(dirp, dirplen, fsb, mntargs)
|
||||
char *dirp;
|
||||
int dirplen;
|
||||
struct statfs *fsb;
|
||||
union mount_args *mntargs;
|
||||
{
|
||||
char *cp, savedc;
|
||||
|
||||
cp = NULL; /* First, cp points terminating NUL. */
|
||||
|
||||
/*
|
||||
* XXX:
|
||||
* Maybe I should just use the fsb->f_mntonname path instead
|
||||
* of looping back up the dirp to the mount point??
|
||||
* Also, needs to know how to export all types of local
|
||||
* exportable file systems and not just MOUNT_FFS.
|
||||
*/
|
||||
while ((mount(fsb->f_fstypename, dirp,
|
||||
fsb->f_flags | MNT_UPDATE, mntargs)) == -1) {
|
||||
if (cp)
|
||||
*cp-- = savedc;
|
||||
else
|
||||
cp = dirp + dirplen - 1;
|
||||
if (errno == EPERM) {
|
||||
return(MNTD_NO_PERM);
|
||||
}
|
||||
if (opt_flags & OP_ALLDIRS) {
|
||||
return(MNTD_NO_REMOUNT);
|
||||
}
|
||||
|
||||
/* back up over the last component */
|
||||
while (*cp == '/' && cp > dirp)
|
||||
cp--;
|
||||
while (*(cp - 1) != '/' && cp > dirp)
|
||||
cp--;
|
||||
if (cp == dirp) {
|
||||
if (debug)
|
||||
(void)fprintf(stderr, "mnt unsucc\n");
|
||||
fprintf(stderr, "3\n");
|
||||
return (MNTD_UNSUCC);
|
||||
}
|
||||
savedc = *cp;
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
return (MNTD_EXPORTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the mount syscall with the update flag to push the export info into
|
||||
* the kernel.
|
||||
@ -1761,10 +1669,18 @@ do_mount(line, lineno, ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
|
||||
int dirplen;
|
||||
struct statfs *fsb;
|
||||
{
|
||||
char *cp = NULL;
|
||||
u_int32_t **addrp;
|
||||
int done, error;
|
||||
int done;
|
||||
char savedc = '\0';
|
||||
struct sockaddr_in sin, imask;
|
||||
union mount_args args;
|
||||
union {
|
||||
struct ufs_args ua;
|
||||
struct iso_args ia;
|
||||
struct mfs_args ma;
|
||||
struct msdosfs_args da;
|
||||
struct adosfs_args aa;
|
||||
} args;
|
||||
u_int32_t net;
|
||||
|
||||
args.ua.fspec = 0;
|
||||
@ -1829,53 +1745,58 @@ do_mount(line, lineno, ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
|
||||
default:
|
||||
syslog(LOG_ERR, "\"%s\", line %ld: Bad netgroup type",
|
||||
line, (unsigned long)lineno);
|
||||
if (cp)
|
||||
*cp = savedc;
|
||||
return (1);
|
||||
};
|
||||
|
||||
if((error = mount_export(dirp, dirplen, fsb, &args))
|
||||
!= MNTD_EXPORTED) {
|
||||
if(error == MNTD_NO_REMOUNT) {
|
||||
syslog(LOG_ERR, "\"%s\", line %ld: "
|
||||
"Could not remount %s: %m",
|
||||
line, (unsigned long)lineno, dirp);
|
||||
return 1;
|
||||
/*
|
||||
* XXX:
|
||||
* Maybe I should just use the fsb->f_mntonname path instead
|
||||
* of looping back up the dirp to the mount point??
|
||||
* Also, needs to know how to export all types of local
|
||||
* exportable file systems and not just MOUNT_FFS.
|
||||
*/
|
||||
while (mount(fsb->f_fstypename, dirp,
|
||||
fsb->f_flags | MNT_UPDATE, &args) == -1) {
|
||||
if (cp)
|
||||
*cp-- = savedc;
|
||||
else
|
||||
cp = dirp + dirplen - 1;
|
||||
if (errno == EPERM) {
|
||||
syslog(LOG_ERR,
|
||||
"\"%s\", line %ld: Can't change attributes for %s to %s",
|
||||
line, (unsigned long)lineno,
|
||||
dirp, (grp->gr_type == GT_HOST) ?
|
||||
grp->gr_ptr.gt_hostent->h_name :
|
||||
(grp->gr_type == GT_NET) ?
|
||||
grp->gr_ptr.gt_net.nt_name :
|
||||
"Unknown");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* It may be just some export options are modified.
|
||||
* Unexport and retry.
|
||||
*/
|
||||
if(mount_unexport(fsb)) {
|
||||
if(mount_export(dirp, dirplen, fsb, &args)
|
||||
!= MNTD_EXPORTED) {
|
||||
switch(error) {
|
||||
case MNTD_NO_PERM:
|
||||
syslog(LOG_ERR,
|
||||
"\"%s\", line %ld: "
|
||||
"Can't change attributes "
|
||||
"for %s to %s",
|
||||
line, (unsigned long)lineno,
|
||||
dirp,
|
||||
(grp->gr_type == GT_HOST) ?
|
||||
grp->gr_ptr.gt_hostent->h_name :
|
||||
(grp->gr_type == GT_NET) ?
|
||||
grp->gr_ptr.gt_net.nt_name :
|
||||
"Unknown");
|
||||
break;
|
||||
|
||||
case MNTD_UNSUCC:
|
||||
syslog(LOG_ERR,
|
||||
"\"%s\", line %ld: "
|
||||
"Can't export %s",
|
||||
line,
|
||||
(unsigned long)lineno, dirp);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (opt_flags & OP_ALLDIRS) {
|
||||
syslog(LOG_ERR,
|
||||
"\"%s\", line %ld: Could not remount %s: %m",
|
||||
line, (unsigned long)lineno,
|
||||
dirp);
|
||||
return (1);
|
||||
}
|
||||
/* back up over the last component */
|
||||
while (*cp == '/' && cp > dirp)
|
||||
cp--;
|
||||
while (*(cp - 1) != '/' && cp > dirp)
|
||||
cp--;
|
||||
if (cp == dirp) {
|
||||
if (debug)
|
||||
(void)fprintf(stderr, "mnt unsucc\n");
|
||||
syslog(LOG_ERR,
|
||||
"\"%s\", line %ld: Can't export %s",
|
||||
line, (unsigned long)lineno, dirp);
|
||||
return (1);
|
||||
}
|
||||
savedc = *cp;
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
if (addrp) {
|
||||
++addrp;
|
||||
if (*addrp == NULL)
|
||||
@ -1883,7 +1804,8 @@ do_mount(line, lineno, ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
|
||||
} else
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
if (cp)
|
||||
*cp = savedc;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user