Date: Sat, 6 Nov 1999 05:40:01 -0800 (PST) From: Martin Blapp <blapp@attic.ch> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/14709: umountall requests possibly mishandled by mountd(8) Message-ID: <199911061340.FAA95796@freefall.freebsd.org>
index | next in thread | raw e-mail
The following reply was made to PR bin/14709; it has been noted by GNATS.
From: Martin Blapp <blapp@attic.ch>
To: freebsd-gnats-submit@freebsd.org,
cjc@cc942873-a.ewndsr1.nj.home.com
Cc:
Subject: Re: bin/14709: umountall requests possibly mishandled by mountd(8)
Date: Sat, 06 Nov 1999 12:57:40 +0000
From RFC 1813 :
---------------
5.2.4 Procedure 4: UMNTALL - Remove all mount entries
SYNOPSIS
void MOUNTPROC3_UMNTALL(void) = 4;
DESCRIPTION
Procedure UMNTALL removes all of the mount entries for
this client previously recorded by calls to MNT. AUTH_UNIX
authentication or better is required.
IMPLEMENTATION
This procedure should be used by clients when they are
recovering after a system shutdown. If the client could
not successfully unmount all of its file systems before
being shutdown or the client crashed because of a software
or hardware problem, there may be servers which still have
mount entries for this client. This is an easy way for the
client to inform all servers at once that it does not have
any mounted file systems. However, since this procedure
is generally implemented using broadcast RPC, it is only
of limited usefullness.
ERRORS
There are no MOUNT protocol errors which can be returned
from this procedure. However, RPC errors may be returned
for authentication or other RPC failures.
----------------------------------------------------------------
Imagine we have three hosts in our little network:
A: big server, has nfs-server running.
B: little server, has nfs-client and a nfs-server running.
C: workstation, has only nfs-clients.
One can make the following conclusions:
1. If 'B' has mounted some filesystems from 'A', and 'B'
is being rebooted, mountd(8) from 'B' sends a broadcast
RPC_UMNTALL. The mountd(8) from 'A' should recieve it
and should remove all entries of host 'B' from
/var/db/mountdtab. It seems that our implementation of
rpc.mountd sends the RPC_UMNTALL on a unprivileged
port. If mountd(8) on 'A' is started with '-n',
the RPC_UMNTALL is successful. I'll have to look at
this today.
2. Running a NFS-Client does not mean we have a running NFS-
Server on the host. This is the setup for most workstations.
If we shutdown 'C', 'B' doesn't get informed and can not clean
it's /var/db/mountdtab.
3. As stated in the RFC, use of broadcast RPC is only of
limited usefullness.
4. The _only_ place where a RPC_UMNTALL call does make any sense
is _after_ reboot, but _before_ any new nfs-mounts.
----------------------------------------------------------------
I propose the following changes to *BSD* :
------------------------------------------
1. To have two mounttabs in /var/db/:
/var/db/mountdtab (only for mountd)
/var/db/mounttab (for mount_nfs(8), umount(8))
In /var/db/mounttab we record all mounted
nfs-mounts, and if we unmount them, we remove
the entrys.
2. Add a command which calls RPC_UMNTALL for all entrys
in /var/db/mounttab during startup before any NFS-mount.
Remember: all remaining entries in /var/db/mounttab are
'not properly unmounted nfs-mounts'.
3. Do not use broadcast RPC anymore, so we can have a time-
out control. We can also use a function like pingnfsserver()
from mount_nfs(8).
4. the following patch to mountd(8)
Index: src/sbin/mountd/mountd.c
===================================================================
RCS file: /usr/home/ncvs/src/sbin/mountd/mountd.c,v
retrieving revision 1.37
diff -u -r1.37 mountd.c
--- mountd.c 1999/10/06 18:20:44 1.37
+++ mountd.c 1999/11/06 11:59:55
@@ -193,8 +193,6 @@
void parsecred __P((char *, struct ucred *));
int put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int
*));
int scan_tree __P((struct dirlist *, u_int32_t));
-void send_umntall __P((void));
-int umntall_each __P((caddr_t, struct sockaddr_in *));
static void usage __P((void));
int xdr_dir __P((XDR *, char *));
int xdr_explist __P((XDR *, caddr_t));
@@ -313,7 +311,6 @@
signal(SIGQUIT, SIG_IGN);
}
signal(SIGHUP, (void (*) __P((int))) get_exportlist);
- signal(SIGTERM, (void (*) __P((int))) send_umntall);
{ FILE *pidfile = fopen(_PATH_MOUNTDPID, "w");
if (pidfile != NULL) {
fprintf(pidfile, "%d\n", getpid());
@@ -2081,26 +2078,6 @@
}
fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp);
fclose(mlfile);
-}
-
-/*
- * This function is called via. SIGTERM when the system is going down.
- * It sends a broadcast RPCMNT_UMNTALL.
- */
-void
-send_umntall()
-{
- (void) clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL,
- xdr_void, (caddr_t)0, xdr_void, (caddr_t)0,
umntall_each);
- exit(0);
-}
-
-int
-umntall_each(resultsp, raddr)
- caddr_t resultsp;
- struct sockaddr_in *raddr;
-{
- return (1);
}
/*
This would solve all the strange error-messages we have seen from
mountd(8) and leads also to proper handling of /var/db/mountdtab.
Martin Blapp
Improware AG, Pratteln, Switzerland
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199911061340.FAA95796>
