rc.netboot   [plain text]


#!/bin/sh
##
# Copyright 2002 Apple Computer, Inc.
#
# This script configures NetBoot
##

##
# Set shell to ignore Control-C, etc.
# Prevent inadvertent problems caused by interrupting the shell during boot.
##
stty intr  undef
stty kill  undef
stty quit  undef
stty susp  undef
stty start undef
stty stop  undef
stty dsusp undef
. /etc/rc.common

# 
# Define: NETBOOT_SHADOW
# Purpose:
#   To change the behavior of the system when choosing a netboot shadow
#   to use.
# Values:
#   -NETWORK-		Try to use the network for the shadow file, if
#			that fails, use the local drive
#   -NETWORK_ONLY-	Only use the network, fail if not available
#   -LOCAL-		Use the local drive for the shadow file, if that
#			fails, use the network
#   -LOCAL_ONLY-	Only use the local drive for the shadow, fail if
#			not available

NETBOOT_MOUNT=/var/netboot
NETBOOT_SHADOW=${NETBOOT_SHADOW:-NETWORK-}

Failed()
{
	echo rc.netboot: $1
	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()
{
    found=0
    for i in 1 2 3 4 5 6 7 8 9 10
    do
      volinfo=`autodiskmount -F 2>/dev/null`
      if [ $? -eq 0 ]; then
	  found=1
	  break;
      fi
      if [ ${i} -ne 1 ]; then
	  sleep 1
      fi
    done

    if [ ${found} -ne 1 ]; then
	echo "autodiskmount -F found no local drives"
	return 1
    fi

    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;;
 	nfs:*) fstype=nfs;;
	*) echo "unknown network filesystem mount from ${mount_from}"
	   return 1
	   ;;
    esac
    mount -t "${fstype}" "${mount_from}" "${NETBOOT_MOUNT}"
    if [ $? -ne 0 ]; then
	echo "mount -t ${fstype} ${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_vm()
{
    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

    swapdir=${1:-/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 "${netboot_dir}/app_profile"
			rm -rf "${swapdir}"
			ln -s "${netboot_dir}" "${swapdir}"
		fi
		;;
	*)
	;;
    esac
}

if [ $# -lt 1 ] ; then
    exit 0
fi

command=$1

shift

case "${command}" in
    start)
	do_start $@
	;;
    setup_vm)
	do_vm $@
	;;
esac 

##
# Exit
##
exit 0