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: releng/11.0/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh 247735 2013-03-03 23:07:27Z jpaetzel $ 27209513Simp 28209513Simp# Functions related to disk operations using bsdlabel 29209513Simp 30209513Simp# Check if we are are provided a geli password on the nextline of the config 31209513Simpcheck_for_enc_pass() 32209513Simp{ 33209513Simp CURLINE="${1}" 34209513Simp 35209513Simp get_next_cfg_line "${CFGF}" "${CURLINE}" 36220059Sjpaetzel echo ${VAL} | grep -q "^encpass=" 2>/dev/null 37220059Sjpaetzel if [ $? -eq 0 ] ; then 38209513Simp # Found a password, return it 39209513Simp get_value_from_string "${VAL}" 40209513Simp return 41209513Simp fi 42209513Simp 43220059Sjpaetzel export VAL="" 44209513Simp return 45209513Simp}; 46209513Simp 47209513Simp# On check on the disk-label line if we have any extra vars for this device 48209513Simpget_fs_line_xvars() 49209513Simp{ 50209513Simp ACTIVEDEV="${1}" 51209513Simp LINE="${2}" 52209513Simp 53234990Sjpaetzel echo $LINE | cut -d ' ' -f 4 | grep -q '(' 2>/dev/null 54234990Sjpaetzel if [ $? -ne 0 ] ; then return ; fi 55234990Sjpaetzel 56234990Sjpaetzel # See if we are looking for ZFS specific options 57234990Sjpaetzel echo $LINE | grep -q '^ZFS' 2>/dev/null 58220059Sjpaetzel if [ $? -eq 0 ] ; then 59234990Sjpaetzel ZTYPE="NONE" 60234990Sjpaetzel ZFSVARS="`echo $LINE | cut -d ' ' -f 4-20 |cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`" 61209513Simp 62234990Sjpaetzel echo $ZFSVARS | grep -qE "^(disk|file|mirror|raidz(1|2|3)?|spare|log|cache):" 2>/dev/null 63220059Sjpaetzel if [ $? -eq 0 ] ; then 64211488Simp ZTYPE=`echo $ZFSVARS | cut -f1 -d:` 65247735Sjpaetzel tmpVars=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"` 66247735Sjpaetzel ZFSVARS="" 67247735Sjpaetzel # make sure we have a '/dev' in front of the extra devices 68247735Sjpaetzel for i in $tmpVars 69247735Sjpaetzel do 70247735Sjpaetzel echo $i | grep -q '/dev/' 71247735Sjpaetzel if [ $? -ne 0 ] ; then 72247735Sjpaetzel ZFSVARS="$ZFSVARS /dev/${i}" 73247735Sjpaetzel else 74247735Sjpaetzel ZFSVARS="$ZFSVARS $i" 75247735Sjpaetzel fi 76247735Sjpaetzel done 77234990Sjpaetzel fi 78209513Simp 79234990Sjpaetzel # Return the ZFS options 80234990Sjpaetzel if [ "${ZTYPE}" = "NONE" ] ; then 81234990Sjpaetzel VAR="${ACTIVEDEV} ${ZFSVARS}" 82234990Sjpaetzel else 83234990Sjpaetzel VAR="${ZTYPE} ${ACTIVEDEV} ${ZFSVARS}" 84225657Sjpaetzel fi 85234990Sjpaetzel export VAR 86234990Sjpaetzel return 87234990Sjpaetzel fi # End of ZFS block 88225657Sjpaetzel 89234990Sjpaetzel # See if we are looking for UFS specific newfs options 90234990Sjpaetzel echo $LINE | grep -q '^UFS' 2>/dev/null 91234990Sjpaetzel if [ $? -eq 0 ] ; then 92234990Sjpaetzel FSVARS="`echo $LINE | cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`" 93234990Sjpaetzel VAR="${FSVARS}" 94234990Sjpaetzel export VAR 95234990Sjpaetzel return 96234990Sjpaetzel fi 97209513Simp 98209513Simp # If we got here, set VAR to empty and export 99220059Sjpaetzel export VAR="" 100209513Simp return 101209513Simp}; 102209513Simp 103209513Simp# Init each zfs mirror disk with a boot sector so we can failover 104211730Simpsetup_zfs_mirror_parts() 105211730Simp{ 106211730Simp _nZFS="" 107209513Simp 108234990Sjpaetzel ZTYPE="`echo ${1} | awk '{print $1}'`" 109234990Sjpaetzel 110211730Simp # Using mirroring, setup boot partitions on each disk 111234990Sjpaetzel _mirrline="`echo ${1} | sed 's|mirror ||g' | sed 's|raidz1 ||g' | sed 's|raidz2 ||g' | sed 's|raidz3 ||g' | sed 's|raidz ||g'`" 112211730Simp for _zvars in $_mirrline 113211730Simp do 114211730Simp echo "Looping through _zvars: $_zvars" >>${LOGOUT} 115220059Sjpaetzel echo "$_zvars" | grep -q "${2}" 2>/dev/null 116220059Sjpaetzel if [ $? -eq 0 ] ; then continue ; fi 117211730Simp if [ -z "$_zvars" ] ; then continue ; fi 118211730Simp 119211730Simp is_disk "$_zvars" >/dev/null 2>/dev/null 120220059Sjpaetzel if [ $? -eq 0 ] ; then 121234990Sjpaetzel echo "Setting up ZFS disk $_zvars" >>${LOGOUT} 122211730Simp init_gpt_full_disk "$_zvars" >/dev/null 2>/dev/null 123234990Sjpaetzel rc_halt "gpart add -a 4k -t freebsd-zfs ${_zvars}" >/dev/null 2>/dev/null 124234990Sjpaetzel rc_halt "gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${_zvars}" >/dev/null 2>/dev/null 125211730Simp _nZFS="$_nZFS ${_zvars}p2" 126211730Simp else 127211730Simp _nZFS="$_nZFS ${_zvars}" 128211730Simp fi 129211730Simp done 130234990Sjpaetzel echo "$ZTYPE $2 `echo $_nZFS | tr -s ' '`" 131209513Simp} ; 132209513Simp 133209513Simp# Function which creates a unique label name for the specified mount 134209513Simpgen_glabel_name() 135209513Simp{ 136209513Simp MOUNT="$1" 137209513Simp TYPE="$2" 138209513Simp NUM="0" 139209513Simp MAXNUM="20" 140209513Simp 141232899Sjpaetzel if [ "$TYPE" = "ZFS" ] ; then 142232899Sjpaetzel NAME="zpool" 143232899Sjpaetzel elif [ "$MOUNT" = "/" ] ; then 144209513Simp NAME="rootfs" 145209513Simp else 146209513Simp # If doing a swap partition, also rename it 147209513Simp if [ "${TYPE}" = "SWAP" ] 148209513Simp then 149209513Simp NAME="swap" 150209513Simp else 151209513Simp NAME="`echo $MOUNT | sed 's|/||g' | sed 's| ||g'`" 152209513Simp fi 153209513Simp fi 154209513Simp 155209513Simp # Loop through and break when we find our first available label 156209513Simp while 157209513Simp Z=1 158209513Simp do 159220059Sjpaetzel glabel status | grep -q "${NAME}${NUM}" 2>/dev/null 160220059Sjpaetzel if [ $? -ne 0 ] 161209513Simp then 162209513Simp break 163209513Simp else 164220059Sjpaetzel NUM=$((NUM+1)) 165209513Simp fi 166209513Simp 167209513Simp if [ $NUM -gt $MAXNUM ] 168209513Simp then 169209513Simp exit_err "Cannot allocate additional glabel name for $NAME" 170209513Simp break 171209513Simp fi 172209513Simp done 173209513Simp 174209513Simp 175220059Sjpaetzel export VAL="${NAME}${NUM}" 176209513Simp}; 177209513Simp 178240165Sjpaetzel# Function to determine the size we can safely use when 0 is specified 179240165Sjpaetzelget_autosize() 180240165Sjpaetzel{ 181240165Sjpaetzel # Disk tag to look for 182240165Sjpaetzel dTag="$1" 183240165Sjpaetzel 184240165Sjpaetzel # Total MB Avail 185240165Sjpaetzel get_disk_mediasize_mb "$2" 186240165Sjpaetzel local _aSize=$VAL 187240165Sjpaetzel 188240165Sjpaetzel while read line 189240165Sjpaetzel do 190240165Sjpaetzel # Check for data on this slice 191240165Sjpaetzel echo $line | grep -q "^${_dTag}-part=" 2>/dev/null 192240165Sjpaetzel if [ $? -ne 0 ] ; then continue ; fi 193240165Sjpaetzel 194240165Sjpaetzel get_value_from_string "${line}" 195240165Sjpaetzel STRING="$VAL" 196240165Sjpaetzel 197240165Sjpaetzel # Get the size of this partition 198240165Sjpaetzel SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 199240165Sjpaetzel if [ $SIZE -eq 0 ] ; then continue ; fi 200240165Sjpaetzel _aSize=`expr $_aSize - $SIZE` 201240165Sjpaetzel done <${CFGF} 202240165Sjpaetzel 203240165Sjpaetzel # Pad the size a bit 204240165Sjpaetzel _aSize=`expr $_aSize - 2` 205240165Sjpaetzel 206240165Sjpaetzel VAL="$_aSize" 207240165Sjpaetzel export VAL 208240165Sjpaetzel}; 209240165Sjpaetzel 210217229Sjpaetzel# Function to setup partitions using gpart 211217229Sjpaetzelsetup_gpart_partitions() 212209513Simp{ 213217229Sjpaetzel local _dTag="$1" 214217229Sjpaetzel local _pDisk="$2" 215217229Sjpaetzel local _wSlice="$3" 216217229Sjpaetzel local _sNum="$4" 217217229Sjpaetzel local _pType="$5" 218209513Simp FOUNDPARTS="1" 219240165Sjpaetzel USEDAUTOSIZE=0 220209513Simp 221217229Sjpaetzel # Lets read in the config file now and setup our partitions 222217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 223217229Sjpaetzel CURPART="2" 224235006Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 225235006Sjpaetzel CURPART="3" 226217229Sjpaetzel else 227217229Sjpaetzel PARTLETTER="a" 228217229Sjpaetzel CURPART="1" 229227368Sjpaetzel if [ "${_pType}" = "mbr" ] ; then 230227368Sjpaetzel rc_halt "gpart create -s BSD ${_wSlice}" 231227368Sjpaetzel fi 232217229Sjpaetzel fi 233209513Simp 234209513Simp while read line 235209513Simp do 236209513Simp # Check for data on this slice 237220059Sjpaetzel echo $line | grep -q "^${_dTag}-part=" 2>/dev/null 238220059Sjpaetzel if [ $? -eq 0 ] 239209513Simp then 240209513Simp FOUNDPARTS="0" 241209513Simp # Found a slice- entry, lets get the slice info 242209513Simp get_value_from_string "${line}" 243209513Simp STRING="$VAL" 244209513Simp 245209513Simp # We need to split up the string now, and pick out the variables 246209513Simp FS=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 1` 247209513Simp SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 248209513Simp MNT=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 3` 249209513Simp 250209513Simp # Check if we have a .eli extension on this FS 251220059Sjpaetzel echo ${FS} | grep -q ".eli" 2>/dev/null 252220059Sjpaetzel if [ $? -eq 0 ] 253209513Simp then 254209513Simp FS="`echo ${FS} | cut -d '.' -f 1`" 255209513Simp ENC="ON" 256209513Simp check_for_enc_pass "${line}" 257209513Simp if [ "${VAL}" != "" ] ; then 258209513Simp # We have a user supplied password, save it for later 259209513Simp ENCPASS="${VAL}" 260209513Simp fi 261209513Simp else 262209513Simp ENC="OFF" 263209513Simp fi 264209513Simp 265209513Simp # Check if the user tried to setup / as an encrypted partition 266209513Simp check_for_mount "${MNT}" "/" 267220059Sjpaetzel if [ $? -eq 0 -a "${ENC}" = "ON" ] 268209513Simp then 269220059Sjpaetzel export USINGENCROOT="0" 270209513Simp fi 271209513Simp 272209513Simp # Now check that these values are sane 273209513Simp case $FS in 274213647Simp UFS|UFS+S|UFS+J|UFS+SUJ|ZFS|SWAP) ;; 275209513Simp *) exit_err "ERROR: Invalid file system specified on $line" ;; 276209513Simp esac 277209513Simp 278209513Simp # Check that we have a valid size number 279209513Simp expr $SIZE + 1 >/dev/null 2>/dev/null 280220059Sjpaetzel if [ $? -ne 0 ]; then 281209513Simp exit_err "ERROR: The size specified on $line is invalid" 282209513Simp fi 283209513Simp 284209513Simp # Check that the mount-point starts with / 285220059Sjpaetzel echo "$MNT" | grep -qe "^/" -e "^none" 2>/dev/null 286220059Sjpaetzel if [ $? -ne 0 ]; then 287209513Simp exit_err "ERROR: The mount-point specified on $line is invalid" 288209513Simp fi 289209513Simp 290209513Simp if [ "$SIZE" = "0" ] 291209513Simp then 292240165Sjpaetzel if [ $USEDAUTOSIZE -eq 1 ] ; then 293240165Sjpaetzel exit_err "ERROR: You can not have two partitions with a size of 0 specified!" 294240165Sjpaetzel fi 295240165Sjpaetzel case ${_pType} in 296240165Sjpaetzel gpt|apm) get_autosize "${_dTag}" "$_pDisk" ;; 297240165Sjpaetzel *) get_autosize "${_dTag}" "$_wSlice" ;; 298240165Sjpaetzel esac 299240165Sjpaetzel SOUT="-s ${VAL}M" 300240165Sjpaetzel USEDAUTOSIZE=1 301209513Simp else 302209513Simp SOUT="-s ${SIZE}M" 303209513Simp fi 304209513Simp 305209513Simp # Check if we found a valid root partition 306209513Simp check_for_mount "${MNT}" "/" 307220059Sjpaetzel if [ $? -eq 0 ] ; then 308220059Sjpaetzel export FOUNDROOT="1" 309217229Sjpaetzel if [ "${CURPART}" = "2" -a "$_pType" = "gpt" ] ; then 310220059Sjpaetzel export FOUNDROOT="0" 311209513Simp fi 312235006Sjpaetzel if [ "${CURPART}" = "3" -a "$_pType" = "apm" ] ; then 313235006Sjpaetzel export FOUNDROOT="0" 314235006Sjpaetzel fi 315217229Sjpaetzel if [ "${CURPART}" = "1" -a "$_pType" = "mbr" ] ; then 316220059Sjpaetzel export FOUNDROOT="0" 317217229Sjpaetzel fi 318227368Sjpaetzel if [ "${CURPART}" = "1" -a "$_pType" = "gptslice" ] ; then 319227368Sjpaetzel export FOUNDROOT="0" 320227368Sjpaetzel fi 321209513Simp fi 322209513Simp 323209513Simp check_for_mount "${MNT}" "/boot" 324220059Sjpaetzel if [ $? -eq 0 ] ; then 325220059Sjpaetzel export USINGBOOTPART="0" 326217229Sjpaetzel if [ "${CURPART}" != "2" -a "${_pType}" = "gpt" ] ; then 327209513Simp exit_err "/boot partition must be first partition" 328209513Simp fi 329235006Sjpaetzel if [ "${CURPART}" != "3" -a "${_pType}" = "apm" ] ; then 330235006Sjpaetzel exit_err "/boot partition must be first partition" 331235006Sjpaetzel fi 332217229Sjpaetzel if [ "${CURPART}" != "1" -a "${_pType}" = "mbr" ] ; then 333217229Sjpaetzel exit_err "/boot partition must be first partition" 334217229Sjpaetzel fi 335227368Sjpaetzel if [ "${CURPART}" != "1" -a "${_pType}" = "gptslice" ] ; then 336227368Sjpaetzel exit_err "/boot partition must be first partition" 337227368Sjpaetzel fi 338217229Sjpaetzel 339217229Sjpaetzel if [ "${FS}" != "UFS" -a "${FS}" != "UFS+S" -a "${FS}" != "UFS+J" -a "${FS}" != "UFS+SUJ" ] ; then 340217229Sjpaetzel exit_err "/boot partition must be formatted with UFS" 341217229Sjpaetzel fi 342209513Simp fi 343209513Simp 344209513Simp # Generate a unique label name for this mount 345209513Simp gen_glabel_name "${MNT}" "${FS}" 346209513Simp PLABEL="${VAL}" 347209513Simp 348209513Simp # Get any extra options for this fs / line 349217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 350217229Sjpaetzel get_fs_line_xvars "${_pDisk}p${CURPART}" "${STRING}" 351235006Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 352235006Sjpaetzel get_fs_line_xvars "${_pDisk}s${CURPART}" "${STRING}" 353217229Sjpaetzel else 354227118Sjpaetzel get_fs_line_xvars "${_wSlice}${PARTLETTER}" "${STRING}" 355217229Sjpaetzel fi 356234990Sjpaetzel XTRAOPTS="$VAR" 357209513Simp 358209513Simp # Check if using zfs mirror 359234990Sjpaetzel echo ${XTRAOPTS} | grep -q -e "mirror" -e "raidz" 360225657Sjpaetzel if [ $? -eq 0 -a "$FS" = "ZFS" ] ; then 361227368Sjpaetzel if [ "${_pType}" = "gpt" -o "${_pType}" = "gptslice" ] ; then 362217229Sjpaetzel XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}p${CURPART}") 363235006Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 364235006Sjpaetzel XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}s${CURPART}") 365217229Sjpaetzel else 366234990Sjpaetzel XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_wSlice}${PARTLETTER}") 367217229Sjpaetzel fi 368209513Simp fi 369209513Simp 370209513Simp # Figure out the gpart type to use 371209513Simp case ${FS} in 372211730Simp ZFS) PARTYPE="freebsd-zfs" ;; 373211730Simp SWAP) PARTYPE="freebsd-swap" ;; 374211730Simp *) PARTYPE="freebsd-ufs" ;; 375209513Simp esac 376209513Simp 377209513Simp # Create the partition 378217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 379217229Sjpaetzel if [ "$CURPART" = "2" ] ; then 380217229Sjpaetzel # If this is GPT, make sure first partition is aligned to 4k 381227368Sjpaetzel sleep 2 382232901Sjpaetzel rc_halt "gpart add -a 4k ${SOUT} -t ${PARTYPE} ${_pDisk}" 383217229Sjpaetzel else 384227368Sjpaetzel sleep 2 385217229Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}" 386217229Sjpaetzel fi 387227368Sjpaetzel elif [ "${_pType}" = "gptslice" ]; then 388227368Sjpaetzel sleep 2 389227368Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_wSlice}" 390235006Sjpaetzel elif [ "${_pType}" = "apm" ]; then 391235006Sjpaetzel sleep 2 392235006Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}" 393217229Sjpaetzel else 394227368Sjpaetzel sleep 2 395217229Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} -i ${CURPART} ${_wSlice}" 396217229Sjpaetzel fi 397209513Simp 398209513Simp # Check if this is a root / boot partition, and stamp the right loader 399209513Simp for TESTMNT in `echo ${MNT} | sed 's|,| |g'` 400209513Simp do 401209513Simp if [ "${TESTMNT}" = "/" -a -z "${BOOTTYPE}" ] ; then 402209513Simp BOOTTYPE="${PARTYPE}" 403209513Simp fi 404209513Simp if [ "${TESTMNT}" = "/boot" ] ; then 405209513Simp BOOTTYPE="${PARTYPE}" 406209513Simp fi 407209513Simp done 408209513Simp 409209513Simp # Save this data to our partition config dir 410217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 411220909Sjpaetzel _dFile="`echo $_pDisk | sed 's|/|-|g'`" 412232899Sjpaetzel echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}p${CURPART} 413209513Simp 414217229Sjpaetzel # Clear out any headers 415217229Sjpaetzel sleep 2 416220059Sjpaetzel dd if=/dev/zero of=${_pDisk}p${CURPART} count=2048 2>/dev/null 417209513Simp 418217229Sjpaetzel # If we have a enc password, save it as well 419220059Sjpaetzel if [ -n "${ENCPASS}" ] ; then 420220909Sjpaetzel echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}p${CURPART}-encpass 421217229Sjpaetzel fi 422235006Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 423235006Sjpaetzel _dFile="`echo $_pDisk | sed 's|/|-|g'`" 424235006Sjpaetzel echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}s${CURPART} 425235006Sjpaetzel 426235006Sjpaetzel # Clear out any headers 427235006Sjpaetzel sleep 2 428235006Sjpaetzel dd if=/dev/zero of=${_pDisk}s${CURPART} count=2048 2>/dev/null 429235006Sjpaetzel 430235006Sjpaetzel # If we have a enc password, save it as well 431235006Sjpaetzel if [ -n "${ENCPASS}" ] ; then 432235006Sjpaetzel echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}s${CURPART}-encpass 433235006Sjpaetzel fi 434217229Sjpaetzel else 435227368Sjpaetzel # MBR Partition or GPT slice 436220909Sjpaetzel _dFile="`echo $_wSlice | sed 's|/|-|g'`" 437232899Sjpaetzel echo "${FS}#${MNT}#${ENC}#${PLABEL}#MBR#${XTRAOPTS}#${IMAGE}" >${PARTDIR}/${_dFile}${PARTLETTER} 438217229Sjpaetzel # Clear out any headers 439217229Sjpaetzel sleep 2 440220059Sjpaetzel dd if=/dev/zero of=${_wSlice}${PARTLETTER} count=2048 2>/dev/null 441217229Sjpaetzel 442217229Sjpaetzel # If we have a enc password, save it as well 443220059Sjpaetzel if [ -n "${ENCPASS}" ] ; then 444220909Sjpaetzel echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}${PARTLETTER}-encpass 445217229Sjpaetzel fi 446209513Simp fi 447209513Simp 448217229Sjpaetzel 449209513Simp # Increment our parts counter 450235006Sjpaetzel if [ "$_pType" = "gpt" -o "$_pType" = "apm" ] ; then 451220059Sjpaetzel CURPART=$((CURPART+1)) 452235006Sjpaetzel # If this is a gpt/apm partition, 453235006Sjpaetzel # we can continue and skip the MBR part letter stuff 454217229Sjpaetzel continue 455217229Sjpaetzel else 456220059Sjpaetzel CURPART=$((CURPART+1)) 457217229Sjpaetzel if [ "$CURPART" = "3" ] ; then CURPART="4" ; fi 458217229Sjpaetzel fi 459209513Simp 460217229Sjpaetzel 461217229Sjpaetzel # This partition letter is used, get the next one 462217229Sjpaetzel case ${PARTLETTER} in 463217229Sjpaetzel a) PARTLETTER="b" ;; 464217229Sjpaetzel b) PARTLETTER="d" ;; 465217229Sjpaetzel d) PARTLETTER="e" ;; 466217229Sjpaetzel e) PARTLETTER="f" ;; 467217229Sjpaetzel f) PARTLETTER="g" ;; 468217229Sjpaetzel g) PARTLETTER="h" ;; 469217229Sjpaetzel h) PARTLETTER="ERR" ;; 470217229Sjpaetzel *) exit_err "ERROR: bsdlabel only supports up to letter h for partitions." ;; 471217229Sjpaetzel esac 472217229Sjpaetzel 473209513Simp fi # End of subsection locating a slice in config 474209513Simp 475220059Sjpaetzel echo $line | grep -q "^commitDiskLabel" 2>/dev/null 476220059Sjpaetzel if [ $? -eq 0 -a "${FOUNDPARTS}" = "0" ] 477209513Simp then 478209513Simp 479209513Simp # If this is the boot disk, stamp the right gptboot 480217229Sjpaetzel if [ ! -z "${BOOTTYPE}" -a "$_pType" = "gpt" ] ; then 481209513Simp case ${BOOTTYPE} in 482217229Sjpaetzel freebsd-ufs) rc_halt "gpart bootcode -p /boot/gptboot -i 1 ${_pDisk}" ;; 483217229Sjpaetzel freebsd-zfs) rc_halt "gpart bootcode -p /boot/gptzfsboot -i 1 ${_pDisk}" ;; 484209513Simp esac 485209513Simp fi 486209513Simp 487217229Sjpaetzel # Make sure to stamp the MBR loader 488217229Sjpaetzel if [ "$_pType" = "mbr" ] ; then 489217229Sjpaetzel rc_halt "gpart bootcode -b /boot/boot ${_wSlice}" 490217229Sjpaetzel fi 491209513Simp 492209513Simp # Found our flag to commit this label setup, check that we found at least 1 partition 493232899Sjpaetzel if [ "${CURPART}" = "1" ] ; then 494209513Simp exit_err "ERROR: commitDiskLabel was called without any partition entries for it!" 495209513Simp fi 496209513Simp 497209513Simp break 498209513Simp fi 499209513Simp done <${CFGF} 500209513Simp}; 501209513Simp 502209513Simp# Reads through the config and sets up a BSDLabel for the given slice 503209513Simppopulate_disk_label() 504209513Simp{ 505209513Simp if [ -z "${1}" ] 506209513Simp then 507209513Simp exit_err "ERROR: populate_disk_label() called without argument!" 508209513Simp fi 509209513Simp 510209513Simp # Set some vars from the given working slice 511220909Sjpaetzel diskid="`echo $1 | cut -d ':' -f 1`" 512220909Sjpaetzel disk="`echo $1 | cut -d ':' -f 1 | sed 's|-|/|g'`" 513220909Sjpaetzel slicenum="`echo $1 | cut -d ':' -f 2`" 514220909Sjpaetzel type="`echo $1 | cut -d ':' -f 3`" 515209513Simp 516209513Simp # Set WRKSLICE based upon format we are using 517209513Simp if [ "$type" = "mbr" ] ; then 518220909Sjpaetzel wrkslice="${diskid}s${slicenum}" 519209513Simp fi 520235006Sjpaetzel if [ "$type" = "apm" ] ; then 521235006Sjpaetzel wrkslice="${diskid}s${slicenum}" 522235006Sjpaetzel fi 523227368Sjpaetzel if [ "$type" = "gpt" -o "$type" = "gptslice" ] ; then 524220909Sjpaetzel wrkslice="${diskid}p${slicenum}" 525209513Simp fi 526209513Simp 527220909Sjpaetzel if [ ! -e "${SLICECFGDIR}/${wrkslice}" ] ; then 528209513Simp exit_err "ERROR: Missing SLICETAG data. This shouldn't happen - please let the developers know" 529209513Simp fi 530209513Simp 531220909Sjpaetzel disktag="`cat ${SLICECFGDIR}/${wrkslice}`" 532220909Sjpaetzel slicedev="`echo $wrkslice | sed 's|-|/|g'`" 533220909Sjpaetzel 534217229Sjpaetzel # Setup the partitions with gpart 535220909Sjpaetzel setup_gpart_partitions "${disktag}" "${disk}" "${slicedev}" "${slicenum}" "${type}" 536209513Simp 537209513Simp}; 538209513Simp 539209513Simp# Function which reads in the disk slice config, and performs it 540209513Simpsetup_disk_label() 541209513Simp{ 542209513Simp # We are ready to start setting up the label, lets read the config and do the actions 543209513Simp # First confirm that we have a valid WORKINGSLICES 544213650Simp if [ -z "${WORKINGSLICES}" ]; then 545209513Simp exit_err "ERROR: No slices were setup! Please report this to the maintainers" 546209513Simp fi 547209513Simp 548209513Simp # Check that the slices we have did indeed get setup and gpart worked 549209513Simp for i in $WORKINGSLICES 550209513Simp do 551209513Simp disk="`echo $i | cut -d '-' -f 1`" 552209513Simp pnum="`echo $i | cut -d '-' -f 2`" 553209513Simp type="`echo $i | cut -d '-' -f 3`" 554220909Sjpaetzel if [ "$type" = "mbr" -a ! -e "${disk}s${pnum}" ] ; then 555209513Simp exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 556209513Simp fi 557220909Sjpaetzel if [ "$type" = "gpt" -a ! -e "${disk}p${pnum}" ] ; then 558209513Simp exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 559209513Simp fi 560235006Sjpaetzel if [ "$type" = "apm" -a ! -e "${disk}s${pnum}" ] ; then 561235006Sjpaetzel exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 562235006Sjpaetzel fi 563227368Sjpaetzel if [ "$type" = "gptslice" -a ! -e "${disk}p${pnum}" ] ; then 564227368Sjpaetzel exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 565227368Sjpaetzel fi 566209513Simp done 567209513Simp 568209513Simp # Setup some files which we'll be referring to 569220059Sjpaetzel export LABELLIST="${TMPDIR}/workingLabels" 570209513Simp rm $LABELLIST >/dev/null 2>/dev/null 571209513Simp 572209513Simp # Set our flag to determine if we've got a valid root partition in this setup 573220059Sjpaetzel export FOUNDROOT="-1" 574209513Simp 575209513Simp # Check if we are using a /boot partition 576220059Sjpaetzel export USINGBOOTPART="1" 577209513Simp 578209513Simp # Set encryption on root check 579220059Sjpaetzel export USINGENCROOT="1" 580209513Simp 581209513Simp # Make the tmp directory where we'll store FS info & mount-points 582209513Simp rm -rf ${PARTDIR} >/dev/null 2>/dev/null 583209513Simp mkdir -p ${PARTDIR} >/dev/null 2>/dev/null 584209513Simp rm -rf ${PARTDIR}-enc >/dev/null 2>/dev/null 585209513Simp mkdir -p ${PARTDIR}-enc >/dev/null 2>/dev/null 586209513Simp 587209513Simp for i in $WORKINGSLICES 588209513Simp do 589209513Simp populate_disk_label "${i}" 590209513Simp done 591209513Simp 592209513Simp # Check if we made a root partition 593209513Simp if [ "$FOUNDROOT" = "-1" ] 594209513Simp then 595209513Simp exit_err "ERROR: No root (/) partition specified!!" 596209513Simp fi 597209513Simp 598209513Simp # Check if we made a root partition 599209513Simp if [ "$FOUNDROOT" = "1" -a "${USINGBOOTPART}" != "0" ] 600209513Simp then 601209513Simp exit_err "ERROR: (/) partition isn't first partition on disk!" 602209513Simp fi 603209513Simp 604209513Simp if [ "${USINGENCROOT}" = "0" -a "${USINGBOOTPART}" != "0" ] 605209513Simp then 606209513Simp exit_err "ERROR: Can't encrypt (/) with no (/boot) partition!" 607209513Simp fi 608209513Simp}; 609209513Simp 610212337Simpcheck_fstab_mbr() 611212337Simp{ 612212337Simp local SLICE 613212337Simp local FSTAB 614212337Simp 615212337Simp if [ -z "$2" ] 616212337Simp then 617212337Simp return 1 618212337Simp fi 619212337Simp 620212337Simp SLICE="$1" 621212337Simp FSTAB="$2/etc/fstab" 622212337Simp 623212337Simp if [ -f "${FSTAB}" ] 624212337Simp then 625212337Simp PARTLETTER=`echo "$SLICE" | sed -E 's|^.+([a-h])$|\1|'` 626212337Simp 627220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1 628220059Sjpaetzel if [ $? -eq 0 ] 629212337Simp then 630212337Simp if [ "${PARTLETTER}" = "a" ] 631212337Simp then 632212337Simp FOUNDROOT="0" 633212337Simp else 634212337Simp FOUNDROOT="1" 635212337Simp fi 636213650Simp 637213650Simp ROOTIMAGE="1" 638213650Simp 639212337Simp export FOUNDROOT 640213650Simp export ROOTIMAGE 641212337Simp fi 642212337Simp 643220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1 644220059Sjpaetzel if [ $? -eq 0 ] 645212337Simp then 646212337Simp if [ "${PARTLETTER}" = "a" ] 647212337Simp then 648212337Simp USINGBOOTPART="0" 649212337Simp else 650212337Simp exit_err "/boot partition must be first partition" 651212337Simp fi 652212337Simp export USINGBOOTPART 653212337Simp fi 654212337Simp 655212337Simp return 0 656212337Simp fi 657212337Simp 658212337Simp return 1 659212337Simp}; 660212337Simp 661212337Simpcheck_fstab_gpt() 662212337Simp{ 663212337Simp local SLICE 664212337Simp local FSTAB 665212337Simp 666212337Simp if [ -z "$2" ] 667212337Simp then 668212337Simp return 1 669212337Simp fi 670212337Simp 671212337Simp SLICE="$1" 672212337Simp FSTAB="$2/etc/fstab" 673212337Simp 674212337Simp if [ -f "${FSTAB}" ] 675212337Simp then 676212337Simp PARTNUMBER=`echo "${SLICE}" | sed -E 's|^.+p([0-9]*)$|\1|'` 677212337Simp 678220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1 679220059Sjpaetzel if [ $? -eq 0 ] 680212337Simp then 681212337Simp if [ "${PARTNUMBER}" = "2" ] 682212337Simp then 683212337Simp FOUNDROOT="0" 684212337Simp else 685212337Simp FOUNDROOT="1" 686212337Simp fi 687213650Simp 688213650Simp ROOTIMAGE="1" 689213650Simp 690212337Simp export FOUNDROOT 691213650Simp export ROOTIMAGE 692212337Simp fi 693212337Simp 694220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1 695220059Sjpaetzel if [ $? -eq 0 ] 696212337Simp then 697212337Simp if [ "${PARTNUMBER}" = "2" ] 698212337Simp then 699212337Simp USINGBOOTPART="0" 700212337Simp else 701212337Simp exit_err "/boot partition must be first partition" 702212337Simp fi 703212337Simp export USINGBOOTPART 704212337Simp fi 705212337Simp 706212337Simp return 0 707212337Simp fi 708212337Simp 709212337Simp 710212337Simp return 1 711212337Simp}; 712212337Simp 713213650Simpcheck_disk_layout() 714212337Simp{ 715212337Simp local SLICES 716212337Simp local TYPE 717213650Simp local DISK 718212337Simp local RES 719212337Simp local F 720212337Simp 721213650Simp DISK="$1" 722212337Simp TYPE="MBR" 723212337Simp 724213650Simp if [ -z "${DISK}" ] 725212337Simp then 726212337Simp return 1 727212337Simp fi 728212337Simp 729213650Simp SLICES_MBR=`ls /dev/${DISK}s[1-4]*[a-h]* 2>/dev/null` 730213650Simp SLICES_GPT=`ls /dev/${DISK}p[0-9]* 2>/dev/null` 731213650Simp SLICES_SLICE=`ls /dev/${DISK}[a-h]* 2>/dev/null` 732213650Simp 733213650Simp if [ -n "${SLICES_MBR}" ] 734212337Simp then 735213650Simp SLICES="${SLICES_MBR}" 736213650Simp TYPE="MBR" 737213650Simp RES=0 738212337Simp fi 739213650Simp if [ -n "${SLICES_GPT}" ] 740212337Simp then 741213650Simp SLICES="${SLICES_GPT}" 742213650Simp TYPE="GPT" 743212337Simp RES=0 744212337Simp fi 745213650Simp if [ -n "${SLICES_SLICE}" ] 746213650Simp then 747213650Simp SLICES="${SLICES_SLICE}" 748213650Simp TYPE="MBR" 749213650Simp RES=0 750213650Simp fi 751213650Simp 752212337Simp for slice in ${SLICES} 753212337Simp do 754212337Simp F=1 755212337Simp mount ${slice} /mnt 2>/dev/null 756220059Sjpaetzel if [ $? -ne 0 ] 757212337Simp then 758212337Simp continue 759212337Simp fi 760212337Simp 761212337Simp if [ "${TYPE}" = "MBR" ] 762212337Simp then 763212337Simp check_fstab_mbr "${slice}" "/mnt" 764212337Simp F="$?" 765212337Simp 766212337Simp elif [ "${TYPE}" = "GPT" ] 767212337Simp then 768212337Simp check_fstab_gpt "${slice}" "/mnt" 769212337Simp F="$?" 770212337Simp fi 771212337Simp 772220059Sjpaetzel if [ ${F} -eq 0 ] 773212337Simp then 774212337Simp umount /mnt 775212337Simp break 776212337Simp fi 777212337Simp 778212337Simp umount /mnt 779212337Simp done 780212337Simp 781212337Simp return ${RES} 782212337Simp}; 783