📄 srvr_nfs.c
字号:
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 + -