1209513Simp#!/bin/sh 2209513Simp#- 3209552Simp# Copyright (c) 2010 iXsystems, Inc. All rights reserved. 4209513Simp# 5209513Simp# Redistribution and use in source and binary forms, with or without 6209513Simp# modification, are permitted provided that the following conditions 7209513Simp# are met: 8209513Simp# 1. Redistributions of source code must retain the above copyright 9209513Simp# notice, this list of conditions and the following disclaimer. 10209513Simp# 2. Redistributions in binary form must reproduce the above copyright 11209513Simp# notice, this list of conditions and the following disclaimer in the 12209513Simp# documentation and/or other materials provided with the distribution. 13209513Simp# 14209513Simp# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15209513Simp# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16209513Simp# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17209513Simp# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18209513Simp# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19209513Simp# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20209513Simp# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21209513Simp# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22209513Simp# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23209513Simp# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24209513Simp# SUCH DAMAGE. 25209513Simp# 26209513Simp# $FreeBSD$ 27209513Simp 28209513Simp# Functions which perform the final cleanup after an install 29209513Simp 30209513Simp# Finishes up with ZFS setup before unmounting 31209513Simpzfs_cleanup_unmount() 32209513Simp{ 33209513Simp # Loop through our FS and see if we have any ZFS partitions to cleanup 34209513Simp for PART in `ls ${PARTDIR}` 35209513Simp do 36220909Sjpaetzel PARTDEV=`echo $PART | sed 's|-|/|g'` 37232899Sjpaetzel PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`" 38232899Sjpaetzel PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`" 39220909Sjpaetzel ZPOOLNAME=$(get_zpool_name "${PARTDEV}") 40209513Simp 41209513Simp if [ "$PARTFS" = "ZFS" ] 42209513Simp then 43209513Simp # Check if we have multiple zfs mounts specified 44209513Simp for ZMNT in `echo ${PARTMNT} | sed 's|,| |g'` 45209513Simp do 46209513Simp if [ "${ZMNT}" = "/" ] 47209513Simp then 48209513Simp # Make sure we haven't already added the zfs boot line when 49209513Simp # Creating a dedicated "/boot" partition 50220059Sjpaetzel cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q "vfs.root.mountfrom=" 2>/dev/null 51220059Sjpaetzel if [ $? -ne 0 ] ; then 52240165Sjpaetzel echo "vfs.root.mountfrom=\"zfs:${ZPOOLNAME}/ROOT/default\"" >> ${FSMNT}/boot/loader.conf 53209513Simp fi 54220059Sjpaetzel export FOUNDZFSROOT="${ZPOOLNAME}" 55209513Simp fi 56209513Simp done 57209513Simp FOUNDZFS="1" 58209513Simp fi 59209513Simp done 60209513Simp 61220059Sjpaetzel if [ -n "${FOUNDZFS}" ] 62209513Simp then 63209513Simp # Check if we need to add our ZFS flags to rc.conf, src.conf and loader.conf 64220059Sjpaetzel cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'zfs_load="YES"' 2>/dev/null 65220059Sjpaetzel if [ $? -ne 0 ] 66209513Simp then 67209513Simp echo 'zfs_load="YES"' >>${FSMNT}/boot/loader.conf 68209513Simp fi 69220059Sjpaetzel cat ${FSMNT}/etc/rc.conf 2>/dev/null | grep -q 'zfs_enable="YES"' 2>/dev/null 70220059Sjpaetzel if [ $? -ne 0 ] 71209513Simp then 72209513Simp echo 'zfs_enable="YES"' >>${FSMNT}/etc/rc.conf 73209513Simp fi 74209513Simp 75209513Simp sleep 2 76209513Simp # Copy over any ZFS cache data 77209513Simp cp /boot/zfs/* ${FSMNT}/boot/zfs/ 78209513Simp 79209513Simp # Copy the hostid so that our zfs cache works 80209513Simp cp /etc/hostid ${FSMNT}/etc/hostid 81209513Simp fi 82209513Simp 83209513Simp # Loop through our FS and see if we have any ZFS partitions to cleanup 84209513Simp for PART in `ls ${PARTDIR}` 85209513Simp do 86220909Sjpaetzel PARTDEV=`echo $PART | sed 's|-|/|g'` 87232899Sjpaetzel PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`" 88232899Sjpaetzel PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`" 89232899Sjpaetzel PARTENC="`cat ${PARTDIR}/${PART} | cut -d '#' -f 3`" 90220909Sjpaetzel ZPOOLNAME=$(get_zpool_name "${PARTDEV}") 91209513Simp 92209513Simp if [ "$PARTFS" = "ZFS" ] 93209513Simp then 94220909Sjpaetzel 95220909Sjpaetzel # Create a list of zpool names we can export 96220909Sjpaetzel echo $ZPOOLEXPORTS | grep -q "$ZPOOLNAME " 97220909Sjpaetzel if [ $? -ne 0 ] ; then 98220909Sjpaetzel export ZPOOLEXPORTS="$ZPOOLNAME $ZPOOLEXPORTS" 99220909Sjpaetzel fi 100220909Sjpaetzel 101209513Simp # Check if we have multiple zfs mounts specified 102209513Simp for ZMNT in `echo ${PARTMNT} | sed 's|,| |g'` 103209513Simp do 104232899Sjpaetzel ZMNT="`echo $ZMNT | cut -d '(' -f 1`" 105209513Simp PARTMNTREV="${ZMNT} ${PARTMNTREV}" 106209513Simp done 107209513Simp 108209513Simp for ZMNT in ${PARTMNTREV} 109209513Simp do 110232899Sjpaetzel if [ "${ZMNT}" = "/" ] ; then continue ; fi 111232899Sjpaetzel # Some ZFS like /swap aren't mounted, and dont need unmounting 112232899Sjpaetzel mount | grep -q "${FSMNT}${ZMNT}" 113232899Sjpaetzel if [ $? -eq 0 ] ; then 114232899Sjpaetzel rc_halt "zfs unmount ${ZPOOLNAME}${ZMNT}" 115209513Simp rc_halt "zfs set mountpoint=${ZMNT} ${ZPOOLNAME}${ZMNT}" 116209513Simp fi 117232899Sjpaetzel sleep 2 118209513Simp done 119209513Simp fi 120209513Simp done 121209513Simp 122209513Simp}; 123209513Simp 124209513Simp# Function which performs the specific setup for using a /boot partition 125209513Simpsetup_dedicated_boot_part() 126209513Simp{ 127209513Simp ROOTFS="${1}" 128209513Simp ROOTFSTYPE="${2}" 129209513Simp BOOTFS="${3}" 130209513Simp BOOTMNT="${4}" 131209513Simp 132209513Simp # Set the root mount in loader.conf 133209513Simp echo "vfs.root.mountfrom=\"${ROOTFSTYPE}:${ROOTFS}\"" >> ${FSMNT}/boot/loader.conf 134209513Simp rc_halt "mkdir -p ${FSMNT}/${BOOTMNT}/boot" 135209513Simp rc_halt "mv ${FSMNT}/boot/* ${FSMNT}${BOOTMNT}/boot/" 136209513Simp rc_halt "mv ${FSMNT}${BOOTMNT}/boot ${FSMNT}/boot/" 137220909Sjpaetzel rc_halt "umount ${BOOTFS}" 138220909Sjpaetzel rc_halt "mount ${BOOTFS} ${FSMNT}${BOOTMNT}" 139209513Simp rc_halt "rmdir ${FSMNT}/boot" 140209513Simp 141209513Simp # Strip the '/' from BOOTMNT before making symlink 142209513Simp BOOTMNTNS="`echo ${BOOTMNT} | sed 's|/||g'`" 143209513Simp rc_halt "chroot ${FSMNT} ln -s ${BOOTMNTNS}/boot /boot" 144209513Simp 145209513Simp}; 146209513Simp 147209513Simp# Function which creates the /etc/fstab for the installed system 148209513Simpsetup_fstab() 149209513Simp{ 150209513Simp FSTAB="${FSMNT}/etc/fstab" 151209513Simp rm ${FSTAB} >/dev/null 2>/dev/null 152209513Simp 153209513Simp # Create the header 154209513Simp echo "# Device Mountpoint FStype Options Dump Pass" >> ${FSTAB} 155209513Simp 156209513Simp # Loop through the partitions, and start creating /etc/fstab 157209513Simp for PART in `ls ${PARTDIR}` 158209513Simp do 159220909Sjpaetzel PARTDEV=`echo $PART | sed 's|-|/|g'` 160232899Sjpaetzel PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`" 161232899Sjpaetzel PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`" 162232899Sjpaetzel PARTENC="`cat ${PARTDIR}/${PART} | cut -d '#' -f 3`" 163232899Sjpaetzel PARTLABEL="`cat ${PARTDIR}/${PART} | cut -d '#' -f 4`" 164209513Simp 165209513Simp # Unset EXT 166209513Simp EXT="" 167209513Simp 168210700Simp # Set mount options for file-systems 169210700Simp case $PARTFS in 170210700Simp UFS+J) MNTOPTS="rw,noatime,async" ;; 171211730Simp SWAP) MNTOPTS="sw" ;; 172211730Simp *) MNTOPTS="rw,noatime" ;; 173210700Simp esac 174210700Simp 175210700Simp 176209513Simp # Figure out if we are using a glabel, or the raw name for this entry 177220059Sjpaetzel if [ -n "${PARTLABEL}" ] 178209513Simp then 179209513Simp DEVICE="label/${PARTLABEL}" 180209513Simp else 181209513Simp # Check if using encryption 182209513Simp if [ "${PARTENC}" = "ON" ] ; then 183209513Simp EXT=".eli" 184209513Simp fi 185209513Simp 186209513Simp if [ "${PARTFS}" = "UFS+J" ] ; then 187209513Simp EXT="${EXT}.journal" 188209513Simp fi 189220909Sjpaetzel DEVICE="${PARTDEV}${EXT}" 190209513Simp fi 191209513Simp 192209513Simp 193209513Simp # Set our ROOTFSTYPE for loader.conf if necessary 194209513Simp check_for_mount "${PARTMNT}" "/" 195220059Sjpaetzel if [ $? -eq 0 ] ; then 196209513Simp if [ "${PARTFS}" = "ZFS" ] ; then 197209513Simp ROOTFSTYPE="zfs" 198240165Sjpaetzel ZPOOLNAME=$(get_zpool_name "${PARTDEV}") 199240165Sjpaetzel ROOTFS="${ZPOOLNAME}/ROOT/default" 200209513Simp else 201209513Simp ROOTFS="${DEVICE}" 202209513Simp ROOTFSTYPE="ufs" 203209513Simp fi 204209513Simp fi 205209513Simp 206209513Simp # Only create non-zfs partitions 207209513Simp if [ "${PARTFS}" != "ZFS" ] 208209513Simp then 209209513Simp 210209513Simp # Make sure geom_journal is loaded 211209513Simp if [ "${PARTFS}" = "UFS+J" ] ; then 212209513Simp setup_gjournal 213209513Simp fi 214209513Simp 215209513Simp # Save the BOOTFS for call at the end 216209513Simp if [ "${PARTMNT}" = "/boot" ] ; then 217220909Sjpaetzel BOOTFS="${PARTDEV}${EXT}" 218209513Simp BOOTMNT="${BOOT_PART_MOUNT}" 219209513Simp PARTMNT="${BOOTMNT}" 220209513Simp fi 221209513Simp 222209513Simp # Echo out the fstab entry now 223209513Simp if [ "${PARTFS}" = "SWAP" ] 224209513Simp then 225222365Skevlo echo "/dev/${DEVICE} none swap ${MNTOPTS} 0 0" >> ${FSTAB} 226209513Simp else 227222365Skevlo echo "/dev/${DEVICE} ${PARTMNT} ufs ${MNTOPTS} 1 1" >> ${FSTAB} 228209513Simp fi 229209513Simp 230209513Simp fi # End of ZFS Check 231209513Simp done 232209513Simp 233209513Simp # Setup some specific PC-BSD fstab options 234209513Simp if [ "$INSTALLTYPE" != "FreeBSD" ] 235209513Simp then 236209513Simp echo "procfs /proc procfs rw 0 0" >> ${FSTAB} 237209513Simp echo "linprocfs /compat/linux/proc linprocfs rw 0 0" >> ${FSTAB} 238209513Simp fi 239209513Simp 240209513Simp # If we have a dedicated /boot, run the post-install setup of it now 241209513Simp if [ ! -z "${BOOTMNT}" ] ; then 242209513Simp setup_dedicated_boot_part "${ROOTFS}" "${ROOTFSTYPE}" "${BOOTFS}" "${BOOTMNT}" 243209513Simp fi 244209513Simp 245209513Simp}; 246209513Simp 247209513Simp# Setup our disk mirroring with gmirror 248209513Simpsetup_gmirror() 249209513Simp{ 250220059Sjpaetzel cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_mirror_load="YES"' 2>/dev/null 251220059Sjpaetzel if [ $? -ne 0 ] 252209513Simp then 253209513Simp echo 'geom_mirror_load="YES"' >>${FSMNT}/boot/loader.conf 254209513Simp fi 255209513Simp 256209513Simp}; 257209513Simp 258209513Simp# Function which saves geli keys and sets up loading of them at boot 259209513Simpsetup_geli_loading() 260209513Simp{ 261209513Simp 262209513Simp # Make our keys dir 263209513Simp mkdir -p ${FSMNT}/boot/keys >/dev/null 2>/dev/null 264209513Simp 265209513Simp cd ${GELIKEYDIR} 266220909Sjpaetzel for KEYFILE in `ls` 267209513Simp do 268209513Simp # Figure out the partition name based on keyfile name removing .key 269209513Simp PART="`echo ${KEYFILE} | cut -d '.' -f 1`" 270220909Sjpaetzel PARTDEV="`echo ${PART} | sed 's|-|/|g'`" 271220909Sjpaetzel PARTNAME="`echo ${PART} | sed 's|-dev-||g'`" 272209513Simp 273220909Sjpaetzel rc_halt "geli configure -b ${PARTDEV}" 274209513Simp 275220909Sjpaetzel # If no passphrase, setup key files 276220909Sjpaetzel if [ ! -e "${PARTDIR}-enc/${PART}-encpass" ] ; then 277220909Sjpaetzel echo "geli_${PARTNAME}_keyfile0_load=\"YES\"" >> ${FSMNT}/boot/loader.conf 278220909Sjpaetzel echo "geli_${PARTNAME}_keyfile0_type=\"${PARTNAME}:geli_keyfile0\"" >> ${FSMNT}/boot/loader.conf 279220909Sjpaetzel echo "geli_${PARTNAME}_keyfile0_name=\"/boot/keys/${PARTNAME}.key\"" >> ${FSMNT}/boot/loader.conf 280220909Sjpaetzel 281220909Sjpaetzel # Copy the key to the disk 282220909Sjpaetzel rc_halt "cp ${GELIKEYDIR}/${KEYFILE} ${FSMNT}/boot/keys/${PARTNAME}.key" 283209513Simp fi 284209513Simp 285209513Simp done 286209513Simp 287209513Simp # Make sure we have geom_eli set to load at boot 288220059Sjpaetzel cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_eli_load="YES"' 2>/dev/null 289220059Sjpaetzel if [ $? -ne 0 ] 290209513Simp then 291209513Simp echo 'geom_eli_load="YES"' >>${FSMNT}/boot/loader.conf 292209513Simp fi 293209513Simp 294209513Simp}; 295209513Simp 296209513Simp 297209513Simp# Function to generate a random hostname if none was specified 298209513Simpgen_hostname() 299209513Simp{ 300209513Simp RAND="`jot -r 1 1 9000`" 301209513Simp 302209513Simp if [ "$INSTALLTYPE" = "FreeBSD" ] 303209513Simp then 304209513Simp VAL="freebsd-${RAND}" 305209513Simp else 306209513Simp VAL="pcbsd-${RAND}" 307209513Simp fi 308209513Simp 309209513Simp export VAL 310209513Simp 311209513Simp}; 312209513Simp 313209513Simp# Function which sets up the hostname for the system 314209513Simpsetup_hostname() 315209513Simp{ 316209513Simp 317209513Simp get_value_from_cfg hostname 318209513Simp HOSTNAME="${VAL}" 319209513Simp 320209513Simp # If we don't have a hostname, make one up 321209513Simp if [ -z "${HOSTNAME}" ] 322209513Simp then 323209513Simp gen_hostname 324209513Simp HOSTNAME="${VAL}" 325209513Simp fi 326209513Simp 327209513Simp # Clean up any saved hostname 328209513Simp cat ${FSMNT}/etc/rc.conf | grep -v "hostname=" >${FSMNT}/etc/rc.conf.new 329209513Simp mv ${FSMNT}/etc/rc.conf.new ${FSMNT}/etc/rc.conf 330209513Simp 331209513Simp # Set the hostname now 332209513Simp echo_log "Setting hostname: ${HOSTNAME}" 333209513Simp echo "hostname=\"${HOSTNAME}\"" >> ${FSMNT}/etc/rc.conf 334209513Simp sed -i -e "s|my.domain|${HOSTNAME} ${HOSTNAME}|g" ${FSMNT}/etc/hosts 335209513Simp 336209513Simp}; 337209513Simp 338209513Simp 339209513Simp# Check and make sure geom_journal is enabled on the system 340209513Simpsetup_gjournal() 341209513Simp{ 342209513Simp 343209513Simp # Make sure we have geom_journal set to load at boot 344220059Sjpaetzel cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_journal_load="YES"' 2>/dev/null 345220059Sjpaetzel if [ $? -ne 0 ] 346209513Simp then 347209513Simp echo 'geom_journal_load="YES"' >>${FSMNT}/boot/loader.conf 348209513Simp fi 349209513Simp 350209513Simp}; 351209513Simp 352209513Simp# Function which sets the root password from the install config 353209513Simpset_root_pw() 354209513Simp{ 355217234Sjpaetzel # Get the plaintext string 356209513Simp get_value_from_cfg_with_spaces rootPass 357217234Sjpaetzel local PW="${VAL}" 358209513Simp 359217234Sjpaetzel # Get the encrypted string 360217234Sjpaetzel get_value_from_cfg_with_spaces rootEncPass 361217234Sjpaetzel local ENCPW="${VAL}" 362217234Sjpaetzel 363209513Simp # If we don't have a root pass, return 364217234Sjpaetzel if [ -z "${PW}" -a -z "${ENCPW}" ] ; then return 0 ; fi 365209513Simp 366209513Simp echo_log "Setting root password" 367209513Simp 368217234Sjpaetzel # Check if setting plaintext password 369220059Sjpaetzel if [ -n "${PW}" ] ; then 370217234Sjpaetzel echo "${PW}" > ${FSMNT}/.rootpw 371217234Sjpaetzel run_chroot_cmd "cat /.rootpw | pw usermod root -h 0" 372217234Sjpaetzel rc_halt "rm ${FSMNT}/.rootpw" 373217234Sjpaetzel fi 374217234Sjpaetzel 375217234Sjpaetzel # Check if setting encrypted password 376220059Sjpaetzel if [ -n "${ENCPW}" ] ; then 377217234Sjpaetzel echo "${ENCPW}" > ${FSMNT}/.rootpw 378217234Sjpaetzel run_chroot_cmd "cat /.rootpw | pw usermod root -H 0" 379217234Sjpaetzel rc_halt "rm ${FSMNT}/.rootpw" 380217234Sjpaetzel fi 381217234Sjpaetzel 382209513Simp}; 383209513Simp 384209513Simp 385209513Simprun_final_cleanup() 386209513Simp{ 387211730Simp # Check if we need to run any gmirror setup 388211730Simp ls ${MIRRORCFGDIR}/* >/dev/null 2>/dev/null 389220059Sjpaetzel if [ $? -eq 0 ] 390211730Simp then 391211730Simp # Lets setup gmirror now 392211730Simp setup_gmirror 393211730Simp fi 394209513Simp 395211730Simp # Check if we need to save any geli keys 396211730Simp ls ${GELIKEYDIR}/* >/dev/null 2>/dev/null 397220059Sjpaetzel if [ $? -eq 0 ] 398211730Simp then 399211730Simp # Lets setup geli loading 400211730Simp setup_geli_loading 401211730Simp fi 402209513Simp 403211730Simp # Set a hostname on the install system 404211730Simp setup_hostname 405209513Simp 406211730Simp # Set the root_pw if it is specified 407211730Simp set_root_pw 408209513Simp 409211730Simp # Generate the fstab for the installed system 410211730Simp setup_fstab 411209513Simp}; 412