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