1 /* 2 * Copyright (c) 1989 Jan-Simon Pendry 3 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Jan-Simon Pendry at Imperial College, London. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)srvr_afs.c 8.1 (Berkeley) 6/6/93 35 * $Id: srvr_afs.c,v 1.4 2003/06/02 23:36:51 millert Exp $ 36 */ 37 38 /* 39 * Automount FS server ("localhost") modeling 40 */ 41 42 #include "am.h" 43 44 extern qelem afs_srvr_list; 45 qelem afs_srvr_list = { &afs_srvr_list, &afs_srvr_list }; 46 47 static fserver *localhost; 48 49 /* 50 * Find an nfs server for the local host 51 */ 52 fserver * 53 find_afs_srvr(mntfs *mf) 54 { 55 fserver *fs = localhost; 56 57 if (!fs) { 58 fs = ALLOC(fserver); 59 fs->fs_refc = 0; 60 fs->fs_host = strdup("localhost"); 61 fs->fs_ip = 0; 62 fs->fs_cid = 0; 63 fs->fs_pinger = 0; 64 fs->fs_flags = FSF_VALID; 65 fs->fs_type = "local"; 66 fs->fs_private = 0; 67 fs->fs_prfree = 0; 68 69 ins_que(&fs->fs_q, &afs_srvr_list); 70 71 srvrlog(fs, "starts up"); 72 73 localhost = fs; 74 } 75 76 fs->fs_refc++; 77 78 return fs; 79 } 80 81 /*------------------------------------------------------------------*/ 82 /* Generic routines follow */ 83 84 /* 85 * Wakeup anything waiting for this server 86 */ 87 void 88 wakeup_srvr(fserver *fs) 89 { 90 fs->fs_flags &= ~FSF_WANT; 91 wakeup((void *)fs); 92 } 93 94 /* 95 * Called when final ttl of server has expired 96 */ 97 static void 98 timeout_srvr(fserver *fs) 99 { 100 /* 101 * If the reference count is still zero then 102 * we are free to remove this node 103 */ 104 if (fs->fs_refc == 0) { 105 #ifdef DEBUG 106 dlog("Deleting file server %s", fs->fs_host); 107 #endif /* DEBUG */ 108 if (fs->fs_flags & FSF_WANT) 109 wakeup_srvr(fs); 110 111 /* 112 * Remove from queue. 113 */ 114 rem_que(&fs->fs_q); 115 /* 116 * (Possibly) call the private free routine. 117 */ 118 if (fs->fs_private && fs->fs_prfree) 119 (*fs->fs_prfree)(fs->fs_private); 120 121 /* 122 * Free the net address 123 */ 124 if (fs->fs_ip) 125 free((void *)fs->fs_ip); 126 127 /* 128 * Free the host name. 129 */ 130 free((void *)fs->fs_host); 131 132 /* 133 * Discard the fserver object. 134 */ 135 free((void *)fs); 136 } 137 } 138 139 /* 140 * Free a file server 141 */ 142 void 143 free_srvr(fserver *fs) 144 { 145 if (--fs->fs_refc == 0) { 146 /* 147 * The reference count is now zero, 148 * so arrange for this node to be 149 * removed in AM_TTL seconds if no 150 * other mntfs is referencing it. 151 */ 152 int ttl = (fs->fs_flags & (FSF_DOWN|FSF_ERROR)) ? 19 : AM_TTL; 153 #ifdef DEBUG 154 dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl); 155 #endif /* DEBUG */ 156 if (fs->fs_cid) { 157 untimeout(fs->fs_cid); 158 /* 159 * Turn off pinging - XXX 160 */ 161 fs->fs_flags &= ~FSF_PINGING; 162 } 163 /* 164 * Keep structure lying around for a while 165 */ 166 fs->fs_cid = timeout(ttl, timeout_srvr, (void *)fs); 167 /* 168 * Mark the fileserver down and invalid again 169 */ 170 fs->fs_flags &= ~FSF_VALID; 171 fs->fs_flags |= FSF_DOWN; 172 } 173 } 174 175 /* 176 * Make a duplicate fserver reference 177 */ 178 fserver * 179 dup_srvr(fserver *fs) 180 { 181 fs->fs_refc++; 182 return fs; 183 } 184 185 /* 186 * Log state change 187 */ 188 void srvrlog(fserver *fs, char *state) 189 { 190 plog(XLOG_INFO, "file server %s type %s %s", fs->fs_host, fs->fs_type, state); 191 } 192