1398a5aebSmckusick /*
2398a5aebSmckusick * Copyright (c) 1989 Jan-Simon Pendry
3398a5aebSmckusick * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
4*4092c5ccSbostic * Copyright (c) 1989, 1993
5*4092c5ccSbostic * The Regents of the University of California. All rights reserved.
6398a5aebSmckusick *
7398a5aebSmckusick * This code is derived from software contributed to Berkeley by
8398a5aebSmckusick * Jan-Simon Pendry at Imperial College, London.
9398a5aebSmckusick *
10398a5aebSmckusick * %sccs.include.redist.c%
11398a5aebSmckusick *
12*4092c5ccSbostic * @(#)srvr_afs.c 8.1 (Berkeley) 06/06/93
13c626267eSpendry *
14cc0207dcSpendry * $Id: srvr_afs.c,v 5.2.2.1 1992/02/09 15:09:05 jsp beta $
15c626267eSpendry *
16398a5aebSmckusick */
17398a5aebSmckusick
18398a5aebSmckusick /*
19398a5aebSmckusick * Automount FS server ("localhost") modeling
20398a5aebSmckusick */
21398a5aebSmckusick
22398a5aebSmckusick #include "am.h"
23398a5aebSmckusick
24398a5aebSmckusick extern qelem afs_srvr_list;
25398a5aebSmckusick qelem afs_srvr_list = { &afs_srvr_list, &afs_srvr_list };
26398a5aebSmckusick
27398a5aebSmckusick static fserver *localhost;
28398a5aebSmckusick
29398a5aebSmckusick /*
30398a5aebSmckusick * Find an nfs server for the local host
31398a5aebSmckusick */
32398a5aebSmckusick fserver *find_afs_srvr P((mntfs *));
find_afs_srvr(mf)33398a5aebSmckusick fserver *find_afs_srvr(mf)
34398a5aebSmckusick mntfs *mf;
35398a5aebSmckusick {
36398a5aebSmckusick fserver *fs = localhost;
37398a5aebSmckusick
38398a5aebSmckusick if (!fs) {
39398a5aebSmckusick fs = ALLOC(fserver);
40398a5aebSmckusick fs->fs_refc = 0;
41398a5aebSmckusick fs->fs_host = strdup("localhost");
42398a5aebSmckusick fs->fs_ip = 0;
43398a5aebSmckusick fs->fs_cid = 0;
44398a5aebSmckusick fs->fs_pinger = 0;
45398a5aebSmckusick fs->fs_flags = FSF_VALID;
46398a5aebSmckusick fs->fs_type = "local";
47398a5aebSmckusick fs->fs_private = 0;
48398a5aebSmckusick fs->fs_prfree = 0;
49398a5aebSmckusick
50398a5aebSmckusick ins_que(&fs->fs_q, &afs_srvr_list);
51398a5aebSmckusick
52398a5aebSmckusick srvrlog(fs, "starts up");
53398a5aebSmckusick
54398a5aebSmckusick localhost = fs;
55398a5aebSmckusick }
56398a5aebSmckusick
57398a5aebSmckusick fs->fs_refc++;
58398a5aebSmckusick
59398a5aebSmckusick return fs;
60398a5aebSmckusick }
61398a5aebSmckusick
62398a5aebSmckusick /*------------------------------------------------------------------*/
63398a5aebSmckusick /* Generic routines follow */
64398a5aebSmckusick
65398a5aebSmckusick /*
66398a5aebSmckusick * Wakeup anything waiting for this server
67398a5aebSmckusick */
68398a5aebSmckusick void wakeup_srvr P((fserver *fs));
wakeup_srvr(fs)69398a5aebSmckusick void wakeup_srvr(fs)
70398a5aebSmckusick fserver *fs;
71398a5aebSmckusick {
72398a5aebSmckusick fs->fs_flags &= ~FSF_WANT;
73398a5aebSmckusick wakeup((voidp) fs);
74398a5aebSmckusick }
75398a5aebSmckusick
76398a5aebSmckusick /*
77398a5aebSmckusick * Called when final ttl of server has expired
78398a5aebSmckusick */
79398a5aebSmckusick static void timeout_srvr P((fserver *fs));
timeout_srvr(fs)80398a5aebSmckusick static void timeout_srvr(fs)
81398a5aebSmckusick fserver *fs;
82398a5aebSmckusick {
83398a5aebSmckusick /*
84398a5aebSmckusick * If the reference count is still zero then
85398a5aebSmckusick * we are free to remove this node
86398a5aebSmckusick */
87398a5aebSmckusick if (fs->fs_refc == 0) {
88398a5aebSmckusick #ifdef DEBUG
89398a5aebSmckusick dlog("Deleting file server %s", fs->fs_host);
90398a5aebSmckusick #endif /* DEBUG */
91398a5aebSmckusick if (fs->fs_flags & FSF_WANT)
92398a5aebSmckusick wakeup_srvr(fs);
93398a5aebSmckusick
94398a5aebSmckusick /*
95398a5aebSmckusick * Remove from queue.
96398a5aebSmckusick */
97398a5aebSmckusick rem_que(&fs->fs_q);
98398a5aebSmckusick /*
99398a5aebSmckusick * (Possibly) call the private free routine.
100398a5aebSmckusick */
101398a5aebSmckusick if (fs->fs_private && fs->fs_prfree)
102398a5aebSmckusick (*fs->fs_prfree)(fs->fs_private);
103398a5aebSmckusick
104398a5aebSmckusick /*
105398a5aebSmckusick * Free the net address
106398a5aebSmckusick */
107398a5aebSmckusick if (fs->fs_ip)
108398a5aebSmckusick free((voidp) fs->fs_ip);
109398a5aebSmckusick
110398a5aebSmckusick /*
111398a5aebSmckusick * Free the host name.
112398a5aebSmckusick */
113398a5aebSmckusick free((voidp) fs->fs_host);
114398a5aebSmckusick
115398a5aebSmckusick /*
116398a5aebSmckusick * Discard the fserver object.
117398a5aebSmckusick */
118398a5aebSmckusick free((voidp) fs);
119398a5aebSmckusick }
120398a5aebSmckusick }
121398a5aebSmckusick
122398a5aebSmckusick /*
123398a5aebSmckusick * Free a file server
124398a5aebSmckusick */
125398a5aebSmckusick void free_srvr P((fserver *fs));
free_srvr(fs)126398a5aebSmckusick void free_srvr(fs)
127398a5aebSmckusick fserver *fs;
128398a5aebSmckusick {
129398a5aebSmckusick if (--fs->fs_refc == 0) {
130398a5aebSmckusick /*
131398a5aebSmckusick * The reference count is now zero,
132398a5aebSmckusick * so arrange for this node to be
133398a5aebSmckusick * removed in AM_TTL seconds if no
134398a5aebSmckusick * other mntfs is referencing it.
135398a5aebSmckusick */
136398a5aebSmckusick int ttl = (fs->fs_flags & (FSF_DOWN|FSF_ERROR)) ? 19 : AM_TTL;
137398a5aebSmckusick #ifdef DEBUG
138398a5aebSmckusick dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl);
139398a5aebSmckusick #endif /* DEBUG */
140398a5aebSmckusick if (fs->fs_cid) {
141398a5aebSmckusick untimeout(fs->fs_cid);
142398a5aebSmckusick /*
143398a5aebSmckusick * Turn off pinging - XXX
144398a5aebSmckusick */
145398a5aebSmckusick fs->fs_flags &= ~FSF_PINGING;
146398a5aebSmckusick }
147398a5aebSmckusick /*
148398a5aebSmckusick * Keep structure lying around for a while
149398a5aebSmckusick */
150398a5aebSmckusick fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs);
151398a5aebSmckusick /*
152398a5aebSmckusick * Mark the fileserver down and invalid again
153398a5aebSmckusick */
154398a5aebSmckusick fs->fs_flags &= ~FSF_VALID;
155398a5aebSmckusick fs->fs_flags |= FSF_DOWN;
156398a5aebSmckusick }
157398a5aebSmckusick }
158398a5aebSmckusick
159398a5aebSmckusick /*
160398a5aebSmckusick * Make a duplicate fserver reference
161398a5aebSmckusick */
162398a5aebSmckusick fserver *dup_srvr P((fserver *fs));
dup_srvr(fs)163398a5aebSmckusick fserver *dup_srvr(fs)
164398a5aebSmckusick fserver *fs;
165398a5aebSmckusick {
166398a5aebSmckusick fs->fs_refc++;
167398a5aebSmckusick return fs;
168398a5aebSmckusick }
169398a5aebSmckusick
170398a5aebSmckusick /*
171398a5aebSmckusick * Log state change
172398a5aebSmckusick */
173398a5aebSmckusick void srvrlog P((fserver *fs, char *state));
srvrlog(fs,state)174398a5aebSmckusick void srvrlog(fs, state)
175398a5aebSmckusick fserver *fs;
176398a5aebSmckusick char *state;
177398a5aebSmckusick {
178398a5aebSmckusick plog(XLOG_INFO, "file server %s type %s %s", fs->fs_host, fs->fs_type, state);
179398a5aebSmckusick }
180