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