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# $FreeBSD$ 28# 29 30# 31# /etc/autofs/include_nis_nullfs 32# 33# automountd Directory Services script for NIS 34# 35# SYNOPSIS 36# include_nis_nullfs <mapname> 37# 38# include_nis_nullfs <mapname> <key> 39# 40# DESCRIPTION 41# 42# This script provides a Directory Services map for automountd 43# based on NIS. Please see auto_master(5) for general information. 44# 45# The first form, with one argument, emits the entire named NIS map. 46# The second form, with two arguments, emits the map entry for the 47# key given in the second argument. 48# 49# This script attempts to determine the names and IP addresses 50# of the local host. Map entries matching the local host are 51# rewritten to specify nullfs mounts (instead of the default 52# NFS) to reduce access overhead in the kernel. 53# 54# If a map entry contains multiple location fields, it is not changed. 55# 56 57 58# Populate list of names and IP addrs thet mean "this host" 59# into myhostnames array 60BEGIN { 61 # 62 # Set self hostnames 63 # 64 65 "hostname -s" | getline; 66 myhostnames[$0] = 1; 67 68 "hostname -f" | getline; 69 myhostnames[$0] = 1; 70 71 myhostnames["localhost"] = 1 72 73 "hostname -f" | getline; 74 localdomain=$0 75 myhostnames["localhost."localdomain] = 1 76 77 while ("ifconfig" | getline) { 78 if ($1 == "inet") { 79 myhostnames[$2] = 1; 80 } 81 } 82 83 # debug 84# print "--- hostname list start ----" 85# for (i in myhostnames) { 86# print i 87# } 88# print "--- hostname list end ----" 89 90 if (ARGC == 2) { 91 # mapname only 92 while ("ypcat -k " ARGV[1] | getline) { 93 proc_mapline(1) 94 } 95 } 96 if (ARGC == 3) { 97 # mapname and keyname 98 while ("ypmatch " ARGV[2] " " ARGV[1] | getline) { 99 proc_mapline(0) 100 } 101 } 102 exit 0 103} 104 105function is_self(hostname) 106{ 107 if (myhostnames[hostname]) { 108 return 1 109 } 110 return 0 111} 112 113# 114# Lines are of the form [key] [-opts] location1 [... locationN] 115# 116# indicate index of key field with first positional parameter 117# 1 means keyfield is the first field 118# 0 means keyfield is not present 119# 120function proc_mapline(keyfield) 121{ 122 optionsfield = 0 123 locationfield = 0 124 locationcount = 0 125 126 for (i=keyfield+1; i <= NF; ++i) { 127 if (!optionsfield) { 128 if ($i ~ /^-/) { 129 # the first options field found on the line 130 optionsfield = i; 131 continue 132 } 133 } 134 # Assumption: location contains colon (":") 135 if (optionsfield && ($i ~ /:/) && ($i !~ /^-/)) { 136 ++locationcount 137 if (!locationfield) { 138 # the first location field found on the line 139 locationfield = i 140 } 141 } 142 } 143 144 # 145 # If location not found, do not modify. 146 # 147 # If there is more than one location, do not modify. Rationale: 148 # Options are applied to all locations. We ca not have "nullfs" 149 # for only some locations and "nfs" for others for a given 150 # map key (i.e., a line). The usual reason for multiple 151 # locations is for redundancy using replicated volumes on 152 # multiple hosts, so multiple hosts imply fstype=nfs (the 153 # FreeBSD default for automounter maps). 154 # 155 # Hypothetically there could be a map entry with multiple 156 # locations all with host parts matching "me". In that case, 157 # it would be safe to rewrite the locations and specify 158 # nullfs, but the code does not handle this case. 159 # 160 if (locationcount == 1) { 161 # 162 # We have a line with exactly one location field 163 # 164 # Assumption: location has no more than one colon (":") 165 # 166 n=split($locationfield,location,":") 167 if (is_self(location[1])) { 168 $locationfield = ":" location[2] 169 if (optionsfield) { 170 # append to existing options 171 $optionsfield = $optionsfield ",fstype=nullfs" 172 } else { 173 # sneak in ahead of location 174 $locationfield = "-fstype=nullfs " $locationfield 175 } 176 } 177 } 178 179 print 180} 181