1#!/usr/bin/awk -f 2#- 3# Copyright (c) 2017 G. Paul Ziemba 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# 28 29# 30# /etc/autofs/include_nis_nullfs 31# 32# automountd Directory Services script for NIS 33# 34# SYNOPSIS 35# include_nis_nullfs <mapname> 36# 37# include_nis_nullfs <mapname> <key> 38# 39# DESCRIPTION 40# 41# This script provides a Directory Services map for automountd 42# based on NIS. Please see auto_master(5) for general information. 43# 44# The first form, with one argument, emits the entire named NIS map. 45# The second form, with two arguments, emits the map entry for the 46# key given in the second argument. 47# 48# This script attempts to determine the names and IP addresses 49# of the local host. Map entries matching the local host are 50# rewritten to specify nullfs mounts (instead of the default 51# NFS) to reduce access overhead in the kernel. 52# 53# If a map entry contains multiple location fields, it is not changed. 54# 55 56 57# Populate list of names and IP addrs thet mean "this host" 58# into myhostnames array 59BEGIN { 60 # 61 # Set self hostnames 62 # 63 64 "hostname -s" | getline; 65 myhostnames[$0] = 1; 66 67 "hostname -f" | getline; 68 myhostnames[$0] = 1; 69 70 myhostnames["localhost"] = 1 71 72 "hostname -f" | getline; 73 localdomain=$0 74 myhostnames["localhost."localdomain] = 1 75 76 while ("ifconfig" | getline) { 77 if ($1 == "inet") { 78 myhostnames[$2] = 1; 79 } 80 } 81 82 # debug 83# print "--- hostname list start ----" 84# for (i in myhostnames) { 85# print i 86# } 87# print "--- hostname list end ----" 88 89 if (ARGC == 2) { 90 # mapname only 91 while ("ypcat -k " ARGV[1] | getline) { 92 proc_mapline(1) 93 } 94 } 95 if (ARGC == 3) { 96 # mapname and keyname 97 while ("ypmatch " ARGV[2] " " ARGV[1] | getline) { 98 proc_mapline(0) 99 } 100 } 101 exit 0 102} 103 104function is_self(hostname) 105{ 106 if (myhostnames[hostname]) { 107 return 1 108 } 109 return 0 110} 111 112# 113# Lines are of the form [key] [-opts] location1 [... locationN] 114# 115# indicate index of key field with first positional parameter 116# 1 means keyfield is the first field 117# 0 means keyfield is not present 118# 119function proc_mapline(keyfield) 120{ 121 optionsfield = 0 122 locationfield = 0 123 locationcount = 0 124 125 for (i=keyfield+1; i <= NF; ++i) { 126 if (!optionsfield) { 127 if ($i ~ /^-/) { 128 # the first options field found on the line 129 optionsfield = i; 130 continue 131 } 132 } 133 # Assumption: location contains colon (":") 134 if (optionsfield && ($i ~ /:/) && ($i !~ /^-/)) { 135 ++locationcount 136 if (!locationfield) { 137 # the first location field found on the line 138 locationfield = i 139 } 140 } 141 } 142 143 # 144 # If location not found, do not modify. 145 # 146 # If there is more than one location, do not modify. Rationale: 147 # Options are applied to all locations. We ca not have "nullfs" 148 # for only some locations and "nfs" for others for a given 149 # map key (i.e., a line). The usual reason for multiple 150 # locations is for redundancy using replicated volumes on 151 # multiple hosts, so multiple hosts imply fstype=nfs (the 152 # FreeBSD default for automounter maps). 153 # 154 # Hypothetically there could be a map entry with multiple 155 # locations all with host parts matching "me". In that case, 156 # it would be safe to rewrite the locations and specify 157 # nullfs, but the code does not handle this case. 158 # 159 if (locationcount == 1) { 160 # 161 # We have a line with exactly one location field 162 # 163 # Assumption: location has no more than one colon (":") 164 # 165 n=split($locationfield,location,":") 166 if (is_self(location[1])) { 167 $locationfield = ":" location[2] 168 if (optionsfield) { 169 # append to existing options 170 $optionsfield = $optionsfield ",fstype=nullfs" 171 } else { 172 # sneak in ahead of location 173 $locationfield = "-fstype=nullfs " $locationfield 174 } 175 } 176 } 177 178 print 179} 180