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

📄 srvr_nfs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			found_map++;#endif /* DEBUG */			break;		}	}#ifdef DEBUG	if (found_map == 0)		dlog("Spurious ping packet");#endif /* DEBUG */}/* * Called when no ping-reply received */static void nfs_timed_out P((fserver *fs));static void nfs_timed_out(fs)fserver *fs;{	nfs_private *np = (nfs_private *) fs->fs_private;	/*	 * Another ping has failed	 */	np->np_ping++;	/*	 * Not known to be up any longer	 */	if (FSRV_ISUP(fs)) {		fs->fs_flags &= ~FSF_VALID;		if (np->np_ping > 1)			srvrlog(fs, "not responding");	}	/*	 * If ttl has expired then guess that it is dead	 */	if (np->np_ttl < clocktime()) {		int oflags = fs->fs_flags;		if ((fs->fs_flags & FSF_DOWN) == 0) {			/*			 * Server was up, but is now down.			 */			srvrlog(fs, "is down");			fs->fs_flags |= FSF_DOWN|FSF_VALID;			/*			 * Since the server is down, the portmap			 * information may now be wrong, so it			 * must be flushed from the local cache			 */			flush_nfs_fhandle_cache(fs);			np->np_error = -1;#ifdef notdef			/*			 * Pretend just one ping has failed now			 */			np->np_ping = 1;#endif		} else {			/*			 * Known to be down			 */#ifdef DEBUG			if ((fs->fs_flags & FSF_VALID) == 0)				srvrlog(fs, "starts down");#endif			fs->fs_flags |= FSF_VALID;		}		if (oflags != fs->fs_flags && (fs->fs_flags & FSF_WANT))			wakeup_srvr(fs);	} else {#ifdef DEBUG		if (np->np_ping > 1)			dlog("%d pings to %s failed - at most %d allowed", np->np_ping, fs->fs_host, MAX_ALLOWED_PINGS);#endif /* DEBUG */	}	/*	 * Run keepalive again	 */	nfs_keepalive(fs);}/* * Keep track of whether a server is alive */static void nfs_keepalive P((fserver *fs));static void nfs_keepalive(fs)fserver *fs;{	int error;	nfs_private *np = (nfs_private *) fs->fs_private;	int fstimeo = -1;	/*	 * Send an NFS ping to this node	 */	if (ping_len == 0)		start_ping();	/*	 * Queue the packet...	 */	error = fwd_packet(MK_RPC_XID(RPC_XID_NFSPING, np->np_xid), (voidp) ping_buf,		ping_len, fs->fs_ip, (struct sockaddr_in *) 0, (voidp) np->np_xid, nfs_pinged);	/*	 * See if a hard error occured	 */	switch (error) {	case ENETDOWN:	case ENETUNREACH:	case EHOSTDOWN:	case EHOSTUNREACH:		np->np_ping = MAX_ALLOWED_PINGS;	/* immediately down */		np->np_ttl = (time_t) 0;		/*		 * This causes an immediate call to nfs_timed_out		 * whenever the server was thought to be up.		 * See +++ below.		 */		fstimeo = 0;		break;	case 0:#ifdef DEBUG		dlog("Sent NFS ping to %s", fs->fs_host);#endif /* DEBUG */		break;	}#ifdef DEBUG	/*dlog("keepalive, ping = %d", np->np_ping);*/#endif /* DEBUG */	/*	 * Back off the ping interval if we are not getting replies and	 * the remote system is know to be down.	 */	switch (fs->fs_flags & (FSF_DOWN|FSF_VALID)) {	case FSF_VALID:			/* Up */		if (fstimeo < 0)	/* +++ see above */			fstimeo = FAST_NFS_PING;		break;	case FSF_VALID|FSF_DOWN:	/* Down */		fstimeo = fs->fs_pinger;		break;	default:			/* Unknown */		fstimeo = FAST_NFS_PING;		break;	}#ifdef DEBUG	dlog("NFS timeout in %d seconds", fstimeo);#endif /* DEBUG */	fs->fs_cid = timeout(fstimeo, nfs_timed_out, (voidp) fs);}int nfs_srvr_port P((fserver *fs, u_short *port, voidp wchan));int nfs_srvr_port(fs, port, wchan)fserver *fs;u_short *port;voidp wchan;{	int error = -1;	if ((fs->fs_flags & FSF_VALID) == FSF_VALID) {		if ((fs->fs_flags & FSF_DOWN) == 0) {			nfs_private *np = (nfs_private *) fs->fs_private;			if (np->np_error == 0) {				*port = np->np_mountd;				error = 0;			} else {				error = np->np_error;			}			/*			 * Now go get the port mapping again in case it changed.			 * Note that it is used even if (np_mountd_inval)			 * is True.  The flag is used simply as an			 * indication that the mountd may be invalid, not			 * that it is known to be invalid.			 */			if (np->np_mountd_inval)				recompute_portmap(fs);			else				np->np_mountd_inval = TRUE;		} else {			error = EWOULDBLOCK;		}	}	if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) {		/*		 * If a wait channel is supplied, and no		 * error has yet occured, then arrange		 * that a wakeup is done on the wait channel,		 * whenever a wakeup is done on this fs node.		 * Wakeup's are done on the fs node whenever		 * it changes state - thus causing control to		 * come back here and new, better things to happen.		 */		fs->fs_flags |= FSF_WANT;		sched_task(wakeup_task, wchan, (voidp) fs);	}	return error;}static void start_nfs_pings P((fserver *fs, int pingval));static void start_nfs_pings(fs, pingval)fserver *fs;int pingval;{	if (!(fs->fs_flags & FSF_PINGING)) {		fs->fs_flags |= FSF_PINGING;		if (fs->fs_cid)			untimeout(fs->fs_cid);		if (pingval < 0) {			srvrlog(fs, "wired up");			fs->fs_flags |= FSF_VALID;			fs->fs_flags &= ~FSF_DOWN;		} else {			nfs_keepalive(fs);		}	} else {#ifdef DEBUG		dlog("Already running pings to %s", fs->fs_host);#endif /* DEBUG */	}}/* * Find an nfs server for a host. */fserver *find_nfs_srvr P((mntfs *mf));fserver *find_nfs_srvr(mf)mntfs *mf;{	fserver *fs;	struct hostent *hp = 0;	char *host = mf->mf_fo->opt_rhost;	struct sockaddr_in *ip;	nfs_private *np;	int pingval;	/*	 * Get ping interval from mount options.	 * Current only used to decide whether pings	 * are required or not.  < 0 = no pings.	 */	{ struct mntent mnt;	  mnt.mnt_opts = mf->mf_mopts;	  pingval = hasmntval(&mnt, "ping");#ifdef HAS_TCP_NFS	  /*	   * Over TCP mount, don't bother to do pings.	   * This is experimental - maybe you want to	   * do pings anyway...	   */	  if (pingval == 0 && hasmntopt(&mnt, "tcp"))		pingval = -1;#endif /* HAS_TCP_NFS */	}	/*	 * lookup host address and canonical name	 */	hp = gethostbyname(host);	/*	 * New code from Bob Harris <harris@basil-rathbone.mit.edu>	 * Use canonical name to keep track of file server	 * information.  This way aliases do not generate	 * multiple NFS pingers.  (Except when we're normalizing	 * hosts.)	 */	if (hp && !normalize_hosts) host = hp->h_name;	ITER(fs, fserver, &nfs_srvr_list) {		if (STREQ(host, fs->fs_host)) {			start_nfs_pings(fs, pingval);			fs->fs_refc++;			return fs;		}	}	/*	 * Get here if we can't find an entry	 */	if (hp) {		switch (hp->h_addrtype) {		case AF_INET:			ip = ALLOC(sockaddr_in);			bzero((voidp) ip, sizeof(*ip));			ip->sin_family = AF_INET;			bcopy((voidp) hp->h_addr, (voidp) &ip->sin_addr, sizeof(ip->sin_addr));			ip->sin_port = htons(NFS_PORT);			break;		default:			ip = 0;			break;		}	} else {		plog(XLOG_USER, "Unknown host: %s", host);		ip = 0;	}	/*	 * Allocate a new server	 */	fs = ALLOC(fserver);	fs->fs_refc = 1;	fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname");	if (normalize_hosts) host_normalize(&fs->fs_host);	fs->fs_ip = ip;	fs->fs_cid = 0;	if (ip) {		fs->fs_flags = FSF_DOWN;	/* Starts off down */	} else {		fs->fs_flags = FSF_ERROR|FSF_VALID;		mf->mf_flags |= MFF_ERROR;		mf->mf_error = ENOENT;	}	fs->fs_type = "nfs";	fs->fs_pinger = AM_PINGER;	np = ALLOC(nfs_private);	bzero((voidp) np, sizeof(*np));	np->np_mountd_inval = TRUE;	np->np_xid = NPXID_ALLOC();	np->np_error = -1;	/*	 * Initially the server will be deemed dead after	 * MAX_ALLOWED_PINGS of the fast variety have failed.	 */	np->np_ttl = clocktime() + MAX_ALLOWED_PINGS * FAST_NFS_PING - 1;	fs->fs_private = (voidp) np;	fs->fs_prfree = (void (*)()) free;	if (!(fs->fs_flags & FSF_ERROR)) {		/*		 * Start of keepalive timer		 */		start_nfs_pings(fs, pingval);	}	/*	 * Add to list of servers	 */	ins_que(&fs->fs_q, &nfs_srvr_list);	return fs;}

⌨️ 快捷键说明

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