Merge branch 'vendor/GCC44'
[dragonfly.git] / share / examples / rconfig / hammer_lvm_stripe.sh
1 #!/bin/sh
2 #
3 # This script takes in account a disk list to make a lvm(8) stripe
4 # which will contain a hammer filesystem and the swap partition.
5 #
6 # Be aware that this is just to provide _basic_ installation
7 # functionalities and it may need actions from the sysadmin to
8 # properly install and get a consistent installed system.
9
10 # set -x
11
12 export LVM_SUPPRESS_FD_WARNINGS=1
13
14 disklist="da0 da1"
15 bootdisk=""
16 logfile="/tmp/hammer_lvm_stripe.log"
17
18 #
19 # err exitval message
20 #     Display an error and exit
21 #
22 err()
23 {
24     exitval=$1
25     shift
26
27     echo 1>&2 "$0: ERROR: $*"
28     exit $exitval
29 }
30
31 #
32 # cktmpdir
33 #
34 #     Checks whether /tmp is writeable.
35 #     Exit if not
36 #
37 cktmpdir()
38 {
39     mktemp "/tmp/XXX" >> ${logfile} 2>&1
40
41     if [ $? -ne 0 ]; then
42         err 1 "/tmp directory must be writeable"
43     fi
44 }
45
46 #
47 # ckpreinstall
48 #
49 #     Checks whether lv nodes exist which would may
50 #     indicate an installation already succeeded or
51 #     a previous failed one.
52 #
53 ckpreinstall()
54 {
55
56     # Try to activate the volume first
57     vgchange -a y main >> ${logfile} 2>&1
58
59     if [ -c /dev/mapper/main-lv_root -o -c /dev/mapper/main-lv_swap ]; then
60         echo " ERROR: Either a previous installation failed or your installation"
61         echo " is already done. If the former, please follow instructions below."
62         echo ""
63
64         lvmexit
65     fi
66 }
67
68
69 #
70 # ckstatus status progname
71 #
72 #     Checks exit status of programs and if it fails
73 #     it exists with a message
74 #
75 ckstatus()
76 {
77     local st=$1
78     local prog=$2
79
80     if [ ${st} -ne 0 ]; then
81         err 1 "Failed to run $2. Check ${logfile}"
82     fi
83 }
84
85 #
86 # ckloadmod modname
87 #
88 #     Checks if a module is loaded, if not
89 #     it tries to load it. In case of failure
90 #     it exits
91 #
92 ckloadmod()
93 {
94     local mod=$1
95
96     if ! kldstat -q -m ${mod}; then
97         kldload $1 >> ${logfile} 2>&1
98
99         if [ $? -ne 0 ]; then
100             err 1 "Could not load ${mod}"
101         fi
102     fi
103 }
104
105 #
106 # prepdisk disk
107 #
108 #     Clears the first sectors of the disk
109 #     and then prepares the disk for disklabel.
110 #     It also installs bootblocks in the first
111 #     disk of the list.
112 #
113 prepdisk()
114 {
115     local disk=$1
116
117     # Hey don't shoot yourself in the foot
118     if [ ! "$disk" = "" ]; then
119         mount | fgrep ${disk} >> ${logfile} 2>&1
120
121         if [ $? -ne 1 ]; then
122             err 1 "${disk} is already being used, aborting"
123         fi
124     fi
125
126     if [ "${bootdisk}" = "" ]; then
127         bootdisk=${disk}
128     fi
129
130     dd if=/dev/zero of=/dev/${disk} bs=32k count=16 >> ${logfile} 2>&1
131     ckstatus $? "dd"
132
133     fdisk -IB ${disk} >> ${logfile} 2>&1
134     ckstatus $? "fdisk"
135
136     disklabel -r -w ${disk}s1 auto >> ${logfile} 2>&1
137     ckstatus $? "disklabel"
138
139     if [ ! "${bootdisk}" = "" ]; then
140         disklabel -B ${disk}s1 >> ${logfile} 2>&1
141         ckstatus $? "disklabel"
142     fi
143 }
144
145 #
146 # mklabel disk
147 #
148 #     Create same labels for every disk
149 #     except for the disk that will contain
150 #     /boot partition
151 #
152 mklabel()
153 {
154     local disk=$1
155
156     disklabel ${disk}s1 > /tmp/label
157     ckstatus $? "disklabel"
158
159     if [ "${disk}" = "${bootdisk}" ]; then
160         cat >> /tmp/label <<EOF
161  a: 768m 0 4.2BSD
162  d: * * unknown
163 EOF
164     else
165         cat >> /tmp/label <<EOF
166  d: * * unknown
167 EOF
168
169     fi
170
171     disklabel -R ${disk}s1 /tmp/label >> ${logfile} 2>&1
172     ckstatus $? "disklabel"
173 }
174
175
176 #
177 # lvmexit
178 #
179 #     lvm exit message
180 lvmexit()
181 {
182     local status=$1
183
184     if [ $# -ne 0 ]; then
185         if [ ${status} -eq 0 ]; then
186             return
187         fi
188     fi
189
190     echo " There was an error during or after LVM operations for this"
191     echo " installation and those operations done cannot be reverted"
192     echo " by the script itself. Please revert them manually:"
193     echo ""
194     echo " Basically you need to perform these steps:"
195     echo "   1. Remove all logical volumes in VG main (lv_swap, lv_root)"
196     echo "   2. Remove main volume group"
197     echo "   3. Remove all the physical volumes. PVs are all in [disk]1d"
198     echo "      For example, if you have 2 disks, you need to remove:"
199     echo "        /sbin/pvremove /dev/da0s1d"
200     echo "        /sbin/pvremove /dev/da1s1d"
201     echo ""
202     exit 1
203 }
204
205 #
206 # rev_lvmops
207 #
208 #     Revert all lvmops
209 #
210 rev_lvmops()
211 {
212
213     vgchange -a n main >> ${logfile} 2>&1
214
215     lvremove --force lv_swap main >> ${logfile} 2>&1
216     if [ $? -ne 0 ]; then
217         lvmexit
218     fi
219
220     lvremove --force lv_root main >> ${logfile} 2>&1
221     if [ $? -ne 0 ]; then
222         lvmexit
223     fi
224
225     vgremove --force main >> ${logfile} 2>&1
226     if [ $? -ne 0 ]; then
227         lvmexit
228     fi
229
230     for disk in ${disklist}
231     do
232         pvremove /dev/${disk}s1d >> ${logfile} 2>&1
233     done
234 }
235
236 #
237 # lvmops
238 #
239 #     Create physical volumes, volume group 'main' and
240 #     the ROOT hammer filesystem where everything will
241 #     be installed. swap is also created as a log. volume.
242 #
243 lvmops()
244 {
245     local lst=""
246     local tmp=""
247
248     for disk in ${disklist}
249     do
250         pvcreate /dev/${disk}s1d >> ${logfile} 2>&1
251         if [ $? -ne 0 ]; then
252             rev_lvmops
253         fi
254         tmp=${lst}
255         lst="${tmp} /dev/${disk}s1d"
256
257         # Be safe
258         sync
259         sleep 1
260     done
261
262     # Do a full scan in the hope the lvm
263     # cache is rebuilt
264     pvscan >> ${logfile} 2>&1
265
266     vgcreate main ${lst} >> ${logfile} 2>&1
267     if [ $? -ne 0 ]; then
268         rev_lvmops
269     fi
270
271     # We need to sync and wait for some secs to settle
272     # Otherwise /dev/main won't appear
273     echo "     Settling LVM operations (5 secs)"
274     sync
275     sleep 5
276     vgscan >> ${logfile} 2>&1
277
278     lvcreate -Z n -n lv_swap -L ${memtotal} main >> ${logfile} 2>&1
279     if [ $? -ne 0 ]; then
280         rev_lvmops
281     fi
282
283     # We sync in every lvm operation
284     sync
285     lvscan >> ${logfile} 2>&1
286     sleep 1
287
288     lvcreate -Z n -n lv_root -l 100%FREE main >> ${logfile} 2>&1
289     if [ $? -ne 0 ]; then
290         rev_lvmops
291     fi
292
293 }
294
295 echo "ALL DATA IN DISKS ${disklist} WILL BE LOST!"
296 echo "Press ^C to abort."
297 for n in 10 9 8 7 6 5 4 3 2 1
298 do
299     echo -n " ${n}"
300     sleep 1
301 done
302 echo ""
303
304 # /tmp has to be writeable
305 echo "* Checking /tmp is writeable"
306 cktmpdir
307
308 rm "${logfile}" >> ${logfile} 2>&1
309 echo "* Output to ${logfile}"
310
311 # calculate memory
312 tmp=`sysctl hw.physmem | cut -w -f 2`
313 memtotal=`expr ${tmp} / 1024 / 1024`
314
315 # kldload needed modules and start udevd
316 echo "* Loading modules"
317 ckloadmod dm_target_striped >> ${logfile} 2>&1
318 ckloadmod dm_target_linear >> ${logfile} 2>&1
319 /sbin/udevd >> ${logfile} 2>&1
320
321 # check previous installations
322 ckpreinstall
323
324 # Unmount any prior mounts on /mnt, reverse order to unwind
325 # sub-directory mounts.
326 #
327 for mount in `df | fgrep /mnt | awk '{ print $6; }' | tail -r`
328 do
329     echo " Umounting ${mount}"
330     umount ${mount} >> ${logfile} 2>&1
331 done
332
333 # Prepare the disks in the list
334 for disk in ${disklist}
335 do
336     echo "* Preparing disk ${disk}"
337     prepdisk ${disk}
338     mklabel ${disk}
339     pvscan >> ${logfile} 2>&1
340 done
341
342 # lvm(8) operations in the disks
343 echo "* Performing LVM operations"
344 lvmops
345
346 # Format the volumes
347 echo "* Formating ${bootdisk} and LVs lv_root"
348 newfs /dev/${bootdisk}s1a >> ${logfile} 2>&1
349 lvmexit $?
350
351 newfs_hammer -f -L ROOT /dev/main/lv_root >> ${logfile} 2>&1
352 lvmexit $?
353
354 # Mount it
355 #
356 echo "* Mounting everything"
357 mount_hammer /dev/main/lv_root /mnt >> ${logfile} 2>&1
358 lvmexit $?
359
360 mkdir /mnt/boot
361
362 mount /dev/${bootdisk}s1a /mnt/boot >> ${logfile} 2>&1
363 lvmexit $?
364
365 # Create PFS mount points for nullfs.
366 pfslist="usr usr.obj var var.crash var.tmp tmp home"
367
368 mkdir /mnt/pfs
369
370 for pfs in ${pfslist}
371 do
372     hammer pfs-master /mnt/pfs/$pfs >> ${logfile} 2>&1
373     lvmexit $?
374 done
375
376 # Mount /usr and /var so that you can add subdirs
377 mkdir /mnt/usr >> ${logfile} 2>&1
378 mkdir /mnt/var >> ${logfile} 2>&1
379 mount_null /mnt/pfs/usr /mnt/usr >> ${logfile} 2>&1
380 lvmexit $?
381
382 mount_null /mnt/pfs/var /mnt/var >> ${logfile} 2>&1
383 lvmexit $?
384
385 mkdir /mnt/usr/obj >> ${logfile} 2>&1
386 mkdir /mnt/var/tmp >> ${logfile} 2>&1
387 mkdir /mnt/var/crash >> ${logfile} 2>&1
388
389 mkdir /mnt/tmp >> ${logfile} 2>&1
390 mkdir /mnt/home >> ${logfile} 2>&1
391
392 mount_null /mnt/pfs/tmp /mnt/tmp >> ${logfile} 2>&1
393 lvmexit $?
394
395 mount_null /mnt/pfs/home /mnt/home >> ${logfile} 2>&1
396 lvmexit $?
397
398 mount_null /mnt/pfs/var.tmp /mnt/var/tmp >> ${logfile} 2>&1
399 lvmexit $?
400
401 mount_null /mnt/pfs/var.crash /mnt/var/crash >> ${logfile} 2>&1
402 lvmexit $?
403
404 mount_null /mnt/pfs/usr.obj /mnt/usr/obj >> ${logfile} 2>&1
405 lvmexit $?
406
407 chmod 1777 /mnt/tmp >> ${logfile} 2>&1
408 chmod 1777 /mnt/var/tmp >> ${logfile} 2>&1
409
410 # Install the system from the live CD
411 #
412 echo "* Starting file copy"
413 cpdup -vv -o / /mnt >> ${logfile} 2>&1
414 lvmexit $?
415
416 cpdup -vv -o /boot /mnt/boot >> ${logfile} 2>&1
417 lvmexit $?
418
419 cpdup -vv -o /usr /mnt/usr >> ${logfile} 2>&1
420 lvmexit $?
421
422 cpdup -vv -o /var /mnt/var >> ${logfile} 2>&1
423 lvmexit $?
424
425 cpdup -vv -i0 /etc.hdd /mnt/etc >> ${logfile} 2>&1
426 lvmexit $?
427
428 chflags -R nohistory /mnt/tmp >> ${logfile} 2>&1
429 chflags -R nohistory /mnt/var/tmp >> ${logfile} 2>&1
430 chflags -R nohistory /mnt/var/crash >> ${logfile} 2>&1
431 chflags -R nohistory /mnt/usr/obj >> ${logfile} 2>&1
432
433 echo "* Adapting fstab and loader.conf"
434 cat > /mnt/etc/fstab << EOF
435 # Device                Mountpoint      FStype  Options         Dump    Pass#
436 /dev/main/lv_root       /               hammer  rw              1       1
437 /dev/${bootdisk}s1a     /boot           ufs     rw              1       1
438 /dev/main/lv_swap       none            swap    sw              0       0
439 /pfs/usr                /usr            null    rw              0       0
440 /pfs/var                /var            null    rw              0       0
441 /pfs/tmp                /tmp            null    rw              0       0
442 /pfs/home               /home           null    rw              0       0
443 /pfs/var.tmp            /var/tmp        null    rw              0       0
444 /pfs/usr.obj            /usr/obj        null    rw              0       0
445 /pfs/var.crash          /var/crash      null    rw              0       0
446 proc                    /proc           procfs  rw              0       0
447 EOF
448
449 # Because root is not on the boot partition we have to tell the loader
450 # to tell the kernel where root is.
451 #
452 cat > /mnt/boot/loader.conf << EOF
453 dm_target_striped_load="YES"
454 dm_target_linear_load="YES"
455 initrd.img_load="YES"
456 initrd.img_type="md_image"
457 vfs.root.mountfrom="ufs:md0s0"
458 vfs.root.realroot="local:hammer:/dev/main/lv_root"
459 EOF
460
461 # Setup interface, configuration, sshd
462 #
463 echo "* iface setup"
464 ifc=`route -n get default | fgrep interface | awk '{ print $2; }'`
465 ip=`ifconfig $ifc | fgrep inet | fgrep -v inet6 | awk '{ print $2; }'`
466 lip=`echo $ip | awk -F . '{ print $4; }'`
467
468 echo -n "ifconfig_$ifc=" >> /mnt/etc/rc.conf
469 echo '"DHCP"' >> /mnt/etc/rc.conf
470 cat >> /mnt/etc/rc.conf << EOF
471 sshd_enable="YES"
472 dntpd_enable="YES"
473 hostname="test$lip.MYDOMAIN.XXX"
474 dumpdev="/dev/main/lv_swap"
475 EOF
476
477 # Misc sysctls
478 #
479 cat >> /mnt/etc/sysctl.conf << EOF
480 #net.inet.ip.portrange.first=4000
481 EOF
482
483 # adjust work directory for pkgsrc in case we want
484 # to mount /usr/pkgsrc read-only.
485 #
486 cat >> /mnt/usr/pkg/etc/mk.conf << EOF
487 .ifdef BSD_PKG_MK       # begin pkgsrc settings
488 WRKOBJDIR=              /usr/obj/pkgsrc
489 .endif                  # end pkgsrc settings
490 EOF
491
492 # mkinitd image
493 echo "* Preparing initrd image"
494 /sbin/mkinitrd -b /mnt/boot >> ${logfile} 2>&1
495
496 # Warn about ssh
497 echo ""
498 echo "Warning:"
499 echo "chroot now to /mnt and change root password and also edit"
500 echo "/mnt/etc/ssh/sshd_config to allow root login and authentication"
501 echo "using passwords. Alternatively, you can also just copy your"
502 echo "~/.ssh/authorized_keys file to allow login using your ssh keys."
503
504 echo "Installation finished successfully."
505
506
507 # take CD out and reboot
508 #