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
11disklist="da0 da1"
12bootdisk=""
13logfile="/tmp/hammer_ccd_mirror.log"
14contents_dir="/tmp/contents"
15
16#
17# err exitval message
18#     Display an error and exit
19#
20err()
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#
35cktmpdir()
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#
48ckpreinstall()
49{
50    # No pre-install checks
51}
52
53#
54# ccdexit
55#
56ccdexit()
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#
78ckstatus()
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#
95ckloadmod()
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#
116prepdisk()
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 >> ${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#
155mklabel()
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
171EOF
172    else
173	cat >> /tmp/label <<EOF
174 a: 768m 0 4.2BSD
175 d: * * ccd
176EOF
177    fi
178    disklabel -R ${disk}s1 /tmp/label >> ${logfile} 2>&1
179    ckstatus $? "disklabel"
180}
181
182#
183# ccdops
184#
185ccdops()
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#
204gen_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
221ccdconfig -C -f /etc/ccd.conf
222sleep 5
223EOF
224    # Make sure it can be executed by initrd rc
225    chmod +x ${contents_dir}/etc/rc.ccd
226    sync
227}
228
229echo "ALL DATA IN DISKS ${disklist} WILL BE LOST!"
230echo "Press ^C to abort."
231for n in 10 9 8 7 6 5 4 3 2 1
232do
233    echo -n " ${n}"
234    sleep 1
235done
236echo ""
237
238# /tmp has to be writeable
239echo "* Checking /tmp is writeable"
240cktmpdir
241
242rm "${logfile}" >> ${logfile} 2>&1
243echo "* Output to ${logfile}"
244
245# kldload needed modules and start udevd
246echo "* Loading modules"
247ckloadmod ccd >> ${logfile} 2>&1
248
249# check previous installations
250ckpreinstall
251
252# Unmount any prior mounts on /mnt, reverse order to unwind
253# sub-directory mounts.
254#
255for mount in `df | fgrep /mnt | awk '{ print $6; }' | tail -r`
256do
257    echo " Umounting ${mount}"
258    umount ${mount} >> ${logfile} 2>&1
259done
260
261# Prepare the disks in the list
262for disk in ${disklist}
263do
264    echo "* Preparing disk ${disk}"
265    prepdisk ${disk}
266    mklabel ${disk}
267done
268
269# ccdconfig operations in the disks
270echo "* Performing CCD operations"
271ccdops
272
273# prepare the concatenated disk
274prepdisk ccd0
275sleep 1
276mklabel ccd0 root
277
278# Format the volumes
279echo "* Formatting ccd0"
280newfs /dev/${bootdisk}s1a >> ${logfile} 2>&1
281ccdexit $?
282
283newfs_hammer -f -L ROOT /dev/ccd0s1d >> ${logfile} 2>&1
284ccdexit $?
285
286# Mount it
287#
288echo "* Mounting everything"
289mount_hammer /dev/ccd0s1d /mnt >> ${logfile} 2>&1
290ccdexit $?
291
292mkdir /mnt/boot
293
294mount /dev/${bootdisk}s1a /mnt/boot >> ${logfile} 2>&1
295ccdexit $?
296
297# Create PFS mount points for nullfs.
298pfslist="usr usr.obj var var.crash var.tmp tmp home"
299
300mkdir /mnt/pfs
301
302for pfs in ${pfslist}
303do
304    hammer pfs-master /mnt/pfs/$pfs >> ${logfile} 2>&1
305    ccdexit $?
306done
307
308# Mount /usr and /var so that you can add subdirs
309mkdir /mnt/usr >> ${logfile} 2>&1
310mkdir /mnt/var >> ${logfile} 2>&1
311mount_null /mnt/pfs/usr /mnt/usr >> ${logfile} 2>&1
312ccdexit $?
313
314mount_null /mnt/pfs/var /mnt/var >> ${logfile} 2>&1
315ccdexit $?
316
317mkdir /mnt/usr/obj >> ${logfile} 2>&1
318mkdir /mnt/var/tmp >> ${logfile} 2>&1
319mkdir /mnt/var/crash >> ${logfile} 2>&1
320
321mkdir /mnt/tmp >> ${logfile} 2>&1
322mkdir /mnt/home >> ${logfile} 2>&1
323
324mount_null /mnt/pfs/tmp /mnt/tmp >> ${logfile} 2>&1
325ccdexit $?
326
327mount_null /mnt/pfs/home /mnt/home >> ${logfile} 2>&1
328ccdexit $?
329
330mount_null /mnt/pfs/var.tmp /mnt/var/tmp >> ${logfile} 2>&1
331ccdexit $?
332
333mount_null /mnt/pfs/var.crash /mnt/var/crash >> ${logfile} 2>&1
334ccdexit $?
335
336mount_null /mnt/pfs/usr.obj /mnt/usr/obj >> ${logfile} 2>&1
337ccdexit $?
338
339chmod 1777 /mnt/tmp >> ${logfile} 2>&1
340chmod 1777 /mnt/var/tmp >> ${logfile} 2>&1
341
342# Install the system from the live CD
343#
344echo "* Starting file copy"
345cpdup -vv -o / /mnt >> ${logfile} 2>&1
346ccdexit $?
347
348cpdup -vv -o /boot /mnt/boot >> ${logfile} 2>&1
349ccdexit $?
350
351cpdup -vv -o /usr /mnt/usr >> ${logfile} 2>&1
352ccdexit $?
353
354cpdup -vv -o /var /mnt/var >> ${logfile} 2>&1
355ccdexit $?
356
357cpdup -vv -i0 /etc.hdd /mnt/etc >> ${logfile} 2>&1
358ccdexit $?
359
360chflags -R nohistory /mnt/tmp >> ${logfile} 2>&1
361chflags -R nohistory /mnt/var/tmp >> ${logfile} 2>&1
362chflags -R nohistory /mnt/var/crash >> ${logfile} 2>&1
363chflags -R nohistory /mnt/usr/obj >> ${logfile} 2>&1
364
365echo "* Adapting fstab and loader.conf"
366cat > /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
378proc			/proc		procfs	rw		0	0
379EOF
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#
384cat > /mnt/boot/loader.conf << EOF
385ccd_load="YES"
386initrd.img_load="YES"
387initrd.img_type="md_image"
388vfs.root.mountfrom="ufs:md0s0"
389vfs.root.realroot="local:hammer:/dev/ccd0s1d"
390EOF
391
392# Setup interface, configuration, sshd
393#
394echo "* iface setup"
395ifc=`route -n get default | fgrep interface | awk '{ print $2; }'`
396ip=`ifconfig $ifc | fgrep inet | fgrep -v inet6 | awk '{ print $2; }'`
397lip=`echo $ip | awk -F . '{ print $4; }'`
398
399echo -n "ifconfig_$ifc=" >> /mnt/etc/rc.conf
400echo '"DHCP"' >> /mnt/etc/rc.conf
401cat >> /mnt/etc/rc.conf << EOF
402sshd_enable="YES"
403dntpd_enable="YES"
404hostname="test$lip.MYDOMAIN.XXX"
405dumpdev="/dev/ccd0s1b"
406EOF
407
408# Misc sysctls
409#
410cat >> /mnt/etc/sysctl.conf << EOF
411#net.inet.ip.portrange.first=4000
412EOF
413
414# mkinitd image
415echo "* Preparing initrd image"
416cp /etc/defaults/mkinitrd.conf /etc/mkinitrd.conf
417cpdup /usr/share/initrd ${contents_dir}
418
419sed -i.bak '/^BIN_TOOLS/ s/\"$/ sleep\"/' /etc/mkinitrd.conf
420sed -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
423escaped_var=$(printf '%s\n' "${contents_dir}" | sed 's/[\&/]/\\&/g')
424sed -i.bak "s/^CONTENT_DIRS=.*/CONTENT_DIRS=\"${escaped_var}\"/" /etc/mkinitrd.conf
425
426gen_rc_ccd
427
428/sbin/mkinitrd -b /mnt/boot >> ${logfile} 2>&1
429
430# copy installation log
431echo "* Saving up installation log"
432cp ${logfile} /mnt/tmp/
433
434# Warn about ssh
435echo ""
436echo "Warning:"
437echo "chroot now to /mnt and change root password and also edit"
438echo "/mnt/etc/ssh/sshd_config to allow root login and authentication"
439echo "using passwords. Alternatively, you can also just copy your"
440echo "~/.ssh/authorized_keys file to allow login using your ssh keys."
441
442echo "Installation finished successfully."
443
444
445# take CD out and reboot
446#
447