hammer2 - update documentation, begin working on callback I/O
[dragonfly.git] / share / examples / rconfig / hammer_ccd_mirror.sh
1 #!/bin/sh
2 #
3 # HAMMER INSTALLATION on a CCD disk (mirror)
4 #
5 # You should modify disklist to match the disks you want to use.
6 # Please BE CAREFUL when doing so.
7 #
8 #
9 # set -x
10
11 disklist="da0 da1"
12 bootdisk=""
13 logfile="/tmp/hammer_ccd_mirror.log"
14 contents_dir="/tmp/contents"
15
16 #
17 # err exitval message
18 #     Display an error and exit
19 #
20 err()
21 {
22     exitval=$1
23     shift
24
25     echo 1>&2 "$0: ERROR: $*"
26     exit $exitval
27 }
28
29 #
30 # cktmpdir
31 #
32 #     Checks whether /tmp is writeable.
33 #     Exit if not
34 #
35 cktmpdir()
36 {
37     mktemp "/tmp/XXX" >> ${logfile} 2>&1
38
39     if [ $? -ne 0 ]; then
40         err 1 "/tmp directory must be writeable"
41     fi
42 }
43
44 #
45 # ckpreinstall
46 #
47 #
48 ckpreinstall()
49 {
50     # No pre-install checks
51 }
52
53 #
54 # ccdexit
55 #
56 ccdexit()
57 {
58     local status=$1
59
60     if [ $# -ne 0 ]; then
61         if [ ${status} -eq 0 ]; then
62                 return
63                 fi
64     fi
65
66     echo ""
67     echo "ccd operations were not sucessfully performed,"
68     echo "it is highly probably you have to reboot this computer now."
69     exit 1
70 }
71
72 #
73 # ckstatus status progname
74 #
75 #     Checks exit status of programs and if it fails
76 #     it exists with a message
77 #
78 ckstatus()
79 {
80     local st=$1
81     local prog=$2
82
83     if [ ${st} -ne 0 ]; then
84         err 1 "Failed to run $2. Check ${logfile}"
85     fi
86 }
87
88 #
89 # ckloadmod modname
90 #
91 #     Checks if a module is loaded, if not
92 #     it tries to load it. In case of failure
93 #     it exits
94 #
95 ckloadmod()
96 {
97     local mod=$1
98
99     if ! kldstat -q -m ${mod}; then
100         kldload $1 >> ${logfile} 2>&1
101
102         if [ $? -ne 0 ]; then
103             err 1 "Could not load ${mod}"
104         fi
105     fi
106 }
107
108 #
109 # prepdisk disk
110 #
111 #     Clears the first sectors of the disk
112 #     and then prepares the disk for disklabel.
113 #     It also installs bootblocks in the first
114 #     disk of the list.
115 #
116 prepdisk()
117 {
118     local disk=$1
119
120     # Hey don't shoot yourself in the foot
121     if [ ! "$disk" = "" ]; then
122         mount | fgrep ${disk} >> ${logfile} 2>&1
123
124         if [ $? -ne 1 ]; then
125             err 1 "${disk} is already being used, aborting"
126         fi
127     fi
128
129     if [ "${bootdisk}" = "" ]; then
130         bootdisk=${disk}
131     fi
132
133     dd if=/dev/zero of=/dev/${disk} bs=32k count=16 >> ${logfile} 2>&1
134     ckstatus $? "dd"
135
136     fdisk -IB ${disk} >> ${logfile} 2>&1
137     ckstatus $? "fdisk"
138
139     disklabel -r -w ${disk}s1 auto >> ${logfile} 2>&1
140     ckstatus $? "disklabel"
141
142     if [ ! "${bootdisk}" = "" ]; then
143         disklabel -B ${disk}s1 >> ${logfile} 2>&1
144         ckstatus $? "disklabel"
145     fi
146 }
147
148 #
149 # mklabel disk
150 #
151 #     Create same labels for every disk
152 #     except for the disk that will contain
153 #     /boot partition
154 #
155 mklabel()
156 {
157     local disk=$1
158     local param=$2
159
160     disklabel ${disk}s1 > /tmp/label
161     ckstatus $? "disklabel"
162
163     # calculate memory
164     tmp=`sysctl hw.physmem | cut -w -f 2`
165     memtotal=`expr ${tmp} / 1024 / 1024`
166
167     if [ "${param}" = "root" ]; then
168         cat >> /tmp/label <<EOF
169  b: ${memtotal}m * swap
170  d: * * hammer
171 EOF
172     else
173         cat >> /tmp/label <<EOF
174  a: 768m 0 4.2BSD
175  d: * * ccd
176 EOF
177     fi
178     disklabel -R ${disk}s1 /tmp/label >> ${logfile} 2>&1
179     ckstatus $? "disklabel"
180 }
181
182 #
183 # ccdops
184 #
185 ccdops()
186 {
187     local lst=""
188     local tmp=""
189
190     for disk in ${disklist}
191     do
192         tmp=${lst}
193         lst="${tmp} /dev/${disk}s1d"
194     done
195
196     ccdconfig ccd0 128 CCDF_MIRROR ${lst}
197     ckstatus $? "ccdconfig"
198     sleep 3     # Try to settle ops
199 }
200
201 #
202 # gen_rc_ccd
203 #
204 gen_rc_ccd()
205 {
206     local lst=""
207     local tmp=""
208
209     for disk in ${disklist}
210     do
211         tmp=${lst}
212         lst="${tmp} /dev/${disk}s1d"
213     done
214
215     # dump the config
216     ccdconfig -g > ${contents_dir}/etc/ccd.conf
217     ckstatus $? "ccdconfig"
218
219     cat >> ${contents_dir}/etc/rc.ccd << EOF
220 # call ccdconfig to restore the configuration
221 ccdconfig -C -f /etc/ccd.conf
222 sleep 5
223 EOF
224     # Make sure it can be executed by initrd rc
225     chmod +x ${contents_dir}/etc/rc.ccd
226     sync
227 }
228
229 echo "ALL DATA IN DISKS ${disklist} WILL BE LOST!"
230 echo "Press ^C to abort."
231 for n in 10 9 8 7 6 5 4 3 2 1
232 do
233     echo -n " ${n}"
234     sleep 1
235 done
236 echo ""
237
238 # /tmp has to be writeable
239 echo "* Checking /tmp is writeable"
240 cktmpdir
241
242 rm "${logfile}" >> ${logfile} 2>&1
243 echo "* Output to ${logfile}"
244
245 # kldload needed modules and start udevd
246 echo "* Loading modules"
247 ckloadmod ccd >> ${logfile} 2>&1
248
249 # check previous installations
250 ckpreinstall
251
252 # Unmount any prior mounts on /mnt, reverse order to unwind
253 # sub-directory mounts.
254 #
255 for mount in `df | fgrep /mnt | awk '{ print $6; }' | tail -r`
256 do
257     echo " Umounting ${mount}"
258     umount ${mount} >> ${logfile} 2>&1
259 done
260
261 # Prepare the disks in the list
262 for disk in ${disklist}
263 do
264     echo "* Preparing disk ${disk}"
265     prepdisk ${disk}
266     mklabel ${disk}
267 done
268
269 # ccdconfig operations in the disks
270 echo "* Performing CCD operations"
271 ccdops
272
273 # prepare the concatenated disk
274 prepdisk ccd0
275 sleep 1
276 mklabel ccd0 root
277
278 # Format the volumes
279 echo "* Formating ccd0"
280 newfs /dev/${bootdisk}s1a >> ${logfile} 2>&1
281 ccdexit $?
282
283 newfs_hammer -f -L ROOT /dev/ccd0s1d >> ${logfile} 2>&1
284 ccdexit $?
285
286 # Mount it
287 #
288 echo "* Mounting everything"
289 mount_hammer /dev/ccd0s1d /mnt >> ${logfile} 2>&1
290 ccdexit $?
291
292 mkdir /mnt/boot
293
294 mount /dev/${bootdisk}s1a /mnt/boot >> ${logfile} 2>&1
295 ccdexit $?
296
297 # Create PFS mount points for nullfs.
298 pfslist="usr usr.obj var var.crash var.tmp tmp home"
299
300 mkdir /mnt/pfs
301
302 for pfs in ${pfslist}
303 do
304     hammer pfs-master /mnt/pfs/$pfs >> ${logfile} 2>&1
305     ccdexit $?
306 done
307
308 # Mount /usr and /var so that you can add subdirs
309 mkdir /mnt/usr >> ${logfile} 2>&1
310 mkdir /mnt/var >> ${logfile} 2>&1
311 mount_null /mnt/pfs/usr /mnt/usr >> ${logfile} 2>&1
312 ccdexit $?
313
314 mount_null /mnt/pfs/var /mnt/var >> ${logfile} 2>&1
315 ccdexit $?
316
317 mkdir /mnt/usr/obj >> ${logfile} 2>&1
318 mkdir /mnt/var/tmp >> ${logfile} 2>&1
319 mkdir /mnt/var/crash >> ${logfile} 2>&1
320
321 mkdir /mnt/tmp >> ${logfile} 2>&1
322 mkdir /mnt/home >> ${logfile} 2>&1
323
324 mount_null /mnt/pfs/tmp /mnt/tmp >> ${logfile} 2>&1
325 ccdexit $?
326
327 mount_null /mnt/pfs/home /mnt/home >> ${logfile} 2>&1
328 ccdexit $?
329
330 mount_null /mnt/pfs/var.tmp /mnt/var/tmp >> ${logfile} 2>&1
331 ccdexit $?
332
333 mount_null /mnt/pfs/var.crash /mnt/var/crash >> ${logfile} 2>&1
334 ccdexit $?
335
336 mount_null /mnt/pfs/usr.obj /mnt/usr/obj >> ${logfile} 2>&1
337 ccdexit $?
338
339 chmod 1777 /mnt/tmp >> ${logfile} 2>&1
340 chmod 1777 /mnt/var/tmp >> ${logfile} 2>&1
341
342 # Install the system from the live CD
343 #
344 echo "* Starting file copy"
345 cpdup -vv -o / /mnt >> ${logfile} 2>&1
346 ccdexit $?
347
348 cpdup -vv -o /boot /mnt/boot >> ${logfile} 2>&1
349 ccdexit $?
350
351 cpdup -vv -o /usr /mnt/usr >> ${logfile} 2>&1
352 ccdexit $?
353
354 cpdup -vv -o /var /mnt/var >> ${logfile} 2>&1
355 ccdexit $?
356
357 cpdup -vv -i0 /etc.hdd /mnt/etc >> ${logfile} 2>&1
358 ccdexit $?
359
360 chflags -R nohistory /mnt/tmp >> ${logfile} 2>&1
361 chflags -R nohistory /mnt/var/tmp >> ${logfile} 2>&1
362 chflags -R nohistory /mnt/var/crash >> ${logfile} 2>&1
363 chflags -R nohistory /mnt/usr/obj >> ${logfile} 2>&1
364
365 echo "* Adapting fstab and loader.conf"
366 cat > /mnt/etc/fstab << EOF
367 # Device                Mountpoint      FStype  Options         Dump    Pass#
368 /dev/ccd0s1d    /               hammer  rw              1       1
369 /dev/${bootdisk}s1a     /boot           ufs     rw              1       1
370 /dev/ccd0s1b    none            swap    sw              0       0
371 /pfs/usr                /usr            null    rw              0       0
372 /pfs/var                /var            null    rw              0       0
373 /pfs/tmp                /tmp            null    rw              0       0
374 /pfs/home               /home           null    rw              0       0
375 /pfs/var.tmp            /var/tmp        null    rw              0       0
376 /pfs/usr.obj            /usr/obj        null    rw              0       0
377 /pfs/var.crash          /var/crash      null    rw              0       0
378 proc                    /proc           procfs  rw              0       0
379 EOF
380
381 # Because root is not on the boot partition we have to tell the loader
382 # to tell the kernel where root is.
383 #
384 cat > /mnt/boot/loader.conf << EOF
385 ccd_load="YES"
386 initrd.img_load="YES"
387 initrd.img_type="md_image"
388 vfs.root.mountfrom="ufs:md0s0"
389 vfs.root.realroot="local:hammer:/dev/ccd0s1d"
390 EOF
391
392 # Setup interface, configuration, sshd
393 #
394 echo "* iface setup"
395 ifc=`route -n get default | fgrep interface | awk '{ print $2; }'`
396 ip=`ifconfig $ifc | fgrep inet | fgrep -v inet6 | awk '{ print $2; }'`
397 lip=`echo $ip | awk -F . '{ print $4; }'`
398
399 echo -n "ifconfig_$ifc=" >> /mnt/etc/rc.conf
400 echo '"DHCP"' >> /mnt/etc/rc.conf
401 cat >> /mnt/etc/rc.conf << EOF
402 sshd_enable="YES"
403 dntpd_enable="YES"
404 hostname="test$lip.MYDOMAIN.XXX"
405 dumpdev="/dev/ccd0s1b"
406 EOF
407
408 # Misc sysctls
409 #
410 cat >> /mnt/etc/sysctl.conf << EOF
411 #net.inet.ip.portrange.first=4000
412 EOF
413
414 # mkinitd image
415 echo "* Preparing initrd image"
416 cp /etc/defaults/mkinitrd.conf /etc/mkinitrd.conf
417 cpdup /usr/share/initrd ${contents_dir}
418
419 sed -i.bak '/^BIN_TOOLS/ s/\"$/ sleep\"/' /etc/mkinitrd.conf
420 sed -i.bak '/^SBIN_TOOLS/ s/\\/ccdconfig \\/' /etc/mkinitrd.conf
421
422 # Need to escape the directory so that sed doesn't take the var literally
423 escaped_var=$(printf '%s\n' "${contents_dir}" | sed 's/[\&/]/\\&/g')
424 sed -i.bak "s/^CONTENT_DIRS=.*/CONTENT_DIRS=\"${escaped_var}\"/" /etc/mkinitrd.conf
425
426 gen_rc_ccd
427
428 /sbin/mkinitrd -b /mnt/boot >> ${logfile} 2>&1
429
430 # copy installation log
431 echo "* Saving up installation log"
432 cp ${logfile} /mnt/tmp/
433
434 # Warn about ssh
435 echo ""
436 echo "Warning:"
437 echo "chroot now to /mnt and change root password and also edit"
438 echo "/mnt/etc/ssh/sshd_config to allow root login and authentication"
439 echo "using passwords. Alternatively, you can also just copy your"
440 echo "~/.ssh/authorized_keys file to allow login using your ssh keys."
441
442 echo "Installation finished successfully."
443
444
445 # take CD out and reboot
446 #