Subject: bin/6182 umount -R segfaults...
To: None <current-users@netbsd.org>
From: Matthew Orgass <darkstar@pgh.net>
List: current-users
Date: 05/01/1999 02:03:47
Please apply the following patch to umount and pull it up to 1.4. It
fixes the -R segfault as well as skipping things that should not be done
with the -a or -A flags (and updates the man page).
Also, please apply the patches at the bottom of bin/3615 to -current.
While I don't think this is quite an "utterly critical" change, it seems
bad to need a special flag to be able to unmount some things that were
mounted with system utilities (such as mounting under a symlinked
directory).
Thanks!
Matthew Orgass
darkstar@pgh.net
--- sbin/umount/umount.c.bak Tue Apr 20 21:49:50 1999
+++ sbin/umount/umount.c Fri Apr 30 18:21:13 1999
@@ -77,8 +77,9 @@
int main __P((int, char *[]));
int namematch __P((struct hostent *));
int selected __P((int));
+int umountone __P((char *, char **));
int umountall __P((char **));
-int umountfs __P((char *, char **));
+int umountfs __P((char *, char *, char *));
void usage __P((void));
int xdr_dir __P((XDR *, char *));
@@ -149,7 +150,9 @@
for (errs = 0, mnts--; mnts > 0; mnts--) {
if (checkvfsname(mntbuf[mnts].f_fstypename, typelist))
continue;
- if (umountfs(mntbuf[mnts].f_mntonname, typelist) != 0)
+ if (umountfs(mntbuf[mnts].f_mntfromname,
+ mntbuf[mnts].f_mntonname,
+ mntbuf[mnts].f_fstypename) != 0)
errs = 1;
}
break;
@@ -160,13 +163,71 @@
break;
case 0:
for (errs = 0; *argv != NULL; ++argv)
- if (umountfs(*argv, typelist) != 0)
+ if (umountone(*argv, typelist) != 0)
errs = 1;
break;
}
exit(errs);
}
+int
+umountone(name, typelist)
+ char *name;
+ char **typelist;
+{
+ struct stat sb;
+ char *type, *mntpt, rname[MAXPATHLEN];
+ mntwhat what;
+
+ if (raw)
+ strncpy(rname, name, MAXPATHLEN)[MAXPATHLEN-1] = '\0';
+ else
+ if (realpath(name, rname) == NULL) {
+ warn("%s", rname);
+ return (1);
+ }
+
+ mntpt = name = rname;
+ what = MNTANY;
+
+ if (stat(name, &sb) == 0) {
+ if (S_ISBLK(sb.st_mode))
+ what = MNTON;
+ else if (S_ISDIR(sb.st_mode))
+ what = MNTFROM;
+ }
+
+ switch (what) {
+ case MNTON:
+ if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
+ warnx("%s: not currently mounted", name);
+ return (1);
+ }
+ break;
+ case MNTFROM:
+ if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
+ warnx("%s: not currently mounted", mntpt);
+ return (1);
+ }
+ break;
+ default:
+ if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
+ name = rname;
+ if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
+ warnx("%s: not currently mounted", name);
+ return (1);
+ }
+ }
+ }
+
+ if (checkvfsname(type, typelist))
+ return (1);
+
+ if (umountfs(name, mntpt, type) != 0)
+ return (1);
+
+ return (0);
+}
int
umountall(typelist)
@@ -189,94 +250,47 @@
if (checkvfsname(fs[n].f_fstypename, typelist))
continue;
- if (umountfs(fs[n].f_mntonname, typelist))
+ if (umountfs(fs[n].f_mntfromname, fs[n].f_mntonname,
+ fs[n].f_fstypename))
rval = 1;
}
return (rval);
}
int
-umountfs(name, typelist)
- char *name;
- char **typelist;
+umountfs(name, mntpt, type)
+ char *name; /* for verbose */
+ char *mntpt;
+ char *type;
{
enum clnt_stat clnt_stat;
struct hostent *hp;
struct sockaddr_in saddr;
- struct stat sb;
struct timeval pertry, try;
CLIENT *clp;
int so;
- char *type, *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
- mntwhat what;
+ char *delimp, *hostp;
hp = NULL;
delimp = NULL;
- if (raw) {
- mntpt = name;
- } else {
-
- if (realpath(name, rname) == NULL) {
- warn("%s", rname);
- return (1);
- }
-
- what = MNTANY;
- mntpt = name = rname;
-
- if (stat(name, &sb) == 0) {
- if (S_ISBLK(sb.st_mode))
- what = MNTON;
- else if (S_ISDIR(sb.st_mode))
- what = MNTFROM;
+ if (!strncmp(type, MOUNT_NFS, MFSNAMELEN)) {
+ if ((delimp = strchr(name, '@')) != NULL) {
+ hostp = delimp + 1;
+ *delimp = '\0';
+ hp = gethostbyname(hostp);
+ *delimp = '@';
+ } else if ((delimp = strchr(name, ':')) != NULL) {
+ *delimp = '\0';
+ hostp = name;
+ hp = gethostbyname(hostp);
+ name = delimp + 1;
+ *delimp = ':';
}
-
- switch (what) {
- case MNTON:
- if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
- warnx("%s: not currently mounted", name);
- return (1);
- }
- break;
- case MNTFROM:
- if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
- warnx("%s: not currently mounted", mntpt);
- return (1);
- }
- break;
- default:
- if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
- name = rname;
- if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
- warnx("%s: not currently mounted", name);
- return (1);
- }
- }
- }
-
- if (checkvfsname(type, typelist))
- return (1);
-
- hp = NULL;
- if (!strncmp(type, MOUNT_NFS, MFSNAMELEN)) {
- if ((delimp = strchr(name, '@')) != NULL) {
- hostp = delimp + 1;
- *delimp = '\0';
- hp = gethostbyname(hostp);
- *delimp = '@';
- } else if ((delimp = strchr(name, ':')) != NULL) {
- *delimp = '\0';
- hostp = name;
- hp = gethostbyname(hostp);
- name = delimp + 1;
- *delimp = ':';
- }
- }
-
- if (!namematch(hp))
- return (1);
}
+
+ if (!namematch(hp))
+ return (1);
if (verbose)
(void)printf("%s: unmount from %s\n", name, mntpt);
--- sbin/umount/umount.8.bak Fri Apr 30 18:24:29 1999
+++ sbin/umount/umount.8 Fri Apr 30 18:29:54 1999
@@ -88,22 +88,14 @@
.Nm
would attempt to do).
.It Fl R
-Take the
-.Ar special | node
-argument as a path to be passed directly to
-.Xr unmount 2 ,
-bypassing all attempts to be smart about mechanically determining the
-correct path from the argument.
-This option is incompatible with any option that potentially umounts
-more than one filesystem, such as
-.Fl a ,
-but it can be used with
-.Fl f
-and/or
-.Fl v .
-This is the only way to unmount something that does not appear as a
-directory (such as a nullfs mount of a plain file); there are probably
-other cases where it is necessary.
+Do not attempt to resolve the path of
+.Ar special
+or
+.Ar node .
+This option has no effect if used with
+.Fl a
+or
+.Fl A .
.It Fl h Ar host
Only filesystems mounted from the specified host will be
unmounted.