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 # $NetBSD: include_nis_nullfs,v 1.1 2018/01/09 03:31:14 christos Exp $ 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 60 BEGIN { 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 105 function 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 # 120 function 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