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 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 53235445Sjpaetzel echo $LINE | cut -d ' ' -f 4 | grep -q '(' 2>/dev/null 54235445Sjpaetzel if [ $? -ne 0 ] ; then return ; fi 55235445Sjpaetzel 56235445Sjpaetzel # See if we are looking for ZFS specific options 57235445Sjpaetzel echo $LINE | grep -q '^ZFS' 2>/dev/null 58220059Sjpaetzel if [ $? -eq 0 ] ; then 59235445Sjpaetzel ZTYPE="NONE" 60235445Sjpaetzel ZFSVARS="`echo $LINE | cut -d ' ' -f 4-20 |cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`" 61209513Simp 62235445Sjpaetzel 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:` 65211488Simp ZFSVARS=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"` 66235445Sjpaetzel fi 67209513Simp 68235445Sjpaetzel # Return the ZFS options 69235445Sjpaetzel if [ "${ZTYPE}" = "NONE" ] ; then 70235445Sjpaetzel VAR="${ACTIVEDEV} ${ZFSVARS}" 71235445Sjpaetzel else 72235445Sjpaetzel VAR="${ZTYPE} ${ACTIVEDEV} ${ZFSVARS}" 73225657Sjpaetzel fi 74235445Sjpaetzel export VAR 75235445Sjpaetzel return 76235445Sjpaetzel fi # End of ZFS block 77225657Sjpaetzel 78235445Sjpaetzel # See if we are looking for UFS specific newfs options 79235445Sjpaetzel echo $LINE | grep -q '^UFS' 2>/dev/null 80235445Sjpaetzel if [ $? -eq 0 ] ; then 81235445Sjpaetzel FSVARS="`echo $LINE | cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`" 82235445Sjpaetzel VAR="${FSVARS}" 83235445Sjpaetzel export VAR 84235445Sjpaetzel return 85235445Sjpaetzel fi 86209513Simp 87209513Simp # If we got here, set VAR to empty and export 88220059Sjpaetzel export VAR="" 89209513Simp return 90209513Simp}; 91209513Simp 92209513Simp# Init each zfs mirror disk with a boot sector so we can failover 93211730Simpsetup_zfs_mirror_parts() 94211730Simp{ 95211730Simp _nZFS="" 96209513Simp 97235445Sjpaetzel ZTYPE="`echo ${1} | awk '{print $1}'`" 98235445Sjpaetzel 99211730Simp # Using mirroring, setup boot partitions on each disk 100235445Sjpaetzel _mirrline="`echo ${1} | sed 's|mirror ||g' | sed 's|raidz1 ||g' | sed 's|raidz2 ||g' | sed 's|raidz3 ||g' | sed 's|raidz ||g'`" 101211730Simp for _zvars in $_mirrline 102211730Simp do 103211730Simp echo "Looping through _zvars: $_zvars" >>${LOGOUT} 104220059Sjpaetzel echo "$_zvars" | grep -q "${2}" 2>/dev/null 105220059Sjpaetzel if [ $? -eq 0 ] ; then continue ; fi 106211730Simp if [ -z "$_zvars" ] ; then continue ; fi 107211730Simp 108211730Simp is_disk "$_zvars" >/dev/null 2>/dev/null 109220059Sjpaetzel if [ $? -eq 0 ] ; then 110235445Sjpaetzel echo "Setting up ZFS disk $_zvars" >>${LOGOUT} 111211730Simp init_gpt_full_disk "$_zvars" >/dev/null 2>/dev/null 112235445Sjpaetzel rc_halt "gpart add -a 4k -t freebsd-zfs ${_zvars}" >/dev/null 2>/dev/null 113235445Sjpaetzel rc_halt "gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${_zvars}" >/dev/null 2>/dev/null 114211730Simp _nZFS="$_nZFS ${_zvars}p2" 115211730Simp else 116211730Simp _nZFS="$_nZFS ${_zvars}" 117211730Simp fi 118211730Simp done 119235445Sjpaetzel echo "$ZTYPE $2 `echo $_nZFS | tr -s ' '`" 120209513Simp} ; 121209513Simp 122209513Simp# Function which creates a unique label name for the specified mount 123209513Simpgen_glabel_name() 124209513Simp{ 125209513Simp MOUNT="$1" 126209513Simp TYPE="$2" 127209513Simp NUM="0" 128209513Simp MAXNUM="20" 129209513Simp 130233224Sjpaetzel if [ "$TYPE" = "ZFS" ] ; then 131233224Sjpaetzel NAME="zpool" 132233224Sjpaetzel elif [ "$MOUNT" = "/" ] ; then 133209513Simp NAME="rootfs" 134209513Simp else 135209513Simp # If doing a swap partition, also rename it 136209513Simp if [ "${TYPE}" = "SWAP" ] 137209513Simp then 138209513Simp NAME="swap" 139209513Simp else 140209513Simp NAME="`echo $MOUNT | sed 's|/||g' | sed 's| ||g'`" 141209513Simp fi 142209513Simp fi 143209513Simp 144209513Simp # Loop through and break when we find our first available label 145209513Simp while 146209513Simp Z=1 147209513Simp do 148220059Sjpaetzel glabel status | grep -q "${NAME}${NUM}" 2>/dev/null 149220059Sjpaetzel if [ $? -ne 0 ] 150209513Simp then 151209513Simp break 152209513Simp else 153220059Sjpaetzel NUM=$((NUM+1)) 154209513Simp fi 155209513Simp 156209513Simp if [ $NUM -gt $MAXNUM ] 157209513Simp then 158209513Simp exit_err "Cannot allocate additional glabel name for $NAME" 159209513Simp break 160209513Simp fi 161209513Simp done 162209513Simp 163209513Simp 164220059Sjpaetzel export VAL="${NAME}${NUM}" 165209513Simp}; 166209513Simp 167240315Sjpaetzel# Function to determine the size we can safely use when 0 is specified 168240315Sjpaetzelget_autosize() 169240315Sjpaetzel{ 170240315Sjpaetzel # Disk tag to look for 171240315Sjpaetzel dTag="$1" 172240315Sjpaetzel 173240315Sjpaetzel # Total MB Avail 174240315Sjpaetzel get_disk_mediasize_mb "$2" 175240315Sjpaetzel local _aSize=$VAL 176240315Sjpaetzel 177240315Sjpaetzel while read line 178240315Sjpaetzel do 179240315Sjpaetzel # Check for data on this slice 180240315Sjpaetzel echo $line | grep -q "^${_dTag}-part=" 2>/dev/null 181240315Sjpaetzel if [ $? -ne 0 ] ; then continue ; fi 182240315Sjpaetzel 183240315Sjpaetzel get_value_from_string "${line}" 184240315Sjpaetzel STRING="$VAL" 185240315Sjpaetzel 186240315Sjpaetzel # Get the size of this partition 187240315Sjpaetzel SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 188240315Sjpaetzel if [ $SIZE -eq 0 ] ; then continue ; fi 189240315Sjpaetzel _aSize=`expr $_aSize - $SIZE` 190240315Sjpaetzel done <${CFGF} 191240315Sjpaetzel 192240315Sjpaetzel # Pad the size a bit 193240315Sjpaetzel _aSize=`expr $_aSize - 2` 194240315Sjpaetzel 195240315Sjpaetzel VAL="$_aSize" 196240315Sjpaetzel export VAL 197240315Sjpaetzel}; 198240315Sjpaetzel 199217229Sjpaetzel# Function to setup partitions using gpart 200217229Sjpaetzelsetup_gpart_partitions() 201209513Simp{ 202217229Sjpaetzel local _dTag="$1" 203217229Sjpaetzel local _pDisk="$2" 204217229Sjpaetzel local _wSlice="$3" 205217229Sjpaetzel local _sNum="$4" 206217229Sjpaetzel local _pType="$5" 207209513Simp FOUNDPARTS="1" 208240315Sjpaetzel USEDAUTOSIZE=0 209209513Simp 210217229Sjpaetzel # Lets read in the config file now and setup our partitions 211217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 212217229Sjpaetzel CURPART="2" 213235447Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 214235447Sjpaetzel CURPART="3" 215217229Sjpaetzel else 216217229Sjpaetzel PARTLETTER="a" 217217229Sjpaetzel CURPART="1" 218232415Sjpaetzel if [ "${_pType}" = "mbr" ] ; then 219232415Sjpaetzel rc_halt "gpart create -s BSD ${_wSlice}" 220232415Sjpaetzel fi 221217229Sjpaetzel fi 222209513Simp 223209513Simp while read line 224209513Simp do 225209513Simp # Check for data on this slice 226220059Sjpaetzel echo $line | grep -q "^${_dTag}-part=" 2>/dev/null 227220059Sjpaetzel if [ $? -eq 0 ] 228209513Simp then 229209513Simp FOUNDPARTS="0" 230209513Simp # Found a slice- entry, lets get the slice info 231209513Simp get_value_from_string "${line}" 232209513Simp STRING="$VAL" 233209513Simp 234209513Simp # We need to split up the string now, and pick out the variables 235209513Simp FS=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 1` 236209513Simp SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 237209513Simp MNT=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 3` 238209513Simp 239209513Simp # Check if we have a .eli extension on this FS 240220059Sjpaetzel echo ${FS} | grep -q ".eli" 2>/dev/null 241220059Sjpaetzel if [ $? -eq 0 ] 242209513Simp then 243209513Simp FS="`echo ${FS} | cut -d '.' -f 1`" 244209513Simp ENC="ON" 245209513Simp check_for_enc_pass "${line}" 246209513Simp if [ "${VAL}" != "" ] ; then 247209513Simp # We have a user supplied password, save it for later 248209513Simp ENCPASS="${VAL}" 249209513Simp fi 250209513Simp else 251209513Simp ENC="OFF" 252209513Simp fi 253209513Simp 254209513Simp # Check if the user tried to setup / as an encrypted partition 255209513Simp check_for_mount "${MNT}" "/" 256220059Sjpaetzel if [ $? -eq 0 -a "${ENC}" = "ON" ] 257209513Simp then 258220059Sjpaetzel export USINGENCROOT="0" 259209513Simp fi 260209513Simp 261209513Simp # Now check that these values are sane 262209513Simp case $FS in 263213647Simp UFS|UFS+S|UFS+J|UFS+SUJ|ZFS|SWAP) ;; 264209513Simp *) exit_err "ERROR: Invalid file system specified on $line" ;; 265209513Simp esac 266209513Simp 267209513Simp # Check that we have a valid size number 268209513Simp expr $SIZE + 1 >/dev/null 2>/dev/null 269220059Sjpaetzel if [ $? -ne 0 ]; then 270209513Simp exit_err "ERROR: The size specified on $line is invalid" 271209513Simp fi 272209513Simp 273209513Simp # Check that the mount-point starts with / 274220059Sjpaetzel echo "$MNT" | grep -qe "^/" -e "^none" 2>/dev/null 275220059Sjpaetzel if [ $? -ne 0 ]; then 276209513Simp exit_err "ERROR: The mount-point specified on $line is invalid" 277209513Simp fi 278209513Simp 279209513Simp if [ "$SIZE" = "0" ] 280209513Simp then 281240315Sjpaetzel if [ $USEDAUTOSIZE -eq 1 ] ; then 282240315Sjpaetzel exit_err "ERROR: You can not have two partitions with a size of 0 specified!" 283240315Sjpaetzel fi 284240315Sjpaetzel case ${_pType} in 285240315Sjpaetzel gpt|apm) get_autosize "${_dTag}" "$_pDisk" ;; 286240315Sjpaetzel *) get_autosize "${_dTag}" "$_wSlice" ;; 287240315Sjpaetzel esac 288240315Sjpaetzel SOUT="-s ${VAL}M" 289240315Sjpaetzel USEDAUTOSIZE=1 290209513Simp else 291209513Simp SOUT="-s ${SIZE}M" 292209513Simp fi 293209513Simp 294209513Simp # Check if we found a valid root partition 295209513Simp check_for_mount "${MNT}" "/" 296220059Sjpaetzel if [ $? -eq 0 ] ; then 297220059Sjpaetzel export FOUNDROOT="1" 298217229Sjpaetzel if [ "${CURPART}" = "2" -a "$_pType" = "gpt" ] ; then 299220059Sjpaetzel export FOUNDROOT="0" 300209513Simp fi 301235447Sjpaetzel if [ "${CURPART}" = "3" -a "$_pType" = "apm" ] ; then 302235447Sjpaetzel export FOUNDROOT="0" 303235447Sjpaetzel fi 304217229Sjpaetzel if [ "${CURPART}" = "1" -a "$_pType" = "mbr" ] ; then 305220059Sjpaetzel export FOUNDROOT="0" 306217229Sjpaetzel fi 307232415Sjpaetzel if [ "${CURPART}" = "1" -a "$_pType" = "gptslice" ] ; then 308232415Sjpaetzel export FOUNDROOT="0" 309232415Sjpaetzel fi 310209513Simp fi 311209513Simp 312209513Simp check_for_mount "${MNT}" "/boot" 313220059Sjpaetzel if [ $? -eq 0 ] ; then 314220059Sjpaetzel export USINGBOOTPART="0" 315217229Sjpaetzel if [ "${CURPART}" != "2" -a "${_pType}" = "gpt" ] ; then 316209513Simp exit_err "/boot partition must be first partition" 317209513Simp fi 318235447Sjpaetzel if [ "${CURPART}" != "3" -a "${_pType}" = "apm" ] ; then 319235447Sjpaetzel exit_err "/boot partition must be first partition" 320235447Sjpaetzel fi 321217229Sjpaetzel if [ "${CURPART}" != "1" -a "${_pType}" = "mbr" ] ; then 322217229Sjpaetzel exit_err "/boot partition must be first partition" 323217229Sjpaetzel fi 324232415Sjpaetzel if [ "${CURPART}" != "1" -a "${_pType}" = "gptslice" ] ; then 325232415Sjpaetzel exit_err "/boot partition must be first partition" 326232415Sjpaetzel fi 327217229Sjpaetzel 328217229Sjpaetzel if [ "${FS}" != "UFS" -a "${FS}" != "UFS+S" -a "${FS}" != "UFS+J" -a "${FS}" != "UFS+SUJ" ] ; then 329217229Sjpaetzel exit_err "/boot partition must be formatted with UFS" 330217229Sjpaetzel fi 331209513Simp fi 332209513Simp 333209513Simp # Generate a unique label name for this mount 334209513Simp gen_glabel_name "${MNT}" "${FS}" 335209513Simp PLABEL="${VAL}" 336209513Simp 337209513Simp # Get any extra options for this fs / line 338217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 339217229Sjpaetzel get_fs_line_xvars "${_pDisk}p${CURPART}" "${STRING}" 340235447Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 341235447Sjpaetzel get_fs_line_xvars "${_pDisk}s${CURPART}" "${STRING}" 342217229Sjpaetzel else 343227219Sjpaetzel get_fs_line_xvars "${_wSlice}${PARTLETTER}" "${STRING}" 344217229Sjpaetzel fi 345235445Sjpaetzel XTRAOPTS="$VAR" 346209513Simp 347209513Simp # Check if using zfs mirror 348235445Sjpaetzel echo ${XTRAOPTS} | grep -q -e "mirror" -e "raidz" 349225657Sjpaetzel if [ $? -eq 0 -a "$FS" = "ZFS" ] ; then 350232415Sjpaetzel if [ "${_pType}" = "gpt" -o "${_pType}" = "gptslice" ] ; then 351217229Sjpaetzel XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}p${CURPART}") 352235447Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 353235447Sjpaetzel XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}s${CURPART}") 354217229Sjpaetzel else 355235445Sjpaetzel XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_wSlice}${PARTLETTER}") 356217229Sjpaetzel fi 357209513Simp fi 358209513Simp 359209513Simp # Figure out the gpart type to use 360209513Simp case ${FS} in 361211730Simp ZFS) PARTYPE="freebsd-zfs" ;; 362211730Simp SWAP) PARTYPE="freebsd-swap" ;; 363211730Simp *) PARTYPE="freebsd-ufs" ;; 364209513Simp esac 365209513Simp 366209513Simp # Create the partition 367217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 368217229Sjpaetzel if [ "$CURPART" = "2" ] ; then 369217229Sjpaetzel # If this is GPT, make sure first partition is aligned to 4k 370232415Sjpaetzel sleep 2 371233226Sjpaetzel rc_halt "gpart add -a 4k ${SOUT} -t ${PARTYPE} ${_pDisk}" 372217229Sjpaetzel else 373232415Sjpaetzel sleep 2 374217229Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}" 375217229Sjpaetzel fi 376232415Sjpaetzel elif [ "${_pType}" = "gptslice" ]; then 377232415Sjpaetzel sleep 2 378232415Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_wSlice}" 379235447Sjpaetzel elif [ "${_pType}" = "apm" ]; then 380235447Sjpaetzel sleep 2 381235447Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}" 382217229Sjpaetzel else 383232415Sjpaetzel sleep 2 384217229Sjpaetzel rc_halt "gpart add ${SOUT} -t ${PARTYPE} -i ${CURPART} ${_wSlice}" 385217229Sjpaetzel fi 386209513Simp 387209513Simp # Check if this is a root / boot partition, and stamp the right loader 388209513Simp for TESTMNT in `echo ${MNT} | sed 's|,| |g'` 389209513Simp do 390209513Simp if [ "${TESTMNT}" = "/" -a -z "${BOOTTYPE}" ] ; then 391209513Simp BOOTTYPE="${PARTYPE}" 392209513Simp fi 393209513Simp if [ "${TESTMNT}" = "/boot" ] ; then 394209513Simp BOOTTYPE="${PARTYPE}" 395209513Simp fi 396209513Simp done 397209513Simp 398209513Simp # Save this data to our partition config dir 399217229Sjpaetzel if [ "${_pType}" = "gpt" ] ; then 400220909Sjpaetzel _dFile="`echo $_pDisk | sed 's|/|-|g'`" 401233224Sjpaetzel echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}p${CURPART} 402209513Simp 403217229Sjpaetzel # Clear out any headers 404217229Sjpaetzel sleep 2 405220059Sjpaetzel dd if=/dev/zero of=${_pDisk}p${CURPART} count=2048 2>/dev/null 406209513Simp 407217229Sjpaetzel # If we have a enc password, save it as well 408220059Sjpaetzel if [ -n "${ENCPASS}" ] ; then 409220909Sjpaetzel echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}p${CURPART}-encpass 410217229Sjpaetzel fi 411235447Sjpaetzel elif [ "${_pType}" = "apm" ] ; then 412235447Sjpaetzel _dFile="`echo $_pDisk | sed 's|/|-|g'`" 413235447Sjpaetzel echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}s${CURPART} 414235447Sjpaetzel 415235447Sjpaetzel # Clear out any headers 416235447Sjpaetzel sleep 2 417235447Sjpaetzel dd if=/dev/zero of=${_pDisk}s${CURPART} count=2048 2>/dev/null 418235447Sjpaetzel 419235447Sjpaetzel # If we have a enc password, save it as well 420235447Sjpaetzel if [ -n "${ENCPASS}" ] ; then 421235447Sjpaetzel echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}s${CURPART}-encpass 422235447Sjpaetzel fi 423217229Sjpaetzel else 424232415Sjpaetzel # MBR Partition or GPT slice 425220909Sjpaetzel _dFile="`echo $_wSlice | sed 's|/|-|g'`" 426233224Sjpaetzel echo "${FS}#${MNT}#${ENC}#${PLABEL}#MBR#${XTRAOPTS}#${IMAGE}" >${PARTDIR}/${_dFile}${PARTLETTER} 427217229Sjpaetzel # Clear out any headers 428217229Sjpaetzel sleep 2 429220059Sjpaetzel dd if=/dev/zero of=${_wSlice}${PARTLETTER} count=2048 2>/dev/null 430217229Sjpaetzel 431217229Sjpaetzel # If we have a enc password, save it as well 432220059Sjpaetzel if [ -n "${ENCPASS}" ] ; then 433220909Sjpaetzel echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}${PARTLETTER}-encpass 434217229Sjpaetzel fi 435209513Simp fi 436209513Simp 437217229Sjpaetzel 438209513Simp # Increment our parts counter 439235447Sjpaetzel if [ "$_pType" = "gpt" -o "$_pType" = "apm" ] ; then 440220059Sjpaetzel CURPART=$((CURPART+1)) 441235447Sjpaetzel # If this is a gpt/apm partition, 442235447Sjpaetzel # we can continue and skip the MBR part letter stuff 443217229Sjpaetzel continue 444217229Sjpaetzel else 445220059Sjpaetzel CURPART=$((CURPART+1)) 446217229Sjpaetzel if [ "$CURPART" = "3" ] ; then CURPART="4" ; fi 447217229Sjpaetzel fi 448209513Simp 449217229Sjpaetzel 450217229Sjpaetzel # This partition letter is used, get the next one 451217229Sjpaetzel case ${PARTLETTER} in 452217229Sjpaetzel a) PARTLETTER="b" ;; 453217229Sjpaetzel b) PARTLETTER="d" ;; 454217229Sjpaetzel d) PARTLETTER="e" ;; 455217229Sjpaetzel e) PARTLETTER="f" ;; 456217229Sjpaetzel f) PARTLETTER="g" ;; 457217229Sjpaetzel g) PARTLETTER="h" ;; 458217229Sjpaetzel h) PARTLETTER="ERR" ;; 459217229Sjpaetzel *) exit_err "ERROR: bsdlabel only supports up to letter h for partitions." ;; 460217229Sjpaetzel esac 461217229Sjpaetzel 462209513Simp fi # End of subsection locating a slice in config 463209513Simp 464220059Sjpaetzel echo $line | grep -q "^commitDiskLabel" 2>/dev/null 465220059Sjpaetzel if [ $? -eq 0 -a "${FOUNDPARTS}" = "0" ] 466209513Simp then 467209513Simp 468209513Simp # If this is the boot disk, stamp the right gptboot 469217229Sjpaetzel if [ ! -z "${BOOTTYPE}" -a "$_pType" = "gpt" ] ; then 470209513Simp case ${BOOTTYPE} in 471217229Sjpaetzel freebsd-ufs) rc_halt "gpart bootcode -p /boot/gptboot -i 1 ${_pDisk}" ;; 472217229Sjpaetzel freebsd-zfs) rc_halt "gpart bootcode -p /boot/gptzfsboot -i 1 ${_pDisk}" ;; 473209513Simp esac 474209513Simp fi 475209513Simp 476217229Sjpaetzel # Make sure to stamp the MBR loader 477217229Sjpaetzel if [ "$_pType" = "mbr" ] ; then 478217229Sjpaetzel rc_halt "gpart bootcode -b /boot/boot ${_wSlice}" 479217229Sjpaetzel fi 480209513Simp 481209513Simp # Found our flag to commit this label setup, check that we found at least 1 partition 482233224Sjpaetzel if [ "${CURPART}" = "1" ] ; then 483209513Simp exit_err "ERROR: commitDiskLabel was called without any partition entries for it!" 484209513Simp fi 485209513Simp 486209513Simp break 487209513Simp fi 488209513Simp done <${CFGF} 489209513Simp}; 490209513Simp 491209513Simp# Reads through the config and sets up a BSDLabel for the given slice 492209513Simppopulate_disk_label() 493209513Simp{ 494209513Simp if [ -z "${1}" ] 495209513Simp then 496209513Simp exit_err "ERROR: populate_disk_label() called without argument!" 497209513Simp fi 498209513Simp 499209513Simp # Set some vars from the given working slice 500220909Sjpaetzel diskid="`echo $1 | cut -d ':' -f 1`" 501220909Sjpaetzel disk="`echo $1 | cut -d ':' -f 1 | sed 's|-|/|g'`" 502220909Sjpaetzel slicenum="`echo $1 | cut -d ':' -f 2`" 503220909Sjpaetzel type="`echo $1 | cut -d ':' -f 3`" 504209513Simp 505209513Simp # Set WRKSLICE based upon format we are using 506209513Simp if [ "$type" = "mbr" ] ; then 507220909Sjpaetzel wrkslice="${diskid}s${slicenum}" 508209513Simp fi 509235447Sjpaetzel if [ "$type" = "apm" ] ; then 510235447Sjpaetzel wrkslice="${diskid}s${slicenum}" 511235447Sjpaetzel fi 512232415Sjpaetzel if [ "$type" = "gpt" -o "$type" = "gptslice" ] ; then 513220909Sjpaetzel wrkslice="${diskid}p${slicenum}" 514209513Simp fi 515209513Simp 516220909Sjpaetzel if [ ! -e "${SLICECFGDIR}/${wrkslice}" ] ; then 517209513Simp exit_err "ERROR: Missing SLICETAG data. This shouldn't happen - please let the developers know" 518209513Simp fi 519209513Simp 520220909Sjpaetzel disktag="`cat ${SLICECFGDIR}/${wrkslice}`" 521220909Sjpaetzel slicedev="`echo $wrkslice | sed 's|-|/|g'`" 522220909Sjpaetzel 523217229Sjpaetzel # Setup the partitions with gpart 524220909Sjpaetzel setup_gpart_partitions "${disktag}" "${disk}" "${slicedev}" "${slicenum}" "${type}" 525209513Simp 526209513Simp}; 527209513Simp 528209513Simp# Function which reads in the disk slice config, and performs it 529209513Simpsetup_disk_label() 530209513Simp{ 531209513Simp # We are ready to start setting up the label, lets read the config and do the actions 532209513Simp # First confirm that we have a valid WORKINGSLICES 533213650Simp if [ -z "${WORKINGSLICES}" ]; then 534209513Simp exit_err "ERROR: No slices were setup! Please report this to the maintainers" 535209513Simp fi 536209513Simp 537209513Simp # Check that the slices we have did indeed get setup and gpart worked 538209513Simp for i in $WORKINGSLICES 539209513Simp do 540209513Simp disk="`echo $i | cut -d '-' -f 1`" 541209513Simp pnum="`echo $i | cut -d '-' -f 2`" 542209513Simp type="`echo $i | cut -d '-' -f 3`" 543220909Sjpaetzel if [ "$type" = "mbr" -a ! -e "${disk}s${pnum}" ] ; then 544209513Simp exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 545209513Simp fi 546220909Sjpaetzel if [ "$type" = "gpt" -a ! -e "${disk}p${pnum}" ] ; then 547209513Simp exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 548209513Simp fi 549235447Sjpaetzel if [ "$type" = "apm" -a ! -e "${disk}s${pnum}" ] ; then 550235447Sjpaetzel exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 551235447Sjpaetzel fi 552232415Sjpaetzel if [ "$type" = "gptslice" -a ! -e "${disk}p${pnum}" ] ; then 553232415Sjpaetzel exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 554232415Sjpaetzel fi 555209513Simp done 556209513Simp 557209513Simp # Setup some files which we'll be referring to 558220059Sjpaetzel export LABELLIST="${TMPDIR}/workingLabels" 559209513Simp rm $LABELLIST >/dev/null 2>/dev/null 560209513Simp 561209513Simp # Set our flag to determine if we've got a valid root partition in this setup 562220059Sjpaetzel export FOUNDROOT="-1" 563209513Simp 564209513Simp # Check if we are using a /boot partition 565220059Sjpaetzel export USINGBOOTPART="1" 566209513Simp 567209513Simp # Set encryption on root check 568220059Sjpaetzel export USINGENCROOT="1" 569209513Simp 570209513Simp # Make the tmp directory where we'll store FS info & mount-points 571209513Simp rm -rf ${PARTDIR} >/dev/null 2>/dev/null 572209513Simp mkdir -p ${PARTDIR} >/dev/null 2>/dev/null 573209513Simp rm -rf ${PARTDIR}-enc >/dev/null 2>/dev/null 574209513Simp mkdir -p ${PARTDIR}-enc >/dev/null 2>/dev/null 575209513Simp 576209513Simp for i in $WORKINGSLICES 577209513Simp do 578209513Simp populate_disk_label "${i}" 579209513Simp done 580209513Simp 581209513Simp # Check if we made a root partition 582209513Simp if [ "$FOUNDROOT" = "-1" ] 583209513Simp then 584209513Simp exit_err "ERROR: No root (/) partition specified!!" 585209513Simp fi 586209513Simp 587209513Simp # Check if we made a root partition 588209513Simp if [ "$FOUNDROOT" = "1" -a "${USINGBOOTPART}" != "0" ] 589209513Simp then 590209513Simp exit_err "ERROR: (/) partition isn't first partition on disk!" 591209513Simp fi 592209513Simp 593209513Simp if [ "${USINGENCROOT}" = "0" -a "${USINGBOOTPART}" != "0" ] 594209513Simp then 595209513Simp exit_err "ERROR: Can't encrypt (/) with no (/boot) partition!" 596209513Simp fi 597209513Simp}; 598209513Simp 599212337Simpcheck_fstab_mbr() 600212337Simp{ 601212337Simp local SLICE 602212337Simp local FSTAB 603212337Simp 604212337Simp if [ -z "$2" ] 605212337Simp then 606212337Simp return 1 607212337Simp fi 608212337Simp 609212337Simp SLICE="$1" 610212337Simp FSTAB="$2/etc/fstab" 611212337Simp 612212337Simp if [ -f "${FSTAB}" ] 613212337Simp then 614212337Simp PARTLETTER=`echo "$SLICE" | sed -E 's|^.+([a-h])$|\1|'` 615212337Simp 616220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1 617220059Sjpaetzel if [ $? -eq 0 ] 618212337Simp then 619212337Simp if [ "${PARTLETTER}" = "a" ] 620212337Simp then 621212337Simp FOUNDROOT="0" 622212337Simp else 623212337Simp FOUNDROOT="1" 624212337Simp fi 625213650Simp 626213650Simp ROOTIMAGE="1" 627213650Simp 628212337Simp export FOUNDROOT 629213650Simp export ROOTIMAGE 630212337Simp fi 631212337Simp 632220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1 633220059Sjpaetzel if [ $? -eq 0 ] 634212337Simp then 635212337Simp if [ "${PARTLETTER}" = "a" ] 636212337Simp then 637212337Simp USINGBOOTPART="0" 638212337Simp else 639212337Simp exit_err "/boot partition must be first partition" 640212337Simp fi 641212337Simp export USINGBOOTPART 642212337Simp fi 643212337Simp 644212337Simp return 0 645212337Simp fi 646212337Simp 647212337Simp return 1 648212337Simp}; 649212337Simp 650212337Simpcheck_fstab_gpt() 651212337Simp{ 652212337Simp local SLICE 653212337Simp local FSTAB 654212337Simp 655212337Simp if [ -z "$2" ] 656212337Simp then 657212337Simp return 1 658212337Simp fi 659212337Simp 660212337Simp SLICE="$1" 661212337Simp FSTAB="$2/etc/fstab" 662212337Simp 663212337Simp if [ -f "${FSTAB}" ] 664212337Simp then 665212337Simp PARTNUMBER=`echo "${SLICE}" | sed -E 's|^.+p([0-9]*)$|\1|'` 666212337Simp 667220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1 668220059Sjpaetzel if [ $? -eq 0 ] 669212337Simp then 670212337Simp if [ "${PARTNUMBER}" = "2" ] 671212337Simp then 672212337Simp FOUNDROOT="0" 673212337Simp else 674212337Simp FOUNDROOT="1" 675212337Simp fi 676213650Simp 677213650Simp ROOTIMAGE="1" 678213650Simp 679212337Simp export FOUNDROOT 680213650Simp export ROOTIMAGE 681212337Simp fi 682212337Simp 683220059Sjpaetzel cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1 684220059Sjpaetzel if [ $? -eq 0 ] 685212337Simp then 686212337Simp if [ "${PARTNUMBER}" = "2" ] 687212337Simp then 688212337Simp USINGBOOTPART="0" 689212337Simp else 690212337Simp exit_err "/boot partition must be first partition" 691212337Simp fi 692212337Simp export USINGBOOTPART 693212337Simp fi 694212337Simp 695212337Simp return 0 696212337Simp fi 697212337Simp 698212337Simp 699212337Simp return 1 700212337Simp}; 701212337Simp 702213650Simpcheck_disk_layout() 703212337Simp{ 704212337Simp local SLICES 705212337Simp local TYPE 706213650Simp local DISK 707212337Simp local RES 708212337Simp local F 709212337Simp 710213650Simp DISK="$1" 711212337Simp TYPE="MBR" 712212337Simp 713213650Simp if [ -z "${DISK}" ] 714212337Simp then 715212337Simp return 1 716212337Simp fi 717212337Simp 718213650Simp SLICES_MBR=`ls /dev/${DISK}s[1-4]*[a-h]* 2>/dev/null` 719213650Simp SLICES_GPT=`ls /dev/${DISK}p[0-9]* 2>/dev/null` 720213650Simp SLICES_SLICE=`ls /dev/${DISK}[a-h]* 2>/dev/null` 721213650Simp 722213650Simp if [ -n "${SLICES_MBR}" ] 723212337Simp then 724213650Simp SLICES="${SLICES_MBR}" 725213650Simp TYPE="MBR" 726213650Simp RES=0 727212337Simp fi 728213650Simp if [ -n "${SLICES_GPT}" ] 729212337Simp then 730213650Simp SLICES="${SLICES_GPT}" 731213650Simp TYPE="GPT" 732212337Simp RES=0 733212337Simp fi 734213650Simp if [ -n "${SLICES_SLICE}" ] 735213650Simp then 736213650Simp SLICES="${SLICES_SLICE}" 737213650Simp TYPE="MBR" 738213650Simp RES=0 739213650Simp fi 740213650Simp 741212337Simp for slice in ${SLICES} 742212337Simp do 743212337Simp F=1 744212337Simp mount ${slice} /mnt 2>/dev/null 745220059Sjpaetzel if [ $? -ne 0 ] 746212337Simp then 747212337Simp continue 748212337Simp fi 749212337Simp 750212337Simp if [ "${TYPE}" = "MBR" ] 751212337Simp then 752212337Simp check_fstab_mbr "${slice}" "/mnt" 753212337Simp F="$?" 754212337Simp 755212337Simp elif [ "${TYPE}" = "GPT" ] 756212337Simp then 757212337Simp check_fstab_gpt "${slice}" "/mnt" 758212337Simp F="$?" 759212337Simp fi 760212337Simp 761220059Sjpaetzel if [ ${F} -eq 0 ] 762212337Simp then 763212337Simp umount /mnt 764212337Simp break 765212337Simp fi 766212337Simp 767212337Simp umount /mnt 768212337Simp done 769212337Simp 770212337Simp return ${RES} 771212337Simp}; 772