138494Sobrien/* 2310490Scy * Copyright (c) 1997-2014 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. 19310490Scy * 3. Neither the name of the University nor the names of its contributors 2038494Sobrien * may be used to endorse or promote products derived from this software 2138494Sobrien * without specific prior written permission. 2238494Sobrien * 2338494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2438494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2538494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2638494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2738494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2838494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2938494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3038494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3138494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3238494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3338494Sobrien * SUCH DAMAGE. 3438494Sobrien * 3538494Sobrien * 36174294Sobrien * File: am-utils/amd/srvr_amfs_auto.c 3738494Sobrien * 3838494Sobrien */ 3938494Sobrien 4038494Sobrien/* 4138494Sobrien * Automount FS server ("localhost") modeling 4238494Sobrien */ 4338494Sobrien 4438494Sobrien#ifdef HAVE_CONFIG_H 4538494Sobrien# include <config.h> 4638494Sobrien#endif /* HAVE_CONFIG_H */ 4738494Sobrien#include <am_defs.h> 4838494Sobrien#include <amd.h> 4938494Sobrien 5038494Sobrien/* globals */ 5138494Sobrien 5238494Sobrien/* statics */ 53174294Sobrienstatic qelem amfs_auto_srvr_list = {&amfs_auto_srvr_list, &amfs_auto_srvr_list}; 5438494Sobrienstatic fserver *localhost; 5538494Sobrien 5638494Sobrien 5738494Sobrien/* 5838494Sobrien * Find an nfs server for the local host 5938494Sobrien */ 6038494Sobrienfserver * 61174294Sobrienamfs_generic_find_srvr(mntfs *mf) 6238494Sobrien{ 6338494Sobrien fserver *fs = localhost; 6438494Sobrien 6538494Sobrien if (!fs) { 6638494Sobrien fs = ALLOC(struct fserver); 6738494Sobrien fs->fs_refc = 0; 68310490Scy fs->fs_host = xstrdup("localhost"); 69310490Scy fs->fs_ip = NULL; 7038494Sobrien fs->fs_cid = 0; 71174294Sobrien fs->fs_pinger = AM_PINGER; 72174294Sobrien fs->fs_flags = FSF_VALID | FSF_PING_UNINIT; 7338494Sobrien fs->fs_type = "local"; 74310490Scy fs->fs_private = NULL; 75310490Scy fs->fs_prfree = NULL; 7638494Sobrien 7738494Sobrien ins_que(&fs->fs_q, &amfs_auto_srvr_list); 7838494Sobrien 7938494Sobrien srvrlog(fs, "starts up"); 8038494Sobrien 8138494Sobrien localhost = fs; 8238494Sobrien } 8338494Sobrien fs->fs_refc++; 8438494Sobrien 8538494Sobrien return fs; 8638494Sobrien} 8738494Sobrien 8838494Sobrien 8938494Sobrien/***************************************************************************** 9038494Sobrien *** GENERIC ROUTINES FOLLOW 9138494Sobrien *****************************************************************************/ 9238494Sobrien 9338494Sobrien/* 9438494Sobrien * Wakeup anything waiting for this server 9538494Sobrien */ 9638494Sobrienvoid 9738494Sobrienwakeup_srvr(fserver *fs) 9838494Sobrien{ 9938494Sobrien fs->fs_flags &= ~FSF_WANT; 10038494Sobrien wakeup((voidp) fs); 10138494Sobrien} 10238494Sobrien 10338494Sobrien 10438494Sobrien/* 10538494Sobrien * Called when final ttl of server has expired 10638494Sobrien */ 10738494Sobrienstatic void 10838494Sobrientimeout_srvr(voidp v) 10938494Sobrien{ 11038494Sobrien fserver *fs = v; 11138494Sobrien 11238494Sobrien /* 11338494Sobrien * If the reference count is still zero then 11438494Sobrien * we are free to remove this node 11538494Sobrien */ 11638494Sobrien if (fs->fs_refc == 0) { 11738494Sobrien dlog("Deleting file server %s", fs->fs_host); 11838494Sobrien if (fs->fs_flags & FSF_WANT) 11938494Sobrien wakeup_srvr(fs); 12038494Sobrien 12138494Sobrien /* 12238494Sobrien * Remove from queue. 12338494Sobrien */ 12438494Sobrien rem_que(&fs->fs_q); 12538494Sobrien /* 12638494Sobrien * (Possibly) call the private free routine. 12738494Sobrien */ 12838494Sobrien if (fs->fs_private && fs->fs_prfree) 12938494Sobrien (*fs->fs_prfree) (fs->fs_private); 13038494Sobrien 13138494Sobrien /* 13238494Sobrien * Free the net address 13338494Sobrien */ 134310490Scy XFREE(fs->fs_ip); 13538494Sobrien 13638494Sobrien /* 13738494Sobrien * Free the host name. 13838494Sobrien */ 13938494Sobrien XFREE(fs->fs_host); 14038494Sobrien 14138494Sobrien /* 14238494Sobrien * Discard the fserver object. 14338494Sobrien */ 14438494Sobrien XFREE(fs); 14538494Sobrien } 14638494Sobrien} 14738494Sobrien 14838494Sobrien 14938494Sobrien/* 15038494Sobrien * Free a file server 15138494Sobrien */ 15238494Sobrienvoid 15338494Sobrienfree_srvr(fserver *fs) 15438494Sobrien{ 15538494Sobrien if (--fs->fs_refc == 0) { 15638494Sobrien /* 15738494Sobrien * The reference count is now zero, 15838494Sobrien * so arrange for this node to be 15938494Sobrien * removed in AM_TTL seconds if no 16038494Sobrien * other mntfs is referencing it. 16138494Sobrien */ 162174294Sobrien int ttl = (FSRV_ERROR(fs) || FSRV_ISDOWN(fs)) ? 19 : AM_TTL; 16338494Sobrien 16438494Sobrien dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl); 16538494Sobrien if (fs->fs_cid) { 16638494Sobrien untimeout(fs->fs_cid); 16738494Sobrien /* 16838494Sobrien * Turn off pinging - XXX 16938494Sobrien */ 17038494Sobrien fs->fs_flags &= ~FSF_PINGING; 17138494Sobrien } 17238494Sobrien 17338494Sobrien /* 17438494Sobrien * Keep structure lying around for a while 17538494Sobrien */ 17638494Sobrien fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs); 17738494Sobrien 17838494Sobrien /* 17938494Sobrien * Mark the fileserver down and invalid again 18038494Sobrien */ 18138494Sobrien fs->fs_flags &= ~FSF_VALID; 18238494Sobrien fs->fs_flags |= FSF_DOWN; 18338494Sobrien } 18438494Sobrien} 18538494Sobrien 18638494Sobrien 18738494Sobrien/* 18838494Sobrien * Make a duplicate fserver reference 18938494Sobrien */ 19038494Sobrienfserver * 19138494Sobriendup_srvr(fserver *fs) 19238494Sobrien{ 19338494Sobrien fs->fs_refc++; 19438494Sobrien return fs; 19538494Sobrien} 19638494Sobrien 19738494Sobrien 19838494Sobrien/* 19938494Sobrien * Log state change 20038494Sobrien */ 20182794Sobrienvoid 20282794Sobriensrvrlog(fserver *fs, char *state) 20338494Sobrien{ 20482794Sobrien plog(XLOG_INFO, "file server %s, type %s, state %s", fs->fs_host, fs->fs_type, state); 20538494Sobrien} 206