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