#!/usr/bin/awk -f #- # Copyright (c) 2017 G. Paul Ziemba # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $NetBSD: include_nis_nullfs,v 1.1 2018/01/09 03:31:14 christos Exp $ # # # /etc/autofs/include_nis_nullfs # # automountd Directory Services script for NIS # # SYNOPSIS # include_nis_nullfs # # include_nis_nullfs # # DESCRIPTION # # This script provides a Directory Services map for automountd # based on NIS. Please see auto_master(5) for general information. # # The first form, with one argument, emits the entire named NIS map. # The second form, with two arguments, emits the map entry for the # key given in the second argument. # # This script attempts to determine the names and IP addresses # of the local host. Map entries matching the local host are # rewritten to specify nullfs mounts (instead of the default # NFS) to reduce access overhead in the kernel. # # If a map entry contains multiple location fields, it is not changed. # # Populate list of names and IP addrs thet mean "this host" # into myhostnames array BEGIN { # # Set self hostnames # "hostname -s" | getline; myhostnames[$0] = 1; "hostname -f" | getline; myhostnames[$0] = 1; myhostnames["localhost"] = 1 "hostname -f" | getline; localdomain=$0 myhostnames["localhost."localdomain] = 1 while ("ifconfig" | getline) { if ($1 == "inet") { myhostnames[$2] = 1; } } # debug # print "--- hostname list start ----" # for (i in myhostnames) { # print i # } # print "--- hostname list end ----" if (ARGC == 2) { # mapname only while ("ypcat -k " ARGV[1] | getline) { proc_mapline(1) } } if (ARGC == 3) { # mapname and keyname while ("ypmatch " ARGV[2] " " ARGV[1] | getline) { proc_mapline(0) } } exit 0 } function is_self(hostname) { if (myhostnames[hostname]) { return 1 } return 0 } # # Lines are of the form [key] [-opts] location1 [... locationN] # # indicate index of key field with first positional parameter # 1 means keyfield is the first field # 0 means keyfield is not present # function proc_mapline(keyfield) { optionsfield = 0 locationfield = 0 locationcount = 0 for (i=keyfield+1; i <= NF; ++i) { if (!optionsfield) { if ($i ~ /^-/) { # the first options field found on the line optionsfield = i; continue } } # Assumption: location contains colon (":") if (optionsfield && ($i ~ /:/) && ($i !~ /^-/)) { ++locationcount if (!locationfield) { # the first location field found on the line locationfield = i } } } # # If location not found, do not modify. # # If there is more than one location, do not modify. Rationale: # Options are applied to all locations. We ca not have "nullfs" # for only some locations and "nfs" for others for a given # map key (i.e., a line). The usual reason for multiple # locations is for redundancy using replicated volumes on # multiple hosts, so multiple hosts imply fstype=nfs (the # FreeBSD default for automounter maps). # # Hypothetically there could be a map entry with multiple # locations all with host parts matching "me". In that case, # it would be safe to rewrite the locations and specify # nullfs, but the code does not handle this case. # if (locationcount == 1) { # # We have a line with exactly one location field # # Assumption: location has no more than one colon (":") # n=split($locationfield,location,":") if (is_self(location[1])) { $locationfield = ":" location[2] if (optionsfield) { # append to existing options $optionsfield = $optionsfield ",fstype=nullfs" } else { # sneak in ahead of location $locationfield = "-fstype=nullfs " $locationfield } } } print }