#!/bin/sh
. /etc/rc.common
NETBOOT_MOUNT=/var/netboot
NETBOOT_SHADOW=${NETBOOT_SHADOW:-NETWORK-}
Failed()
{
echo rc.netboot: $1
echo rc.netboot: $1 > /dev/console
sleep 5
exit 1
}
common_start()
{
netboot_dir=$1
netboot_shadow=$2
if [ "${netboot_dir}" = "" ] ; then
Failed "netboot_dir is empty"
fi
if [ "${netboot_shadow}" = "" ] ; then
Failed "netboot_shadow is empty"
fi
netboot_shadow="${netboot_dir}/${netboot_shadow}"
if ! mkdir -p "${netboot_dir}" ; then
Failed "create ${netboot_dir} failed"
fi
chmod 700 "${netboot_dir}"
mount -u -o ro /
root_device=$(mount | sed -n 's:/dev/\(.*\) on / .*:\1:p')
case "${root_device}" in
vn*)
if ! touch "${netboot_shadow}" ; then
Failed "create ${netboot_shadow} failed"
fi
chmod 600 "${netboot_shadow}"
if ! /usr/libexec/vndevice shadow "/dev/r${root_device}" "${netboot_shadow}" ; then
Failed "vndevice shadow failed"
fi
;;
"")
Failed "root device unknown"
;;
*)
if ! touch "${netboot_shadow}" ; then
Failed "failed to create shadow ${netboot_shadow}"
fi
chmod 600 "${netboot_shadow}"
if ! /usr/bin/nbdst -recycle "${root_device}" "${netboot_shadow}" ; then
Failed "nbdst failed"
fi
;;
esac
}
local_mount()
{
tries=0
limit=11
while [ $tries -lt $limit ]; do
tries=$(( tries + 1 ))
volinfo=`autodiskmount -F 2>/dev/null`
if [ $? -ne 0 ]; then
if [ $tries -lt $limit ]; then
echo "Waiting for local drives..."
echo "Waiting for local drives (retry ${tries}/$(( limit - 1 )))..." > /dev/console
sleep 5
else
echo "autodiskmount -F found no local drives"
return 1
fi
else
tries=$limit
fi
done
set ${volinfo}
devname=$1
fstype=$2
mount -t "${fstype}" -o nosuid,nodev "/dev/${devname}" "${NETBOOT_MOUNT}" 2>&1
if [ $? -ne 0 ]; then
echo "mount of ${devname} failed"
return 1
fi
common_start "${NETBOOT_MOUNT}/.com.apple.NetBootX" shadowfile
return 0
}
network_mount()
{
mount_from=$(ipconfig netbootoption shadow_mount_path 2>&1)
if [ $? -ne 0 ]; then
echo "no network shadow mount path available"
return 1
fi
shadow_path=$(ipconfig netbootoption shadow_file_path 2>&1)
if [ $? -ne 0 ]; then
echo "no network shadow file path available"
return 1
fi
case "${mount_from}" in
afp:*)
fstype=afp
kextload -v 0 /System/Library/Filesystems/AppleShare/asp_tcp.kext
kextload -v 0 /System/Library/Filesystems/AppleShare/afpfs.kext
;;
nfs:*) fstype=nfs;;
*) echo "unknown network filesystem mount from ${mount_from}"
return 1
;;
esac
mount -t "${fstype}" -o nobrowse "${mount_from}" "${NETBOOT_MOUNT}"
if [ $? -ne 0 ]; then
echo "mount -t ${fstype} -o nobrowse ${mount_from} ${NETBOOT_MOUNT} failed"
return 1
fi
common_start "${NETBOOT_MOUNT}" "${shadow_path}"
return 0
}
do_start()
{
case "${NETBOOT_SHADOW}" in
-LOCAL_ONLY-)
err=$(local_mount)
if [ $? -ne 0 ]; then
Failed "${err}"
fi
;;
-LOCAL-)
err=$(local_mount)
if [ $? -ne 0 ]; then
err=$(network_mount)
if [ $? -ne 0 ]; then
Failed "Could not find a local or network drive"
fi
fi
;;
-NETWORK_ONLY-)
err=$(network_mount)
if [ $? -ne 0 ]; then
Failed "${err}"
fi
;;
*)
err=$(network_mount)
if [ $? -ne 0 ]; then
err=$(local_mount)
if [ $? -ne 0 ]; then
Failed "Could not find a network or local drive"
fi
fi
;;
esac
}
do_init()
{
do_start
fsck -p || fsck -fy || Failed "Could not clean root filesystem"
mount -uw /
swapdir=/private/var/vm
mounted_from=$(mount | sed -n 's:\(.*\) on .*/var/netboot.*:\1:p')
case "${mounted_from}" in
/dev/*)
netboot_dir="${NETBOOT_MOUNT}/.com.apple.NetBootX"
if [ -d "${netboot_dir}" ]; then
rm -rf "${swapdir}"
ln -s "${netboot_dir}" "${swapdir}"
fi
;;
*)
;;
esac
machine_name=$(ipconfig netbootoption machine_name 2>&1)
if [ $? -ne 0 ]; then
echo "no machine name option available"
else
echo "Setting ComputerName to ${machine_name}"
scutil --set ComputerName "${machine_name}"
fi
}
if [ $ exit 0
fi
command=$1
shift
case "${command}" in
init)
do_init $@
;;
esac
exit 0