Merge from Lite2.
- use new getvfsbyname() interface. - new -A option, like -a except only mounted file systems are unmounted. All non-cosmetic FreeBSD changes in umount.c, except ignoring of realpath() failures, went away because they are done better in Lite2. realpath() failures must be ignored so that non-pathnames like "<above>:/foo" and "host:/bar" get as far as mount(2). Reviewed by: dfr
This commit is contained in:
parent
71706cc1fd
commit
d499a0ef65
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=26683
@ -1,6 +1,13 @@
|
||||
# @(#)Makefile 8.2 (Berkeley) 2/20/94
|
||||
# @(#)Makefile 8.4 (Berkeley) 6/22/95
|
||||
|
||||
PROG= umount
|
||||
SRCS= umount.c vfslist.c
|
||||
MAN8= umount.8
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
CFLAGS+= -D_NEW_VFSCONF
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -29,23 +29,23 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)umount.8 8.1 (Berkeley) 2/20/94
|
||||
.\" @(#)umount.8 8.2 (Berkeley) 5/8/95
|
||||
.\"
|
||||
.Dd February 20, 1994
|
||||
.Dd May 8, 1995
|
||||
.Dt UMOUNT 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm umount
|
||||
.Nd unmount file systems
|
||||
.Nd unmount filesystems
|
||||
.Sh SYNOPSIS
|
||||
.Nm umount
|
||||
.Op Fl fv
|
||||
.Ar special | node
|
||||
.Nm umount
|
||||
.Fl a
|
||||
.Fl a | A
|
||||
.Op Fl fv
|
||||
.Op Fl h Ar host
|
||||
.Op Fl t Ar ufs | lfs | external_type
|
||||
.Op Fl t Ar type
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm umount
|
||||
@ -54,7 +54,7 @@ calls the
|
||||
.Xr unmount 2
|
||||
system call to remove a
|
||||
.Ar "special device"
|
||||
or the remote node (rhost:path) from the file system tree at the point
|
||||
or the remote node (rhost:path) from the filesystem tree at the point
|
||||
.Ar node .
|
||||
If either
|
||||
.Ar special
|
||||
@ -67,23 +67,26 @@ file.
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl a
|
||||
All of the file systems described in
|
||||
All the filesystems described in
|
||||
.Xr fstab 5
|
||||
are unmounted.
|
||||
.It Fl A
|
||||
All the currently mounted filesystems except
|
||||
the root are unmounted.
|
||||
.It Fl f
|
||||
The file system is forcibly unmounted.
|
||||
The filesystem is forcibly unmounted.
|
||||
Active special devices continue to work,
|
||||
but all other files return errors if further accesses are attempted.
|
||||
The root file system cannot be forcibly unmounted.
|
||||
The root filesystem cannot be forcibly unmounted.
|
||||
.It Fl h Ar host
|
||||
Only filesystems mounted from the specified host will be
|
||||
unmounted.
|
||||
This option is implies the
|
||||
.Fl a
|
||||
.Fl A
|
||||
option and, unless otherwise specified with the
|
||||
.Fl t
|
||||
option, will only unmount NFS filesystems.
|
||||
.It Fl t Ar "ufs \\*(Ba lfs \\*(Ba external type"
|
||||
.It Fl t Ar type
|
||||
Is used to indicate the actions should only be taken on
|
||||
filesystems of the specified type.
|
||||
More than one type may be specified in a comma separated list.
|
||||
@ -104,13 +107,13 @@ umounts all filesystems of the type
|
||||
and
|
||||
.Tn MFS .
|
||||
.It Fl v
|
||||
Verbose, additional information is printed out as each file system
|
||||
Verbose, additional information is printed out as each filesystem
|
||||
is unmounted.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/fstab -compact
|
||||
.It Pa /etc/fstab
|
||||
file system table
|
||||
filesystem table
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr unmount 2 ,
|
||||
|
@ -38,7 +38,7 @@ static char copyright[] =
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)umount.c 8.3 (Berkeley) 2/20/94";
|
||||
static char sccsid[] = "@(#)umount.c 8.8 (Berkeley) 5/8/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -63,16 +63,16 @@ static char sccsid[] = "@(#)umount.c 8.3 (Berkeley) 2/20/94";
|
||||
|
||||
typedef enum { MNTON, MNTFROM } mntwhat;
|
||||
|
||||
int fake, fflag, vflag, *typelist;
|
||||
int fake, fflag, vflag;
|
||||
char *nfshost;
|
||||
|
||||
int fsnametotype __P((char *));
|
||||
char *getmntname __P((char *, mntwhat, int *));
|
||||
void maketypelist __P((char *));
|
||||
int checkvfsname __P((const char *, char **));
|
||||
char *getmntname __P((char *, mntwhat, char **));
|
||||
char **makevfslist __P((char *));
|
||||
int selected __P((int));
|
||||
int namematch __P((struct hostent *));
|
||||
int umountall __P((void));
|
||||
int umountfs __P((char *));
|
||||
int umountall __P((char **));
|
||||
int umountfs __P((char *, char **));
|
||||
void usage __P((void));
|
||||
int xdr_dir __P((XDR *, char *));
|
||||
|
||||
@ -81,14 +81,19 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int all, ch, errs;
|
||||
int all, ch, errs, mnts;
|
||||
char **typelist = NULL;
|
||||
struct statfs *mntbuf;
|
||||
|
||||
/* Start disks transferring immediately. */
|
||||
sync();
|
||||
|
||||
all = 0;
|
||||
while ((ch = getopt(argc, argv, "aFfh:t:v")) != -1)
|
||||
while ((ch = getopt(argc, argv, "AaFfh:t:v")) != -1)
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
all = 2;
|
||||
break;
|
||||
case 'a':
|
||||
all = 1;
|
||||
break;
|
||||
@ -98,12 +103,14 @@ main(argc, argv)
|
||||
case 'f':
|
||||
fflag = MNT_FORCE;
|
||||
break;
|
||||
case 'h': /* -h implies -a. */
|
||||
all = 1;
|
||||
case 'h': /* -h implies -A. */
|
||||
all = 2;
|
||||
nfshost = optarg;
|
||||
break;
|
||||
case 't':
|
||||
maketypelist(optarg);
|
||||
if (typelist != NULL)
|
||||
errx(1, "only one -t option may be specified.");
|
||||
typelist = makevfslist(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
@ -120,24 +127,44 @@ main(argc, argv)
|
||||
|
||||
/* -h implies "-t nfs" if no -t flag. */
|
||||
if ((nfshost != NULL) && (typelist == NULL))
|
||||
maketypelist("nfs");
|
||||
typelist = makevfslist("nfs");
|
||||
|
||||
if (all) {
|
||||
switch (all) {
|
||||
case 2:
|
||||
if ((mnts = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
|
||||
warn("getmntinfo");
|
||||
errs = 1;
|
||||
break;
|
||||
}
|
||||
for (errs = 0, mnts--; mnts > 0; mnts--) {
|
||||
if (checkvfsname(mntbuf[mnts].f_fstypename, typelist))
|
||||
continue;
|
||||
if (umountfs(mntbuf[mnts].f_mntonname, typelist) != 0)
|
||||
errs = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (setfsent() == 0)
|
||||
err(1, "%s", _PATH_FSTAB);
|
||||
errs = umountall();
|
||||
} else
|
||||
errs = umountall(typelist);
|
||||
break;
|
||||
case 0:
|
||||
for (errs = 0; *argv != NULL; ++argv)
|
||||
errs += umountfs(*argv);
|
||||
if (umountfs(*argv, typelist) != 0)
|
||||
errs = 1;
|
||||
break;
|
||||
}
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
int
|
||||
umountall()
|
||||
umountall(typelist)
|
||||
char **typelist;
|
||||
{
|
||||
struct fstab *fs;
|
||||
int rval, type;
|
||||
char *cp;
|
||||
struct vfsconf vfc;
|
||||
|
||||
while ((fs = getfsent()) != NULL) {
|
||||
/* Ignore the root. */
|
||||
@ -152,11 +179,11 @@ umountall()
|
||||
strcmp(fs->fs_type, FSTAB_RQ))
|
||||
continue;
|
||||
/* If an unknown file system type, complain. */
|
||||
if ((type = fsnametotype(fs->fs_vfstype)) == MOUNT_NONE) {
|
||||
if (getvfsbyname(fs->fs_vfstype, &vfc) < 0) {
|
||||
warnx("%s: unknown mount type", fs->fs_vfstype);
|
||||
continue;
|
||||
}
|
||||
if (!selected(type))
|
||||
if (checkvfsname(fs->fs_vfstype, typelist))
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -167,16 +194,16 @@ umountall()
|
||||
if ((cp = malloc((size_t)strlen(fs->fs_file) + 1)) == NULL)
|
||||
err(1, NULL);
|
||||
(void)strcpy(cp, fs->fs_file);
|
||||
rval = umountall();
|
||||
return (umountfs(cp) || rval);
|
||||
rval = umountall(typelist);
|
||||
return (umountfs(cp, typelist) || rval);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Returns 1 on failure, 0 on success */
|
||||
int
|
||||
umountfs(name)
|
||||
umountfs(name, typelist)
|
||||
char *name;
|
||||
char **typelist;
|
||||
{
|
||||
enum clnt_stat clnt_stat;
|
||||
struct hostent *hp;
|
||||
@ -184,8 +211,8 @@ umountfs(name)
|
||||
struct stat sb;
|
||||
struct timeval pertry, try;
|
||||
CLIENT *clp;
|
||||
int so, type;
|
||||
char *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
|
||||
int so;
|
||||
char *type, *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
|
||||
|
||||
if (realpath(name, rname) == NULL) {
|
||||
/* Continue and let the system call check it... */
|
||||
@ -216,24 +243,27 @@ umountfs(name)
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!selected(type))
|
||||
return (0);
|
||||
if (checkvfsname(type, typelist))
|
||||
return (1);
|
||||
|
||||
if ((delimp = strchr(name, '@')) != NULL && type == MOUNT_NFS) {
|
||||
hp = NULL;
|
||||
if (!strcmp(type, "nfs")) {
|
||||
if ((delimp = strchr(name, '@')) != NULL) {
|
||||
hostp = delimp + 1;
|
||||
*delimp = '\0';
|
||||
hp = gethostbyname(hostp);
|
||||
*delimp = '@';
|
||||
} else if ((delimp = strchr(name, ':')) != NULL && type == MOUNT_NFS) {
|
||||
} else if ((delimp = strchr(name, ':')) != NULL) {
|
||||
*delimp = '\0';
|
||||
hostp = name;
|
||||
hp = gethostbyname(hostp);
|
||||
name = delimp + 1;
|
||||
*delimp = ':';
|
||||
} else
|
||||
hp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!namematch(hp))
|
||||
return (0);
|
||||
return (1);
|
||||
|
||||
if (vflag)
|
||||
(void)printf("%s: unmount from %s\n", name, mntpt);
|
||||
@ -278,101 +308,32 @@ char *
|
||||
getmntname(name, what, type)
|
||||
char *name;
|
||||
mntwhat what;
|
||||
int *type;
|
||||
char **type;
|
||||
{
|
||||
struct statfs *mntbuf;
|
||||
int i, mntsize;
|
||||
static struct statfs *mntbuf;
|
||||
static int mntsize;
|
||||
int i;
|
||||
|
||||
if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
|
||||
if (mntbuf == NULL &&
|
||||
(mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
|
||||
warn("getmntinfo");
|
||||
return (NULL);
|
||||
}
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) {
|
||||
if (type)
|
||||
*type = mntbuf[i].f_type;
|
||||
*type = mntbuf[i].f_fstypename;
|
||||
return (mntbuf[i].f_mntonname);
|
||||
}
|
||||
if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) {
|
||||
if (type)
|
||||
*type = mntbuf[i].f_type;
|
||||
*type = mntbuf[i].f_fstypename;
|
||||
return (mntbuf[i].f_mntfromname);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static enum { IN_LIST, NOT_IN_LIST } which;
|
||||
|
||||
int
|
||||
selected(type)
|
||||
int type;
|
||||
{
|
||||
int *tmp_typelist;
|
||||
|
||||
tmp_typelist=typelist;
|
||||
/* If no type specified, it's always selected. */
|
||||
if (tmp_typelist == NULL)
|
||||
return (1);
|
||||
for (; *tmp_typelist != MOUNT_NONE; ++tmp_typelist)
|
||||
if (type == *tmp_typelist)
|
||||
return (which == IN_LIST ? 1 : 0);
|
||||
return (which == IN_LIST ? 0 : 1);
|
||||
}
|
||||
|
||||
void
|
||||
maketypelist(fslist)
|
||||
char *fslist;
|
||||
{
|
||||
int *av, i;
|
||||
char *nextcp;
|
||||
|
||||
if ((fslist == NULL) || (fslist[0] == '\0'))
|
||||
errx(1, "empty type list");
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Note: the syntax is "noxxx,yyy" for no xxx's and
|
||||
* no yyy's, not the more intuitive "noyyy,noyyy".
|
||||
*/
|
||||
if (fslist[0] == 'n' && fslist[1] == 'o') {
|
||||
fslist += 2;
|
||||
which = NOT_IN_LIST;
|
||||
} else
|
||||
which = IN_LIST;
|
||||
|
||||
/* Count the number of types. */
|
||||
for (i = 0, nextcp = fslist; *nextcp != NULL; ++nextcp)
|
||||
if (*nextcp == ',')
|
||||
i++;
|
||||
|
||||
/* Build an array of that many types. */
|
||||
if ((av = typelist = malloc((i + 2) * sizeof(int))) == NULL)
|
||||
err(1, NULL);
|
||||
for (i = 0; fslist != NULL; fslist = nextcp, ++i) {
|
||||
if ((nextcp = strchr(fslist, ',')) != NULL)
|
||||
*nextcp++ = '\0';
|
||||
av[i] = fsnametotype(fslist);
|
||||
if (av[i] == MOUNT_NONE)
|
||||
errx(1, "%s: unknown mount type", fslist);
|
||||
}
|
||||
/* Terminate the array. */
|
||||
av[i++] = MOUNT_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
fsnametotype(name)
|
||||
char *name;
|
||||
{
|
||||
static char const *namelist[] = INITMOUNTNAMES;
|
||||
char const **cp;
|
||||
|
||||
for (cp = namelist; *cp; ++cp)
|
||||
if (strcmp(name, *cp) == 0)
|
||||
return (cp - namelist);
|
||||
return (MOUNT_NONE);
|
||||
}
|
||||
|
||||
int
|
||||
namematch(hp)
|
||||
struct hostent *hp;
|
||||
|
Loading…
Reference in New Issue
Block a user