138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/amd/srvr_amfs_auto.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien/* 4538494Sobrien * Automount FS server ("localhost") modeling 4638494Sobrien */ 4738494Sobrien 4838494Sobrien#ifdef HAVE_CONFIG_H 4938494Sobrien# include <config.h> 5038494Sobrien#endif /* HAVE_CONFIG_H */ 5138494Sobrien#include <am_defs.h> 5238494Sobrien#include <amd.h> 5338494Sobrien 5438494Sobrien/* globals */ 5538494Sobrien 5638494Sobrien/* statics */ 57174294Sobrienstatic qelem amfs_auto_srvr_list = {&amfs_auto_srvr_list, &amfs_auto_srvr_list}; 5838494Sobrienstatic fserver *localhost; 5938494Sobrien 6038494Sobrien 6138494Sobrien/* 6238494Sobrien * Find an nfs server for the local host 6338494Sobrien */ 6438494Sobrienfserver * 65174294Sobrienamfs_generic_find_srvr(mntfs *mf) 6638494Sobrien{ 6738494Sobrien fserver *fs = localhost; 6838494Sobrien 6938494Sobrien if (!fs) { 7038494Sobrien fs = ALLOC(struct fserver); 7138494Sobrien fs->fs_refc = 0; 7238494Sobrien fs->fs_host = strdup("localhost"); 7338494Sobrien fs->fs_ip = 0; 7438494Sobrien fs->fs_cid = 0; 75174294Sobrien fs->fs_pinger = AM_PINGER; 76174294Sobrien fs->fs_flags = FSF_VALID | FSF_PING_UNINIT; 7738494Sobrien fs->fs_type = "local"; 7838494Sobrien fs->fs_private = 0; 7938494Sobrien fs->fs_prfree = 0; 8038494Sobrien 8138494Sobrien ins_que(&fs->fs_q, &amfs_auto_srvr_list); 8238494Sobrien 8338494Sobrien srvrlog(fs, "starts up"); 8438494Sobrien 8538494Sobrien localhost = fs; 8638494Sobrien } 8738494Sobrien fs->fs_refc++; 8838494Sobrien 8938494Sobrien return fs; 9038494Sobrien} 9138494Sobrien 9238494Sobrien 9338494Sobrien/***************************************************************************** 9438494Sobrien *** GENERIC ROUTINES FOLLOW 9538494Sobrien *****************************************************************************/ 9638494Sobrien 9738494Sobrien/* 9838494Sobrien * Wakeup anything waiting for this server 9938494Sobrien */ 10038494Sobrienvoid 10138494Sobrienwakeup_srvr(fserver *fs) 10238494Sobrien{ 10338494Sobrien fs->fs_flags &= ~FSF_WANT; 10438494Sobrien wakeup((voidp) fs); 10538494Sobrien} 10638494Sobrien 10738494Sobrien 10838494Sobrien/* 10938494Sobrien * Called when final ttl of server has expired 11038494Sobrien */ 11138494Sobrienstatic void 11238494Sobrientimeout_srvr(voidp v) 11338494Sobrien{ 11438494Sobrien fserver *fs = v; 11538494Sobrien 11638494Sobrien /* 11738494Sobrien * If the reference count is still zero then 11838494Sobrien * we are free to remove this node 11938494Sobrien */ 12038494Sobrien if (fs->fs_refc == 0) { 12138494Sobrien dlog("Deleting file server %s", fs->fs_host); 12238494Sobrien if (fs->fs_flags & FSF_WANT) 12338494Sobrien wakeup_srvr(fs); 12438494Sobrien 12538494Sobrien /* 12638494Sobrien * Remove from queue. 12738494Sobrien */ 12838494Sobrien rem_que(&fs->fs_q); 12938494Sobrien /* 13038494Sobrien * (Possibly) call the private free routine. 13138494Sobrien */ 13238494Sobrien if (fs->fs_private && fs->fs_prfree) 13338494Sobrien (*fs->fs_prfree) (fs->fs_private); 13438494Sobrien 13538494Sobrien /* 13638494Sobrien * Free the net address 13738494Sobrien */ 13838494Sobrien if (fs->fs_ip) 13938494Sobrien XFREE(fs->fs_ip); 14038494Sobrien 14138494Sobrien /* 14238494Sobrien * Free the host name. 14338494Sobrien */ 14438494Sobrien XFREE(fs->fs_host); 14538494Sobrien 14638494Sobrien /* 14738494Sobrien * Discard the fserver object. 14838494Sobrien */ 14938494Sobrien XFREE(fs); 15038494Sobrien } 15138494Sobrien} 15238494Sobrien 15338494Sobrien 15438494Sobrien/* 15538494Sobrien * Free a file server 15638494Sobrien */ 15738494Sobrienvoid 15838494Sobrienfree_srvr(fserver *fs) 15938494Sobrien{ 16038494Sobrien if (--fs->fs_refc == 0) { 16138494Sobrien /* 16238494Sobrien * The reference count is now zero, 16338494Sobrien * so arrange for this node to be 16438494Sobrien * removed in AM_TTL seconds if no 16538494Sobrien * other mntfs is referencing it. 16638494Sobrien */ 167174294Sobrien int ttl = (FSRV_ERROR(fs) || FSRV_ISDOWN(fs)) ? 19 : AM_TTL; 16838494Sobrien 16938494Sobrien dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl); 17038494Sobrien if (fs->fs_cid) { 17138494Sobrien untimeout(fs->fs_cid); 17238494Sobrien /* 17338494Sobrien * Turn off pinging - XXX 17438494Sobrien */ 17538494Sobrien fs->fs_flags &= ~FSF_PINGING; 17638494Sobrien } 17738494Sobrien 17838494Sobrien /* 17938494Sobrien * Keep structure lying around for a while 18038494Sobrien */ 18138494Sobrien fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs); 18238494Sobrien 18338494Sobrien /* 18438494Sobrien * Mark the fileserver down and invalid again 18538494Sobrien */ 18638494Sobrien fs->fs_flags &= ~FSF_VALID; 18738494Sobrien fs->fs_flags |= FSF_DOWN; 18838494Sobrien } 18938494Sobrien} 19038494Sobrien 19138494Sobrien 19238494Sobrien/* 19338494Sobrien * Make a duplicate fserver reference 19438494Sobrien */ 19538494Sobrienfserver * 19638494Sobriendup_srvr(fserver *fs) 19738494Sobrien{ 19838494Sobrien fs->fs_refc++; 19938494Sobrien return fs; 20038494Sobrien} 20138494Sobrien 20238494Sobrien 20338494Sobrien/* 20438494Sobrien * Log state change 20538494Sobrien */ 20682794Sobrienvoid 20782794Sobriensrvrlog(fserver *fs, char *state) 20838494Sobrien{ 20982794Sobrien plog(XLOG_INFO, "file server %s, type %s, state %s", fs->fs_host, fs->fs_type, state); 21038494Sobrien} 211