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 12export LVM_SUPPRESS_FD_WARNINGS=1 13 14disklist="da0 da1" 15bootdisk="" 16logfile="/tmp/hammer_lvm_stripe.log" 17 18# 19# err exitval message 20# Display an error and exit 21# 22err() 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# 37cktmpdir() 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# 53ckpreinstall() 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# 75ckstatus() 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# 92ckloadmod() 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# 113prepdisk() 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# 152mklabel() 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 163EOF 164 else 165 cat >> /tmp/label <<EOF 166 d: * * unknown 167EOF 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 180lvmexit() 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# 210rev_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# 243lvmops() 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 295echo "ALL DATA IN DISKS ${disklist} WILL BE LOST!" 296echo "Press ^C to abort." 297for n in 10 9 8 7 6 5 4 3 2 1 298do 299 echo -n " ${n}" 300 sleep 1 301done 302echo "" 303 304# /tmp has to be writeable 305echo "* Checking /tmp is writeable" 306cktmpdir 307 308rm "${logfile}" >> ${logfile} 2>&1 309echo "* Output to ${logfile}" 310 311# calculate memory 312tmp=`sysctl hw.physmem | cut -w -f 2` 313memtotal=`expr ${tmp} / 1024 / 1024` 314 315# kldload needed modules and start udevd 316echo "* Loading modules" 317ckloadmod dm_target_striped >> ${logfile} 2>&1 318ckloadmod dm_target_linear >> ${logfile} 2>&1 319/sbin/udevd >> ${logfile} 2>&1 320 321# check previous installations 322ckpreinstall 323 324# Unmount any prior mounts on /mnt, reverse order to unwind 325# sub-directory mounts. 326# 327for mount in `df | fgrep /mnt | awk '{ print $6; }' | tail -r` 328do 329 echo " Umounting ${mount}" 330 umount ${mount} >> ${logfile} 2>&1 331done 332 333# Prepare the disks in the list 334for disk in ${disklist} 335do 336 echo "* Preparing disk ${disk}" 337 prepdisk ${disk} 338 mklabel ${disk} 339 pvscan >> ${logfile} 2>&1 340done 341 342# lvm(8) operations in the disks 343echo "* Performing LVM operations" 344lvmops 345 346# Format the volumes 347echo "* Formating ${bootdisk} and LVs lv_root" 348newfs /dev/${bootdisk}s1a >> ${logfile} 2>&1 349lvmexit $? 350 351newfs_hammer -f -L ROOT /dev/main/lv_root >> ${logfile} 2>&1 352lvmexit $? 353 354# Mount it 355# 356echo "* Mounting everything" 357mount_hammer /dev/main/lv_root /mnt >> ${logfile} 2>&1 358lvmexit $? 359 360mkdir /mnt/boot 361 362mount /dev/${bootdisk}s1a /mnt/boot >> ${logfile} 2>&1 363lvmexit $? 364 365# Create PFS mount points for nullfs. 366pfslist="usr usr.obj var var.crash var.tmp tmp home" 367 368mkdir /mnt/pfs 369 370for pfs in ${pfslist} 371do 372 hammer pfs-master /mnt/pfs/$pfs >> ${logfile} 2>&1 373 lvmexit $? 374done 375 376# Mount /usr and /var so that you can add subdirs 377mkdir /mnt/usr >> ${logfile} 2>&1 378mkdir /mnt/var >> ${logfile} 2>&1 379mount_null /mnt/pfs/usr /mnt/usr >> ${logfile} 2>&1 380lvmexit $? 381 382mount_null /mnt/pfs/var /mnt/var >> ${logfile} 2>&1 383lvmexit $? 384 385mkdir /mnt/usr/obj >> ${logfile} 2>&1 386mkdir /mnt/var/tmp >> ${logfile} 2>&1 387mkdir /mnt/var/crash >> ${logfile} 2>&1 388 389mkdir /mnt/tmp >> ${logfile} 2>&1 390mkdir /mnt/home >> ${logfile} 2>&1 391 392mount_null /mnt/pfs/tmp /mnt/tmp >> ${logfile} 2>&1 393lvmexit $? 394 395mount_null /mnt/pfs/home /mnt/home >> ${logfile} 2>&1 396lvmexit $? 397 398mount_null /mnt/pfs/var.tmp /mnt/var/tmp >> ${logfile} 2>&1 399lvmexit $? 400 401mount_null /mnt/pfs/var.crash /mnt/var/crash >> ${logfile} 2>&1 402lvmexit $? 403 404mount_null /mnt/pfs/usr.obj /mnt/usr/obj >> ${logfile} 2>&1 405lvmexit $? 406 407chmod 1777 /mnt/tmp >> ${logfile} 2>&1 408chmod 1777 /mnt/var/tmp >> ${logfile} 2>&1 409 410# Install the system from the live CD 411# 412echo "* Starting file copy" 413cpdup -vv -o / /mnt >> ${logfile} 2>&1 414lvmexit $? 415 416cpdup -vv -o /boot /mnt/boot >> ${logfile} 2>&1 417lvmexit $? 418 419cpdup -vv -o /usr /mnt/usr >> ${logfile} 2>&1 420lvmexit $? 421 422cpdup -vv -o /var /mnt/var >> ${logfile} 2>&1 423lvmexit $? 424 425cpdup -vv -i0 /etc.hdd /mnt/etc >> ${logfile} 2>&1 426lvmexit $? 427 428chflags -R nohistory /mnt/tmp >> ${logfile} 2>&1 429chflags -R nohistory /mnt/var/tmp >> ${logfile} 2>&1 430chflags -R nohistory /mnt/var/crash >> ${logfile} 2>&1 431chflags -R nohistory /mnt/usr/obj >> ${logfile} 2>&1 432 433echo "* Adapting fstab and loader.conf" 434cat > /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 446proc /proc procfs rw 0 0 447EOF 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# 452cat > /mnt/boot/loader.conf << EOF 453dm_target_striped_load="YES" 454dm_target_linear_load="YES" 455initrd.img_load="YES" 456initrd.img_type="md_image" 457vfs.root.mountfrom="ufs:md0s0" 458vfs.root.realroot="local:hammer:/dev/main/lv_root" 459EOF 460 461# Setup interface, configuration, sshd 462# 463echo "* iface setup" 464ifc=`route -n get default | fgrep interface | awk '{ print $2; }'` 465ip=`ifconfig $ifc | fgrep inet | fgrep -v inet6 | awk '{ print $2; }'` 466lip=`echo $ip | awk -F . '{ print $4; }'` 467 468echo -n "ifconfig_$ifc=" >> /mnt/etc/rc.conf 469echo '"DHCP"' >> /mnt/etc/rc.conf 470cat >> /mnt/etc/rc.conf << EOF 471sshd_enable="YES" 472dntpd_enable="YES" 473hostname="test$lip.MYDOMAIN.XXX" 474dumpdev="/dev/main/lv_swap" 475EOF 476 477# Misc sysctls 478# 479cat >> /mnt/etc/sysctl.conf << EOF 480#net.inet.ip.portrange.first=4000 481EOF 482 483# mkinitd image 484echo "* Preparing initrd image" 485/sbin/mkinitrd -b /mnt/boot >> ${logfile} 2>&1 486 487# Warn about ssh 488echo "" 489echo "Warning:" 490echo "chroot now to /mnt and change root password and also edit" 491echo "/mnt/etc/ssh/sshd_config to allow root login and authentication" 492echo "using passwords. Alternatively, you can also just copy your" 493echo "~/.ssh/authorized_keys file to allow login using your ssh keys." 494 495echo "Installation finished successfully." 496 497 498# take CD out and reboot 499# 500