From: Antonio Huete Jimenez Date: Wed, 1 Feb 2012 23:00:46 +0000 (+0100) Subject: rconfig - LVM stripe script X-Git-Tag: v3.4.0rc~1302 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/a816ce8e217e98e622474a79fb633b37dc22092e rconfig - LVM stripe script 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. --- diff --git a/share/examples/rconfig/hammer_lvm_stripe.sh b/share/examples/rconfig/hammer_lvm_stripe.sh new file mode 100644 index 0000000000..16afd2b89e --- /dev/null +++ b/share/examples/rconfig/hammer_lvm_stripe.sh @@ -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 <> /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 +#