⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srvr_nfs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry at Imperial College, London. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)srvr_nfs.c	8.1 (Berkeley) 6/6/93 * * $Id: srvr_nfs.c,v 5.2.2.1 1992/02/09 15:09:06 jsp beta $ * *//* * NFS server modeling */#include "am.h"#include <netdb.h>#include <rpc/pmap_prot.h>#include "mount.h"extern qelem nfs_srvr_list;qelem nfs_srvr_list = { &nfs_srvr_list, &nfs_srvr_list };typedef struct nfs_private {	u_short np_mountd;	/* Mount daemon port number */	char np_mountd_inval;	/* Port *may* be invalid */	int np_ping;		/* Number of failed ping attempts */	time_t np_ttl;		/* Time when server is thought dead */	int np_xid;		/* RPC transaction id for pings */	int np_error;		/* Error during portmap request */} nfs_private;static int np_xid;	/* For NFS pings */#define	NPXID_ALLOC()	(++np_xid)/*#define	NPXID_ALLOC()	((++np_xid&0x0fffffff) == 0 ? npxid_gc() : np_xid)*//* * Number of pings allowed to fail before host is declared down * - three-fifths of the allowed mount time...#define	MAX_ALLOWED_PINGS	((((ALLOWED_MOUNT_TIME + 5 * AM_PINGER - 1) * 3) / 5) / AM_PINGER) */#define	MAX_ALLOWED_PINGS	(3 + /* for luck ... */ 1)/* * How often to ping when starting a new server */#define	FAST_NFS_PING		3#if (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME #error: sanity check failed/* you cannot do things this way... sufficient fast pings must be given the chance to fail within the allowed mount time */#endif /* (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME */static int ping_len;static char ping_buf[sizeof(struct rpc_msg) + 32];/* * Flush any cached data */void flush_srvr_nfs_cache P((void));void flush_srvr_nfs_cache(){	fserver *fs = 0;	ITER(fs, fserver, &nfs_srvr_list) {		nfs_private *np = (nfs_private *) fs->fs_private;		if (np) {			np->np_mountd_inval = TRUE;			np->np_error = -1;		}	}}/* * Startup the NFS ping */static void start_ping(P_void);static void start_ping(){	XDR ping_xdr;	struct rpc_msg ping_msg;	rpc_msg_init(&ping_msg, NFS_PROGRAM, NFS_VERSION, NFSPROC_NULL);	/*	 * Create an XDR endpoint	 */	xdrmem_create(&ping_xdr, ping_buf, sizeof(ping_buf), XDR_ENCODE);	/*	 * Create the NFS ping message	 */	if (!xdr_callmsg(&ping_xdr, &ping_msg)) {		plog(XLOG_ERROR, "Couldn't create ping RPC message");		going_down(3);	}	/*	 * Find out how long it is	 */	ping_len = xdr_getpos(&ping_xdr);	/*	 * Destroy the XDR endpoint - we don't need it anymore	 */	xdr_destroy(&ping_xdr);}/* * Called when a portmap reply arrives *//*ARGSUSED*/static void got_portmap P((voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, voidp idv, int done));static void got_portmap(pkt, len, sa, ia, idv, done)voidp pkt;int len;struct sockaddr_in *sa;struct sockaddr_in *ia;voidp idv;int done;{	fserver *fs2 = (fserver *) idv;	fserver *fs = 0;	/*	 * Find which fileserver we are talking about	 */	ITER(fs, fserver, &nfs_srvr_list)		if (fs == fs2)			break;	if (fs == fs2) {		u_long port = 0;	/* XXX - should be short but protocol is naff */		int error = done ? pickup_rpc_reply(pkt, len, (voidp) &port, xdr_u_long) : -1;		nfs_private *np = (nfs_private *) fs->fs_private;		if (!error && port) {#ifdef DEBUG			dlog("got port (%d) for mountd on %s", port, fs->fs_host);#endif /* DEBUG */			/*			 * Grab the port number.  Portmap sends back			 * an unsigned long in native ordering, so it			 * needs converting to a unsigned short in			 * network ordering.			 */			np->np_mountd = htons((u_short) port);			np->np_mountd_inval = FALSE;			np->np_error = 0;		} else {#ifdef DEBUG			dlog("Error fetching port for mountd on %s", fs->fs_host);#endif /* DEBUG */			/*			 * Almost certainly no mountd running on remote host			 */			np->np_error = error ? error : ETIMEDOUT;		}		if (fs->fs_flags & FSF_WANT)			wakeup_srvr(fs);	} else if (done) {#ifdef DEBUG		dlog("Got portmap for old port request");#endif /* DEBUG */	} else {#ifdef DEBUG		dlog("portmap request timed out");#endif /* DEBUG */	}}/* * Obtain portmap information */static int call_portmap P((fserver *fs, AUTH *auth, unsigned long prog, unsigned long vers, unsigned long prot));static int call_portmap(fs, auth, prog, vers, prot)fserver *fs;AUTH *auth;unsigned long prog, vers, prot;{	struct rpc_msg pmap_msg;	int len;	char iobuf[UDPMSGSIZE];	int error;	struct pmap pmap;	rpc_msg_init(&pmap_msg, PMAPPROG, PMAPVERS, (unsigned long) 0);	pmap.pm_prog = prog;	pmap.pm_vers = vers;	pmap.pm_prot = prot;	pmap.pm_port = 0;	len = make_rpc_packet(iobuf, sizeof(iobuf), PMAPPROC_GETPORT,			&pmap_msg, (voidp) &pmap, xdr_pmap, auth);	if (len > 0) {		struct sockaddr_in sin;		bzero((voidp) &sin, sizeof(sin));		sin = *fs->fs_ip;		sin.sin_port = htons(PMAPPORT);		error = fwd_packet(RPC_XID_PORTMAP, (voidp) iobuf, len,				&sin, &sin, (voidp) fs, got_portmap);	} else {		error = -len;	}	return error;}static void nfs_keepalive P((fserver*));static void recompute_portmap P((fserver *fs));static void recompute_portmap(fs)fserver *fs;{					int error;	if (nfs_auth)		error = 0;	else		error = make_nfs_auth();	if (error) {		nfs_private *np = (nfs_private *) fs->fs_private;		np->np_error = error;	} else {		call_portmap(fs, nfs_auth, MOUNTPROG,			MOUNTVERS, (unsigned long) IPPROTO_UDP);	}}/* * This is called when we get a reply to an RPC ping. * The value of id was taken from the nfs_private * structure when the ping was transmitted. *//*ARGSUSED*/static void nfs_pinged P((voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, voidp idv, int done));static void nfs_pinged(pkt, len, sp, tsp, idv, done)voidp pkt;int len;struct sockaddr_in *sp;struct sockaddr_in *tsp;voidp idv;int done;{	int xid = (int) idv;	fserver *fs;#ifdef DEBUG	int found_map = 0;#endif /* DEBUG */	if (!done)		return;	/*	 * For each node...	 */	ITER(fs, fserver, &nfs_srvr_list) {		nfs_private *np = (nfs_private *) fs->fs_private;		if (np->np_xid == xid) {			/*			 * Reset the ping counter.			 * Update the keepalive timer.			 * Log what happened.			 */			if (fs->fs_flags & FSF_DOWN) {				fs->fs_flags &= ~FSF_DOWN;				if (fs->fs_flags & FSF_VALID) {					srvrlog(fs, "is up");				} else {					if (np->np_ping > 1)						srvrlog(fs, "ok");#ifdef DEBUG					else						srvrlog(fs, "starts up");#endif					fs->fs_flags |= FSF_VALID;				}#ifdef notdef				/* why ??? */				if (fs->fs_flags & FSF_WANT)					wakeup_srvr(fs);#endif /* notdef */				map_flush_srvr(fs);			} else {				if (fs->fs_flags & FSF_VALID) {#ifdef DEBUG					dlog("file server %s type nfs is still up", fs->fs_host);#endif /* DEBUG */				} else {					if (np->np_ping > 1)						srvrlog(fs, "ok");					fs->fs_flags |= FSF_VALID;				}			}			/*			 * Adjust ping interval			 */			untimeout(fs->fs_cid);			fs->fs_cid = timeout(fs->fs_pinger, nfs_keepalive, (voidp) fs);			/*			 * Update ttl for this server			 */			np->np_ttl = clocktime() +				(MAX_ALLOWED_PINGS - 1) * FAST_NFS_PING + fs->fs_pinger - 1;			/*			 * New RPC xid...			 */			np->np_xid = NPXID_ALLOC();			/*			 * Failed pings is zero...			 */			np->np_ping = 0;			/*			 * Recompute portmap information if not known			 */			if (np->np_mountd_inval)				recompute_portmap(fs);#ifdef DEBUG	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -