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