rc.initdiskless revision 100791
1100280Sgordon#!/bin/sh
2100280Sgordon#
3118638Sfjoe# Copyright (c) 1999  Matt Dillion
466830Sobrien# All rights reserved.
566830Sobrien#
666830Sobrien# Redistribution and use in source and binary forms, with or without
766830Sobrien# modification, are permitted provided that the following conditions
866830Sobrien# are met:
966830Sobrien# 1. Redistributions of source code must retain the above copyright
1066830Sobrien#    notice, this list of conditions and the following disclaimer.
1166830Sobrien# 2. Redistributions in binary form must reproduce the above copyright
1266830Sobrien#    notice, this list of conditions and the following disclaimer in the
1366830Sobrien#    documentation and/or other materials provided with the distribution.
1466830Sobrien#
1566830Sobrien# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1666830Sobrien# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1766830Sobrien# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1866830Sobrien# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1966830Sobrien# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2066830Sobrien# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2166830Sobrien# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2266830Sobrien# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2366830Sobrien# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2466830Sobrien# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2566830Sobrien# SUCH DAMAGE.
2666830Sobrien#
2751231Ssheldonh# $FreeBSD: head/etc/rc.initdiskless 100791 2002-07-28 03:41:53Z dd $
28100280Sgordon#
29108191Sdillon
30127663Sluigi# PROVIDE: initdiskless
31108191Sdillon# KEYWORD: FreeBSD
32108191Sdillon
33127663Sluigidlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
34127663Sluigi[ ${dlv:=0} -eq 0 ] && exit 0
35127663Sluigi
36127663Sluigi#
37108191Sdillon# BOOTP has mounted / for us.  Assume a read-only mount.  We must then
38127663Sluigi# - figure out our IP by querying the interface
39127663Sluigi# - mount /etc as an MFS
40127663Sluigi# - populate /etc from /conf/default version
41108191Sdillon# - override files in /etc with files from /conf/*/etc where
42127663Sluigi#   '*' is default, netmask of client, ip-address of client
43127663Sluigi#
44127663Sluigi# The operator is in charge of setting /conf/*/etc/* things as appropriate.
45127663Sluigi# Typically rc.conf and fstab need to be changed, but possibly also other
46149170Sbrooks# files such as inetd.conf etc.
47127663Sluigi
48127663Sluigi# chkerr:
49127663Sluigi#
50127663Sluigi# Routine to check for error
51127663Sluigi#
52127663Sluigi#	checks error code and drops into shell on failure.
53149170Sbrooks#	if shell exits, terminates script as well as /etc/rc.
54130151Sschweikh#
55127663Sluigichkerr()
56127663Sluigi{
57149170Sbrooks	case $1 in
58149170Sbrooks	0)
59108191Sdillon		;;
60127663Sluigi	*)
61127663Sluigi		echo "$2 failed: dropping into /bin/sh"
62126787Sphk		/bin/sh
63127663Sluigi		# RESUME
64108191Sdillon		;;
65127663Sluigi	esac
66127663Sluigi}
67127663Sluigi
68127663Sluigimount_md()
69127663Sluigi{
70127663Sluigi	/sbin/mdconfig -a -t malloc -s $1 -u $3
71108191Sdillon	/sbin/disklabel -r -w md$3 auto
72179014Sbms	/sbin/newfs -i 4096 /dev/md$3c
73179014Sbms	/sbin/mount /dev/md$3c $2
74179014Sbms}
75179014Sbms
76127663Sluigi# DEBUGGING
77164862Sluigi#
78164862Sluigi# set -v
79164862Sluigi
80164862Sluigi# Figure out our interface and IP.
81164862Sluigi#
82164862Sluigibootp_ifc=""
83164862Sluigibootp_ipa=""
84161824Sbrooksbootp_ipbca=""
85161824Sbrooksiflist=`ifconfig -l`
86161824Sbrooksfor i in ${iflist} ; do
87108191Sdillon    set `ifconfig ${i}`
88127663Sluigi    while [ $# -ge 1 ] ; do
89127663Sluigi        if [ "${bootp_ifc}" = "" -a "$1" = "inet" ] ; then
90127663Sluigi            bootp_ifc=${i} ; bootp_ipa=${2} ; shift
91127663Sluigi        fi
92127663Sluigi        if [ "${bootp_ipbca}" = "" -a "$1" = "broadcast" ] ; then
93127663Sluigi            bootp_ipbca=$2; shift
94127663Sluigi        fi
95127663Sluigi        shift
96127663Sluigi    done
97127663Sluigi    if [ "${bootp_ifc}" != "" ] ; then
98108191Sdillon        break
99127663Sluigi    fi
100127663Sluigidone
101127663Sluigiecho "Interface ${bootp_ifc} IP-Address ${bootp_ipa} Broadcast ${bootp_ipbca}"
102127663Sluigi
103108191Sdillonif [ -z "`hostname -s`" ]; then
104127663Sluigi	hostname=`kenv dhcp.host-name`
105127663Sluigi	hostname $hostname
106127663Sluigi	echo "Hostname is $hostname"
107127663Sluigifi
108161824Sbrooks
109161824Sbrooksif [ -d /conf/default/etc ]; then
110161824Sbrooks	mount_md 4096 /etc 0
111161824Sbrooks	chkerr $? "MFS mount on /etc"
112161824Sbrooks	/bin/chmod 755 /etc
113161824Sbrooks
114127663Sluigi	/bin/cp -Rp /conf/default/etc/* /etc
115127663Sluigi	chkerr $? "cp /conf/default/etc to /etc MFS"
116161533Srufi
117161533Sru
118161533Sru# Allow for override files to replace files in /etc.  Use /conf/*/etc to find
119161533Sru# the override files.  First choice is default files that # always override,
120161533Sru# then files that from the directory that matches the client's broadcast
121161533Sru# address, finally followed by overrides that match the client's IP address.
122127663Sluigi#
123161533Sru# This way we have some flexibility to handle clusters of machines on
124161533Sru# separate subnets.
125161533Sru
126161533Srufor i in ${bootp_ipbca} ${bootp_ipa} ${hostname} ; do
127161533Sru	if [ -d /conf/${i}/etc ]; then
128161533Sru		cp -Rp /conf/${i}/etc/* /etc
129127663Sluigi	fi
130127663Sluigidone
131127663Sluigi
132127663Sluigi#
133127663Sluigi# if the info is available via dhcp/kenv
134126868Sbrooks# build the resolv.conf
135127663Sluigi#
136127663Sluigiif [ ! -e /etc/resolv.conf ]; then
137108191Sdillon	echo domain `kenv dhcp.domain-name` > /etc/resolv.conf
138100280Sgordon
139100280Sgordon	set `kenv dhcp.domain-name-servers`
140164862Sluigi	for ns in `IFS=','; echo $*`; do
141164862Sluigi		echo nameserver $ns >> /etc/resolv.conf;
142164862Sluigi	done
143164862Sluigifi
144164862Sluigi