rconfig - LVM stripe script
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Wed, 1 Feb 2012 23:00:46 +0000 (00:00 +0100)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Wed, 1 Feb 2012 23:00:46 +0000 (00:00 +0100)
It uses lvm(8) facilities to install a DragonFly system in a
logical volume made of as many disk as you specify in the disk
list. It creates a swap partition and a /boot UFS filesystem
as it is required for proper operation.

share/examples/rconfig/hammer_lvm_stripe.sh [new file with mode: 0644]

diff --git a/share/examples/rconfig/hammer_lvm_stripe.sh b/share/examples/rconfig/hammer_lvm_stripe.sh
new file mode 100644 (file)
index 0000000..16afd2b
--- /dev/null
@@ -0,0 +1,508 @@
+#!/bin/sh
+#
+# This script takes in account a disk list to make a lvm(8) stripe
+# which will contain a hammer filesystem and the swap partition.
+#
+# Be aware that this is just to provide _basic_ installation
+# functionalities and it may need actions from the sysadmin to
+# properly install and get a consistent installed system.
+
+# set -x
+
+export LVM_SUPPRESS_FD_WARNINGS=1
+
+disklist="da0 da1"
+bootdisk=""
+logfile="/tmp/hammer_lvm_stripe.log"
+
+#
+# err exitval message
+#     Display an error and exit
+#
+err()
+{
+    exitval=$1
+    shift
+
+    echo 1>&2 "$0: ERROR: $*"
+    exit $exitval
+}
+
+#
+# cktmpdir
+#
+#     Checks whether /tmp is writeable.
+#     Exit if not
+#
+cktmpdir()
+{
+    mktemp "/tmp/XXX" >> ${logfile} 2>&1
+
+    if [ $? -ne 0 ]; then
+       err 1 "/tmp directory must be writeable"
+    fi
+}
+
+#
+# ckpreinstall
+#
+#     Checks whether lv nodes exist which would may
+#     indicate an installation already succeeded or
+#     a previous failed one.
+#
+ckpreinstall()
+{
+
+    # Try to activate the volume first
+    vgchange -a y main >> ${logfile} 2>&1
+
+    if [ -c /dev/mapper/main-lv_root -o -c /dev/mapper/main-lv_swap ]; then
+       echo " ERROR: Either a previous installation failed or your installation"
+       echo " is already done. If the former, please follow instructions below."
+       echo ""
+
+       lvmexit
+    fi
+}
+
+
+#
+# ckstatus status progname
+#
+#     Checks exit status of programs and if it fails
+#     it exists with a message
+#
+ckstatus()
+{
+    local st=$1
+    local prog=$2
+
+    if [ ${st} -ne 0 ]; then
+       err 1 "Failed to run $2. Check ${logfile}"
+    fi
+}
+
+#
+# ckloadmod modname
+#
+#     Checks if a module is loaded, if not
+#     it tries to load it. In case of failure
+#     it exits
+#
+ckloadmod()
+{
+    local mod=$1
+
+    if ! kldstat -q -m ${mod}; then
+       kldload $1 >> ${logfile} 2>&1
+
+       if [ $? -ne 0 ]; then
+           err 1 "Could not load ${mod}"
+        fi
+    fi
+}
+
+#
+# prepdisk disk
+#
+#     Clears the first sectors of the disk
+#     and then prepares the disk for disklabel.
+#     It also installs bootblocks in the first
+#     disk of the list.
+#
+prepdisk()
+{
+    local disk=$1
+
+    # Hey don't shoot yourself in the foot
+    if [ ! "$disk" = "" ]; then
+       mount | fgrep ${disk} >> ${logfile} 2>&1
+
+       if [ $? -ne 1 ]; then
+           err 1 "${disk} is already being used, aborting"
+       fi
+    fi
+
+    if [ "${bootdisk}" = "" ]; then
+       bootdisk=${disk}
+    fi
+
+    dd if=/dev/zero of=/dev/${disk} bs=32k count=16 >> ${logfile} 2>&1
+    ckstatus $? "dd"
+
+    fdisk -IB ${disk} >> ${logfile} 2>&1
+    ckstatus $? "fdisk"
+
+    disklabel -r -w ${disk}s1 auto >> ${logfile} 2>&1
+    ckstatus $? "disklabel"
+
+    if [ ! "${bootdisk}" = "" ]; then
+       disklabel -B ${disk}s1 >> ${logfile} 2>&1
+       ckstatus $? "disklabel"
+    fi
+}
+
+#
+# mklabel disk
+#
+#     Create same labels for every disk
+#     except for the disk that will contain
+#     /boot partition
+#
+mklabel()
+{
+    local disk=$1
+
+    disklabel ${disk}s1 > /tmp/label
+    ckstatus $? "disklabel"
+
+    if [ "${disk}" = "${bootdisk}" ]; then
+       cat >> /tmp/label <<EOF
+ a: 768m 0 4.2BSD
+ d: * * unknown
+EOF
+    else
+       cat >> /tmp/label <<EOF
+ d: * * unknown
+EOF
+
+    fi
+
+    disklabel -R ${disk}s1 /tmp/label >> ${logfile} 2>&1
+    ckstatus $? "disklabel"
+}
+
+
+#
+# lvmexit
+#
+#     lvm exit message
+lvmexit()
+{
+    local status=$1
+
+    if [ $# -ne 0 ]; then
+       if [ ${status} -eq 0 ]; then
+           return
+       fi
+    fi
+
+    echo " There was an error during or after LVM operations for this"
+    echo " installation and those operations done cannot be reverted"
+    echo " by the script itself. Please revert them manually:"
+    echo ""
+    echo " Basically you need to perform these steps:"
+    echo "   1. Remove all logical volumes in VG main (lv_swap, lv_root)"
+    echo "   2. Remove main volume group"
+    echo "   3. Remove all the physical volumes. PVs are all in [disk]1d"
+    echo "      For example, if you have 2 disks, you need to remove:"
+    echo "        /sbin/pvremove /dev/da0s1d"
+    echo "        /sbin/pvremove /dev/da1s1d"
+    echo ""
+    exit 1
+}
+
+#
+# rev_lvmops
+#
+#     Revert all lvmops
+#
+rev_lvmops()
+{
+
+    vgchange -a n main >> ${logfile} 2>&1
+
+    lvremove --force lv_swap main >> ${logfile} 2>&1
+    if [ $? -ne 0 ]; then
+        lvmexit
+    fi
+
+    lvremove --force lv_root main >> ${logfile} 2>&1
+    if [ $? -ne 0 ]; then
+        lvmexit
+    fi
+
+    vgremove --force main >> ${logfile} 2>&1
+    if [ $? -ne 0 ]; then
+        lvmexit
+    fi
+
+    for disk in ${disklist}
+    do
+       pvremove /dev/${disk}s1d >> ${logfile} 2>&1
+    done
+}
+
+#
+# lvmops
+#
+#     Create physical volumes, volume group 'main' and
+#     the ROOT hammer filesystem where everything will
+#     be installed. swap is also created as a log. volume.
+#
+lvmops()
+{
+    local lst=""
+    local tmp=""
+
+    for disk in ${disklist}
+    do
+       pvcreate /dev/${disk}s1d >> ${logfile} 2>&1
+       if [ $? -ne 0 ]; then
+           rev_lvmops
+        fi
+       tmp=${lst}
+       lst="${tmp} /dev/${disk}s1d"
+
+       # Be safe
+       sync
+       sleep 1
+    done
+
+    # Do a full scan in the hope the lvm
+    # cache is rebuilt
+    pvscan >> ${logfile} 2>&1
+
+    vgcreate main ${lst} >> ${logfile} 2>&1
+    if [ $? -ne 0 ]; then
+        rev_lvmops
+    fi
+
+    # We need to sync and wait for some secs to settle
+    # Otherwise /dev/main won't appear
+    echo "     Settling LVM operations (5 secs)"
+    sync
+    sleep 5
+    vgscan >> ${logfile} 2>&1
+
+    lvcreate -Z n -n lv_swap -L ${memtotal} main >> ${logfile} 2>&1
+    if [ $? -ne 0 ]; then
+        rev_lvmops
+    fi
+
+    # We sync in every lvm operation
+    sync
+    lvscan >> ${logfile} 2>&1
+    sleep 1
+
+    lvcreate -Z n -n lv_root -l 100%FREE main >> ${logfile} 2>&1
+    if [ $? -ne 0 ]; then
+        rev_lvmops
+    fi
+
+}
+
+echo "ALL DATA IN DISKS ${disklist} WILL BE LOST!"
+echo "Press ^C to abort."
+for n in 10 9 8 7 6 5 4 3 2 1
+do
+    echo -n " ${n}"
+    sleep 1
+done
+echo ""
+
+# /tmp has to be writeable
+echo "* Checking /tmp is writeable"
+cktmpdir
+
+rm "${logfile}" >> ${logfile} 2>&1
+echo "* Output to ${logfile}"
+
+# calculate memory
+tmp=`sysctl hw.physmem | cut -w -f 2`
+memtotal=`expr ${tmp} / 1024 / 1024`
+
+# kldload needed modules and start udevd
+echo "* Loading modules"
+ckloadmod dm_target_striped >> ${logfile} 2>&1
+ckloadmod dm_target_linear >> ${logfile} 2>&1
+/sbin/udevd >> ${logfile} 2>&1
+
+# check previous installations
+ckpreinstall
+
+# Unmount any prior mounts on /mnt, reverse order to unwind
+# sub-directory mounts.
+#
+for mount in `df | fgrep /mnt | awk '{ print $6; }' | tail -r`
+do
+    echo " Umounting ${mount}"
+    umount ${mount} >> ${logfile} 2>&1
+done
+
+# Prepare the disks in the list
+for disk in ${disklist}
+do
+    echo "* Preparing disk ${disk}"
+    prepdisk ${disk}
+    mklabel ${disk}
+    pvscan >> ${logfile} 2>&1
+done
+
+# lvm(8) operations in the disks
+echo "* Performing LVM operations"
+lvmops
+
+# Format the volumes
+echo "* Formating ${bootdisk} and LVs lv_root"
+newfs /dev/${bootdisk}s1a >> ${logfile} 2>&1
+lvmexit $?
+
+newfs_hammer -f -L ROOT /dev/main/lv_root >> ${logfile} 2>&1
+lvmexit $?
+
+# Mount it
+#
+echo "* Mounting everything"
+mount_hammer /dev/main/lv_root /mnt >> ${logfile} 2>&1
+lvmexit $?
+
+mkdir /mnt/boot
+
+mount /dev/${bootdisk}s1a /mnt/boot >> ${logfile} 2>&1
+lvmexit $?
+
+# Create PFS mount points for nullfs.
+pfslist="usr usr.obj var var.crash var.tmp tmp home"
+
+mkdir /mnt/pfs
+
+for pfs in ${pfslist}
+do
+    hammer pfs-master /mnt/pfs/$pfs >> ${logfile} 2>&1
+    lvmexit $?
+done
+
+# Mount /usr and /var so that you can add subdirs
+mkdir /mnt/usr >> ${logfile} 2>&1
+mkdir /mnt/var >> ${logfile} 2>&1
+mount_null /mnt/pfs/usr /mnt/usr >> ${logfile} 2>&1
+lvmexit $?
+
+mount_null /mnt/pfs/var /mnt/var >> ${logfile} 2>&1
+lvmexit $?
+
+mkdir /mnt/usr/obj >> ${logfile} 2>&1
+mkdir /mnt/var/tmp >> ${logfile} 2>&1
+mkdir /mnt/var/crash >> ${logfile} 2>&1
+
+mkdir /mnt/tmp >> ${logfile} 2>&1
+mkdir /mnt/home >> ${logfile} 2>&1
+
+mount_null /mnt/pfs/tmp /mnt/tmp >> ${logfile} 2>&1
+lvmexit $?
+
+mount_null /mnt/pfs/home /mnt/home >> ${logfile} 2>&1
+lvmexit $?
+
+mount_null /mnt/pfs/var.tmp /mnt/var/tmp >> ${logfile} 2>&1
+lvmexit $?
+
+mount_null /mnt/pfs/var.crash /mnt/var/crash >> ${logfile} 2>&1
+lvmexit $?
+
+mount_null /mnt/pfs/usr.obj /mnt/usr/obj >> ${logfile} 2>&1
+lvmexit $?
+
+chmod 1777 /mnt/tmp >> ${logfile} 2>&1
+chmod 1777 /mnt/var/tmp >> ${logfile} 2>&1
+
+# Install the system from the live CD
+#
+echo "* Starting file copy"
+cpdup -vv -o / /mnt >> ${logfile} 2>&1
+lvmexit $?
+
+cpdup -vv -o /boot /mnt/boot >> ${logfile} 2>&1
+lvmexit $?
+
+cpdup -vv -o /usr /mnt/usr >> ${logfile} 2>&1
+lvmexit $?
+
+cpdup -vv -o /var /mnt/var >> ${logfile} 2>&1
+lvmexit $?
+
+cpdup -vv -i0 /etc.hdd /mnt/etc >> ${logfile} 2>&1
+lvmexit $?
+
+chflags -R nohistory /mnt/tmp >> ${logfile} 2>&1
+chflags -R nohistory /mnt/var/tmp >> ${logfile} 2>&1
+chflags -R nohistory /mnt/var/crash >> ${logfile} 2>&1
+chflags -R nohistory /mnt/usr/obj >> ${logfile} 2>&1
+
+echo "* Adapting fstab and loader.conf"
+cat > /mnt/etc/fstab << EOF
+# Device               Mountpoint      FStype  Options         Dump    Pass#
+/dev/main/lv_root      /               hammer  rw              1       1
+/dev/${bootdisk}s1a    /boot           ufs     rw              1       1
+/dev/main/lv_swap      none            swap    sw              0       0
+/pfs/usr               /usr            null    rw              0       0
+/pfs/var               /var            null    rw              0       0
+/pfs/tmp               /tmp            null    rw              0       0
+/pfs/home              /home           null    rw              0       0
+/pfs/var.tmp           /var/tmp        null    rw              0       0
+/pfs/usr.obj           /usr/obj        null    rw              0       0
+/pfs/var.crash         /var/crash      null    rw              0       0
+proc                   /proc           procfs  rw              0       0
+EOF
+
+# Because root is not on the boot partition we have to tell the loader
+# to tell the kernel where root is.
+#
+cat > /mnt/boot/loader.conf << EOF
+dm_target_striped_load="YES"
+dm_target_linear_load="YES"
+initrd.img_load="YES"
+initrd.img_type="md_image"
+vfs.root.mountfrom="ufs:md0s0"
+vfs.root.realroot="local:hammer:/dev/main/lv_root"
+EOF
+
+# Setup interface, configuration, sshd
+#
+echo "* iface setup"
+ifc=`route -n get default | fgrep interface | awk '{ print $2; }'`
+ip=`ifconfig $ifc | fgrep inet | fgrep -v inet6 | awk '{ print $2; }'`
+lip=`echo $ip | awk -F . '{ print $4; }'`
+
+echo -n "ifconfig_$ifc=" >> /mnt/etc/rc.conf
+echo '"DHCP"' >> /mnt/etc/rc.conf
+cat >> /mnt/etc/rc.conf << EOF
+sshd_enable="YES"
+dntpd_enable="YES"
+hostname="test$lip.MYDOMAIN.XXX"
+dumpdev="/dev/main/lv_swap"
+EOF
+
+# Misc sysctls
+#
+cat >> /mnt/etc/sysctl.conf << EOF
+#net.inet.ip.portrange.first=4000
+EOF
+
+# adjust work directory for pkgsrc in case we want
+# to mount /usr/pkgsrc read-only.
+#
+cat >> /mnt/usr/pkg/etc/mk.conf << EOF
+.ifdef BSD_PKG_MK       # begin pkgsrc settings
+WRKOBJDIR=             /usr/obj/pkgsrc
+.endif                  # end pkgsrc settings
+EOF
+
+# mkinitd image
+echo "* Preparing initrd image"
+/sbin/mkinitrd -b /mnt/boot >> ${logfile} 2>&1
+
+# Warn about ssh
+echo ""
+echo "Warning:"
+echo "chroot now to /mnt and change root password and also edit"
+echo "/mnt/etc/ssh/sshd_config to allow root login and authentication"
+echo "using passwords. Alternatively, you can also just copy your"
+echo "~/.ssh/authorized_keys file to allow login using your ssh keys."
+
+echo "Installation finished successfully."
+
+
+# take CD out and reboot
+#