1#!/bin/sh 2## 3# Copyright 2002-2014 Apple Inc. 4# 5# This script configures NetBoot 6## 7 8. /etc/rc.common 9 10# 11# Define: NETBOOT_SHADOW 12# Purpose: 13# To change the behavior of the system when choosing a netboot shadow 14# to use. 15# Values: 16# -NETWORK- Try to use the network for the shadow file, if 17# that fails, use the local drive 18# -NETWORK_ONLY- Only use the network, fail if not available 19# -LOCAL- Use the local drive for the shadow file, if that 20# fails, use the network 21# -LOCAL_ONLY- Only use the local drive for the shadow, fail if 22# not available 23 24NETBOOT_MOUNT=/var/netboot 25NETBOOT_SHADOW=${NETBOOT_SHADOW:-NETWORK-} 26LOCAL_NETBOOT_DIR=private/var/run/com.apple.NetBootX 27 28Failed() 29{ 30 echo rc.netboot: $1 31 echo rc.netboot: $1 > /dev/console 32 sleep 5 33 exit 1 34} 35 36common_start() 37{ 38 netboot_dir=$1 39 netboot_shadow=$2 40 if [ "${netboot_dir}" = "" ] ; then 41 Failed "netboot_dir is empty" 42 fi 43 if [ "${netboot_shadow}" = "" ] ; then 44 Failed "netboot_shadow is empty" 45 fi 46 netboot_shadow="${netboot_dir}/${netboot_shadow}" 47 if ! mkdir -p "${netboot_dir}" ; then 48 Failed "create ${netboot_dir} failed" 49 fi 50 chmod 700 "${netboot_dir}" 51 mount -u -o ro / 52 root_device=$(mount | sed -n 's:/dev/\(.*\) on / .*:\1:p') 53 case "${root_device}" in 54 vn*) 55 if ! touch "${netboot_shadow}" ; then 56 Failed "create ${netboot_shadow} failed" 57 fi 58 chmod 600 "${netboot_shadow}" 59 if ! /usr/libexec/vndevice shadow "/dev/r${root_device}" "${netboot_shadow}" ; then 60 Failed "vndevice shadow failed" 61 fi 62 ;; 63 "") 64 Failed "root device unknown" 65 ;; 66 *) 67 if ! touch "${netboot_shadow}" ; then 68 Failed "failed to create shadow ${netboot_shadow}" 69 fi 70 chmod 600 "${netboot_shadow}" 71 if ! /usr/bin/nbdst -recycle "${root_device}" "${netboot_shadow}" ; then 72 Failed "nbdst failed" 73 fi 74 ;; 75 esac 76} 77 78local_mount() 79{ 80 tries=0 81 limit=11 82 while [ $tries -lt $limit ]; do 83 tries=$(( tries + 1 )) 84 volinfo=`autodiskmount -F 2>/dev/null` 85 if [ $? -ne 0 ]; then 86 if [ $tries -lt $limit ]; then 87 echo "Waiting for local drives..." 88 echo "Waiting for local drives (retry ${tries}/$(( limit - 1 )))..." > /dev/console 89 sleep 5 90 else 91 echo "autodiskmount -F found no local drives" 92 return 1 93 fi 94 else 95 tries=$limit 96 fi 97 done 98 set ${volinfo} 99 devname=$1 100 fstype=$2 101 102 mount -t "${fstype}" -o nosuid,nodev "/dev/${devname}" "${NETBOOT_MOUNT}" 2>&1 103 if [ $? -ne 0 ]; then 104 echo "mount of ${devname} failed" 105 return 1 106 fi 107 common_start "${NETBOOT_MOUNT}/${LOCAL_NETBOOT_DIR}" shadowfile 108 return 0 109} 110 111network_mount() 112{ 113 mount_from=$(ipconfig netbootoption shadow_mount_path 2>&1) 114 if [ $? -ne 0 ]; then 115 echo "no network shadow mount path available" 116 return 1 117 fi 118 shadow_path=$(ipconfig netbootoption shadow_file_path 2>&1) 119 if [ $? -ne 0 ]; then 120 echo "no network shadow file path available" 121 return 1 122 fi 123 case "${mount_from}" in 124 afp:*) 125 fstype=afp 126 kextload -v 0 /System/Library/Filesystems/AppleShare/asp_tcp.kext 127 kextload -v 0 /System/Library/Filesystems/AppleShare/afpfs.kext 128 ;; 129 nfs:*) 130 fstype=nfs 131 mount_from=${mount_from#nfs:} 132 ;; 133 *) echo "unknown network filesystem mount from ${mount_from}" 134 return 1 135 ;; 136 esac 137 mount -t "${fstype}" -o nobrowse "${mount_from}" "${NETBOOT_MOUNT}" 138 if [ $? -ne 0 ]; then 139 echo "mount -t ${fstype} -o nobrowse ${mount_from} ${NETBOOT_MOUNT} failed" 140 return 1 141 fi 142 common_start "${NETBOOT_MOUNT}" "${shadow_path}" 143 return 0 144} 145 146do_start() 147{ 148 case "${NETBOOT_SHADOW}" in 149 -LOCAL_ONLY-) 150 err=$(local_mount) 151 if [ $? -ne 0 ]; then 152 Failed "${err}" 153 fi 154 ;; 155 -LOCAL-) 156 err=$(local_mount) 157 if [ $? -ne 0 ]; then 158 err=$(network_mount) 159 if [ $? -ne 0 ]; then 160 Failed "Could not find a local or network drive" 161 fi 162 fi 163 ;; 164 -NETWORK_ONLY-) 165 err=$(network_mount) 166 if [ $? -ne 0 ]; then 167 Failed "${err}" 168 fi 169 ;; 170 171 *) 172 err=$(network_mount) 173 if [ $? -ne 0 ]; then 174 err=$(local_mount) 175 if [ $? -ne 0 ]; then 176 Failed "Could not find a network or local drive" 177 fi 178 fi 179 ;; 180 esac 181 182} 183 184do_init() 185{ 186 # attach the shadow file to the root disk image 187 do_start 188 189 # make sure the root filesystem is clean 190 fsck -p || fsck -fy || Failed "Could not clean root filesystem" 191 192 # make it writable 193 mount -uw / 194 195 # adjust /private/var/vm to point to the writable area (if not diskless) 196 swapdir=/private/var/vm 197 mounted_from=$(mount | sed -n 's:\(.*\) on .*/var/netboot.*:\1:p') 198 case "${mounted_from}" in 199 /dev/*) 200 netboot_dir="${NETBOOT_MOUNT}/${LOCAL_NETBOOT_DIR}" 201 if [ -d "${netboot_dir}" ]; then 202 rm -rf "${swapdir}" 203 ln -s "${netboot_dir}" "${swapdir}" 204 fi 205 ;; 206 *) 207 ;; 208 esac 209 210 # set the ComputerName based on what the NetBoot server told us it was 211 machine_name=$(ipconfig netbootoption machine_name 2>&1) 212 if [ $? -ne 0 ]; then 213 echo "no machine name option available" 214 else 215 echo "Setting ComputerName to ${machine_name}" 216 scutil --set ComputerName "${machine_name}" 217 fi 218} 219 220 221if [ $# -lt 1 ] ; then 222 exit 0 223fi 224 225command=$1 226 227shift 228 229case "${command}" in 230 init) 231 do_init $@ 232 ;; 233esac 234 235## 236# Exit 237## 238exit 0 239