1#!/bin/sh 2#- 3# Copyright (c) 2010 iXsystems, Inc. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24# SUCH DAMAGE. 25# 26# $FreeBSD: releng/10.3/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh 247735 2013-03-03 23:07:27Z jpaetzel $ 27 28# Functions related to disk operations using bsdlabel 29 30# Check if we are are provided a geli password on the nextline of the config 31check_for_enc_pass() 32{ 33 CURLINE="${1}" 34 35 get_next_cfg_line "${CFGF}" "${CURLINE}" 36 echo ${VAL} | grep -q "^encpass=" 2>/dev/null 37 if [ $? -eq 0 ] ; then 38 # Found a password, return it 39 get_value_from_string "${VAL}" 40 return 41 fi 42 43 export VAL="" 44 return 45}; 46 47# On check on the disk-label line if we have any extra vars for this device 48get_fs_line_xvars() 49{ 50 ACTIVEDEV="${1}" 51 LINE="${2}" 52 53 echo $LINE | cut -d ' ' -f 4 | grep -q '(' 2>/dev/null 54 if [ $? -ne 0 ] ; then return ; fi 55 56 # See if we are looking for ZFS specific options 57 echo $LINE | grep -q '^ZFS' 2>/dev/null 58 if [ $? -eq 0 ] ; then 59 ZTYPE="NONE" 60 ZFSVARS="`echo $LINE | cut -d ' ' -f 4-20 |cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`" 61 62 echo $ZFSVARS | grep -qE "^(disk|file|mirror|raidz(1|2|3)?|spare|log|cache):" 2>/dev/null 63 if [ $? -eq 0 ] ; then 64 ZTYPE=`echo $ZFSVARS | cut -f1 -d:` 65 tmpVars=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"` 66 ZFSVARS="" 67 # make sure we have a '/dev' in front of the extra devices 68 for i in $tmpVars 69 do 70 echo $i | grep -q '/dev/' 71 if [ $? -ne 0 ] ; then 72 ZFSVARS="$ZFSVARS /dev/${i}" 73 else 74 ZFSVARS="$ZFSVARS $i" 75 fi 76 done 77 fi 78 79 # Return the ZFS options 80 if [ "${ZTYPE}" = "NONE" ] ; then 81 VAR="${ACTIVEDEV} ${ZFSVARS}" 82 else 83 VAR="${ZTYPE} ${ACTIVEDEV} ${ZFSVARS}" 84 fi 85 export VAR 86 return 87 fi # End of ZFS block 88 89 # See if we are looking for UFS specific newfs options 90 echo $LINE | grep -q '^UFS' 2>/dev/null 91 if [ $? -eq 0 ] ; then 92 FSVARS="`echo $LINE | cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`" 93 VAR="${FSVARS}" 94 export VAR 95 return 96 fi 97 98 # If we got here, set VAR to empty and export 99 export VAR="" 100 return 101}; 102 103# Init each zfs mirror disk with a boot sector so we can failover 104setup_zfs_mirror_parts() 105{ 106 _nZFS="" 107 108 ZTYPE="`echo ${1} | awk '{print $1}'`" 109 110 # Using mirroring, setup boot partitions on each disk 111 _mirrline="`echo ${1} | sed 's|mirror ||g' | sed 's|raidz1 ||g' | sed 's|raidz2 ||g' | sed 's|raidz3 ||g' | sed 's|raidz ||g'`" 112 for _zvars in $_mirrline 113 do 114 echo "Looping through _zvars: $_zvars" >>${LOGOUT} 115 echo "$_zvars" | grep -q "${2}" 2>/dev/null 116 if [ $? -eq 0 ] ; then continue ; fi 117 if [ -z "$_zvars" ] ; then continue ; fi 118 119 is_disk "$_zvars" >/dev/null 2>/dev/null 120 if [ $? -eq 0 ] ; then 121 echo "Setting up ZFS disk $_zvars" >>${LOGOUT} 122 init_gpt_full_disk "$_zvars" >/dev/null 2>/dev/null 123 rc_halt "gpart add -a 4k -t freebsd-zfs ${_zvars}" >/dev/null 2>/dev/null 124 rc_halt "gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${_zvars}" >/dev/null 2>/dev/null 125 _nZFS="$_nZFS ${_zvars}p2" 126 else 127 _nZFS="$_nZFS ${_zvars}" 128 fi 129 done 130 echo "$ZTYPE $2 `echo $_nZFS | tr -s ' '`" 131} ; 132 133# Function which creates a unique label name for the specified mount 134gen_glabel_name() 135{ 136 MOUNT="$1" 137 TYPE="$2" 138 NUM="0" 139 MAXNUM="20" 140 141 if [ "$TYPE" = "ZFS" ] ; then 142 NAME="zpool" 143 elif [ "$MOUNT" = "/" ] ; then 144 NAME="rootfs" 145 else 146 # If doing a swap partition, also rename it 147 if [ "${TYPE}" = "SWAP" ] 148 then 149 NAME="swap" 150 else 151 NAME="`echo $MOUNT | sed 's|/||g' | sed 's| ||g'`" 152 fi 153 fi 154 155 # Loop through and break when we find our first available label 156 while 157 Z=1 158 do 159 glabel status | grep -q "${NAME}${NUM}" 2>/dev/null 160 if [ $? -ne 0 ] 161 then 162 break 163 else 164 NUM=$((NUM+1)) 165 fi 166 167 if [ $NUM -gt $MAXNUM ] 168 then 169 exit_err "Cannot allocate additional glabel name for $NAME" 170 break 171 fi 172 done 173 174 175 export VAL="${NAME}${NUM}" 176}; 177 178# Function to determine the size we can safely use when 0 is specified 179get_autosize() 180{ 181 # Disk tag to look for 182 dTag="$1" 183 184 # Total MB Avail 185 get_disk_mediasize_mb "$2" 186 local _aSize=$VAL 187 188 while read line 189 do 190 # Check for data on this slice 191 echo $line | grep -q "^${_dTag}-part=" 2>/dev/null 192 if [ $? -ne 0 ] ; then continue ; fi 193 194 get_value_from_string "${line}" 195 STRING="$VAL" 196 197 # Get the size of this partition 198 SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 199 if [ $SIZE -eq 0 ] ; then continue ; fi 200 _aSize=`expr $_aSize - $SIZE` 201 done <${CFGF} 202 203 # Pad the size a bit 204 _aSize=`expr $_aSize - 2` 205 206 VAL="$_aSize" 207 export VAL 208}; 209 210# Function to setup partitions using gpart 211setup_gpart_partitions() 212{ 213 local _dTag="$1" 214 local _pDisk="$2" 215 local _wSlice="$3" 216 local _sNum="$4" 217 local _pType="$5" 218 FOUNDPARTS="1" 219 USEDAUTOSIZE=0 220 221 # Lets read in the config file now and setup our partitions 222 if [ "${_pType}" = "gpt" ] ; then 223 CURPART="2" 224 elif [ "${_pType}" = "apm" ] ; then 225 CURPART="3" 226 else 227 PARTLETTER="a" 228 CURPART="1" 229 if [ "${_pType}" = "mbr" ] ; then 230 rc_halt "gpart create -s BSD ${_wSlice}" 231 fi 232 fi 233 234 while read line 235 do 236 # Check for data on this slice 237 echo $line | grep -q "^${_dTag}-part=" 2>/dev/null 238 if [ $? -eq 0 ] 239 then 240 FOUNDPARTS="0" 241 # Found a slice- entry, lets get the slice info 242 get_value_from_string "${line}" 243 STRING="$VAL" 244 245 # We need to split up the string now, and pick out the variables 246 FS=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 1` 247 SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 248 MNT=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 3` 249 250 # Check if we have a .eli extension on this FS 251 echo ${FS} | grep -q ".eli" 2>/dev/null 252 if [ $? -eq 0 ] 253 then 254 FS="`echo ${FS} | cut -d '.' -f 1`" 255 ENC="ON" 256 check_for_enc_pass "${line}" 257 if [ "${VAL}" != "" ] ; then 258 # We have a user supplied password, save it for later 259 ENCPASS="${VAL}" 260 fi 261 else 262 ENC="OFF" 263 fi 264 265 # Check if the user tried to setup / as an encrypted partition 266 check_for_mount "${MNT}" "/" 267 if [ $? -eq 0 -a "${ENC}" = "ON" ] 268 then 269 export USINGENCROOT="0" 270 fi 271 272 # Now check that these values are sane 273 case $FS in 274 UFS|UFS+S|UFS+J|UFS+SUJ|ZFS|SWAP) ;; 275 *) exit_err "ERROR: Invalid file system specified on $line" ;; 276 esac 277 278 # Check that we have a valid size number 279 expr $SIZE + 1 >/dev/null 2>/dev/null 280 if [ $? -ne 0 ]; then 281 exit_err "ERROR: The size specified on $line is invalid" 282 fi 283 284 # Check that the mount-point starts with / 285 echo "$MNT" | grep -qe "^/" -e "^none" 2>/dev/null 286 if [ $? -ne 0 ]; then 287 exit_err "ERROR: The mount-point specified on $line is invalid" 288 fi 289 290 if [ "$SIZE" = "0" ] 291 then 292 if [ $USEDAUTOSIZE -eq 1 ] ; then 293 exit_err "ERROR: You can not have two partitions with a size of 0 specified!" 294 fi 295 case ${_pType} in 296 gpt|apm) get_autosize "${_dTag}" "$_pDisk" ;; 297 *) get_autosize "${_dTag}" "$_wSlice" ;; 298 esac 299 SOUT="-s ${VAL}M" 300 USEDAUTOSIZE=1 301 else 302 SOUT="-s ${SIZE}M" 303 fi 304 305 # Check if we found a valid root partition 306 check_for_mount "${MNT}" "/" 307 if [ $? -eq 0 ] ; then 308 export FOUNDROOT="1" 309 if [ "${CURPART}" = "2" -a "$_pType" = "gpt" ] ; then 310 export FOUNDROOT="0" 311 fi 312 if [ "${CURPART}" = "3" -a "$_pType" = "apm" ] ; then 313 export FOUNDROOT="0" 314 fi 315 if [ "${CURPART}" = "1" -a "$_pType" = "mbr" ] ; then 316 export FOUNDROOT="0" 317 fi 318 if [ "${CURPART}" = "1" -a "$_pType" = "gptslice" ] ; then 319 export FOUNDROOT="0" 320 fi 321 fi 322 323 check_for_mount "${MNT}" "/boot" 324 if [ $? -eq 0 ] ; then 325 export USINGBOOTPART="0" 326 if [ "${CURPART}" != "2" -a "${_pType}" = "gpt" ] ; then 327 exit_err "/boot partition must be first partition" 328 fi 329 if [ "${CURPART}" != "3" -a "${_pType}" = "apm" ] ; then 330 exit_err "/boot partition must be first partition" 331 fi 332 if [ "${CURPART}" != "1" -a "${_pType}" = "mbr" ] ; then 333 exit_err "/boot partition must be first partition" 334 fi 335 if [ "${CURPART}" != "1" -a "${_pType}" = "gptslice" ] ; then 336 exit_err "/boot partition must be first partition" 337 fi 338 339 if [ "${FS}" != "UFS" -a "${FS}" != "UFS+S" -a "${FS}" != "UFS+J" -a "${FS}" != "UFS+SUJ" ] ; then 340 exit_err "/boot partition must be formatted with UFS" 341 fi 342 fi 343 344 # Generate a unique label name for this mount 345 gen_glabel_name "${MNT}" "${FS}" 346 PLABEL="${VAL}" 347 348 # Get any extra options for this fs / line 349 if [ "${_pType}" = "gpt" ] ; then 350 get_fs_line_xvars "${_pDisk}p${CURPART}" "${STRING}" 351 elif [ "${_pType}" = "apm" ] ; then 352 get_fs_line_xvars "${_pDisk}s${CURPART}" "${STRING}" 353 else 354 get_fs_line_xvars "${_wSlice}${PARTLETTER}" "${STRING}" 355 fi 356 XTRAOPTS="$VAR" 357 358 # Check if using zfs mirror 359 echo ${XTRAOPTS} | grep -q -e "mirror" -e "raidz" 360 if [ $? -eq 0 -a "$FS" = "ZFS" ] ; then 361 if [ "${_pType}" = "gpt" -o "${_pType}" = "gptslice" ] ; then 362 XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}p${CURPART}") 363 elif [ "${_pType}" = "apm" ] ; then 364 XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}s${CURPART}") 365 else 366 XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_wSlice}${PARTLETTER}") 367 fi 368 fi 369 370 # Figure out the gpart type to use 371 case ${FS} in 372 ZFS) PARTYPE="freebsd-zfs" ;; 373 SWAP) PARTYPE="freebsd-swap" ;; 374 *) PARTYPE="freebsd-ufs" ;; 375 esac 376 377 # Create the partition 378 if [ "${_pType}" = "gpt" ] ; then 379 if [ "$CURPART" = "2" ] ; then 380 # If this is GPT, make sure first partition is aligned to 4k 381 sleep 2 382 rc_halt "gpart add -a 4k ${SOUT} -t ${PARTYPE} ${_pDisk}" 383 else 384 sleep 2 385 rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}" 386 fi 387 elif [ "${_pType}" = "gptslice" ]; then 388 sleep 2 389 rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_wSlice}" 390 elif [ "${_pType}" = "apm" ]; then 391 sleep 2 392 rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}" 393 else 394 sleep 2 395 rc_halt "gpart add ${SOUT} -t ${PARTYPE} -i ${CURPART} ${_wSlice}" 396 fi 397 398 # Check if this is a root / boot partition, and stamp the right loader 399 for TESTMNT in `echo ${MNT} | sed 's|,| |g'` 400 do 401 if [ "${TESTMNT}" = "/" -a -z "${BOOTTYPE}" ] ; then 402 BOOTTYPE="${PARTYPE}" 403 fi 404 if [ "${TESTMNT}" = "/boot" ] ; then 405 BOOTTYPE="${PARTYPE}" 406 fi 407 done 408 409 # Save this data to our partition config dir 410 if [ "${_pType}" = "gpt" ] ; then 411 _dFile="`echo $_pDisk | sed 's|/|-|g'`" 412 echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}p${CURPART} 413 414 # Clear out any headers 415 sleep 2 416 dd if=/dev/zero of=${_pDisk}p${CURPART} count=2048 2>/dev/null 417 418 # If we have a enc password, save it as well 419 if [ -n "${ENCPASS}" ] ; then 420 echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}p${CURPART}-encpass 421 fi 422 elif [ "${_pType}" = "apm" ] ; then 423 _dFile="`echo $_pDisk | sed 's|/|-|g'`" 424 echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}s${CURPART} 425 426 # Clear out any headers 427 sleep 2 428 dd if=/dev/zero of=${_pDisk}s${CURPART} count=2048 2>/dev/null 429 430 # If we have a enc password, save it as well 431 if [ -n "${ENCPASS}" ] ; then 432 echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}s${CURPART}-encpass 433 fi 434 else 435 # MBR Partition or GPT slice 436 _dFile="`echo $_wSlice | sed 's|/|-|g'`" 437 echo "${FS}#${MNT}#${ENC}#${PLABEL}#MBR#${XTRAOPTS}#${IMAGE}" >${PARTDIR}/${_dFile}${PARTLETTER} 438 # Clear out any headers 439 sleep 2 440 dd if=/dev/zero of=${_wSlice}${PARTLETTER} count=2048 2>/dev/null 441 442 # If we have a enc password, save it as well 443 if [ -n "${ENCPASS}" ] ; then 444 echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}${PARTLETTER}-encpass 445 fi 446 fi 447 448 449 # Increment our parts counter 450 if [ "$_pType" = "gpt" -o "$_pType" = "apm" ] ; then 451 CURPART=$((CURPART+1)) 452 # If this is a gpt/apm partition, 453 # we can continue and skip the MBR part letter stuff 454 continue 455 else 456 CURPART=$((CURPART+1)) 457 if [ "$CURPART" = "3" ] ; then CURPART="4" ; fi 458 fi 459 460 461 # This partition letter is used, get the next one 462 case ${PARTLETTER} in 463 a) PARTLETTER="b" ;; 464 b) PARTLETTER="d" ;; 465 d) PARTLETTER="e" ;; 466 e) PARTLETTER="f" ;; 467 f) PARTLETTER="g" ;; 468 g) PARTLETTER="h" ;; 469 h) PARTLETTER="ERR" ;; 470 *) exit_err "ERROR: bsdlabel only supports up to letter h for partitions." ;; 471 esac 472 473 fi # End of subsection locating a slice in config 474 475 echo $line | grep -q "^commitDiskLabel" 2>/dev/null 476 if [ $? -eq 0 -a "${FOUNDPARTS}" = "0" ] 477 then 478 479 # If this is the boot disk, stamp the right gptboot 480 if [ ! -z "${BOOTTYPE}" -a "$_pType" = "gpt" ] ; then 481 case ${BOOTTYPE} in 482 freebsd-ufs) rc_halt "gpart bootcode -p /boot/gptboot -i 1 ${_pDisk}" ;; 483 freebsd-zfs) rc_halt "gpart bootcode -p /boot/gptzfsboot -i 1 ${_pDisk}" ;; 484 esac 485 fi 486 487 # Make sure to stamp the MBR loader 488 if [ "$_pType" = "mbr" ] ; then 489 rc_halt "gpart bootcode -b /boot/boot ${_wSlice}" 490 fi 491 492 # Found our flag to commit this label setup, check that we found at least 1 partition 493 if [ "${CURPART}" = "1" ] ; then 494 exit_err "ERROR: commitDiskLabel was called without any partition entries for it!" 495 fi 496 497 break 498 fi 499 done <${CFGF} 500}; 501 502# Reads through the config and sets up a BSDLabel for the given slice 503populate_disk_label() 504{ 505 if [ -z "${1}" ] 506 then 507 exit_err "ERROR: populate_disk_label() called without argument!" 508 fi 509 510 # Set some vars from the given working slice 511 diskid="`echo $1 | cut -d ':' -f 1`" 512 disk="`echo $1 | cut -d ':' -f 1 | sed 's|-|/|g'`" 513 slicenum="`echo $1 | cut -d ':' -f 2`" 514 type="`echo $1 | cut -d ':' -f 3`" 515 516 # Set WRKSLICE based upon format we are using 517 if [ "$type" = "mbr" ] ; then 518 wrkslice="${diskid}s${slicenum}" 519 fi 520 if [ "$type" = "apm" ] ; then 521 wrkslice="${diskid}s${slicenum}" 522 fi 523 if [ "$type" = "gpt" -o "$type" = "gptslice" ] ; then 524 wrkslice="${diskid}p${slicenum}" 525 fi 526 527 if [ ! -e "${SLICECFGDIR}/${wrkslice}" ] ; then 528 exit_err "ERROR: Missing SLICETAG data. This shouldn't happen - please let the developers know" 529 fi 530 531 disktag="`cat ${SLICECFGDIR}/${wrkslice}`" 532 slicedev="`echo $wrkslice | sed 's|-|/|g'`" 533 534 # Setup the partitions with gpart 535 setup_gpart_partitions "${disktag}" "${disk}" "${slicedev}" "${slicenum}" "${type}" 536 537}; 538 539# Function which reads in the disk slice config, and performs it 540setup_disk_label() 541{ 542 # We are ready to start setting up the label, lets read the config and do the actions 543 # First confirm that we have a valid WORKINGSLICES 544 if [ -z "${WORKINGSLICES}" ]; then 545 exit_err "ERROR: No slices were setup! Please report this to the maintainers" 546 fi 547 548 # Check that the slices we have did indeed get setup and gpart worked 549 for i in $WORKINGSLICES 550 do 551 disk="`echo $i | cut -d '-' -f 1`" 552 pnum="`echo $i | cut -d '-' -f 2`" 553 type="`echo $i | cut -d '-' -f 3`" 554 if [ "$type" = "mbr" -a ! -e "${disk}s${pnum}" ] ; then 555 exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 556 fi 557 if [ "$type" = "gpt" -a ! -e "${disk}p${pnum}" ] ; then 558 exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 559 fi 560 if [ "$type" = "apm" -a ! -e "${disk}s${pnum}" ] ; then 561 exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 562 fi 563 if [ "$type" = "gptslice" -a ! -e "${disk}p${pnum}" ] ; then 564 exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!" 565 fi 566 done 567 568 # Setup some files which we'll be referring to 569 export LABELLIST="${TMPDIR}/workingLabels" 570 rm $LABELLIST >/dev/null 2>/dev/null 571 572 # Set our flag to determine if we've got a valid root partition in this setup 573 export FOUNDROOT="-1" 574 575 # Check if we are using a /boot partition 576 export USINGBOOTPART="1" 577 578 # Set encryption on root check 579 export USINGENCROOT="1" 580 581 # Make the tmp directory where we'll store FS info & mount-points 582 rm -rf ${PARTDIR} >/dev/null 2>/dev/null 583 mkdir -p ${PARTDIR} >/dev/null 2>/dev/null 584 rm -rf ${PARTDIR}-enc >/dev/null 2>/dev/null 585 mkdir -p ${PARTDIR}-enc >/dev/null 2>/dev/null 586 587 for i in $WORKINGSLICES 588 do 589 populate_disk_label "${i}" 590 done 591 592 # Check if we made a root partition 593 if [ "$FOUNDROOT" = "-1" ] 594 then 595 exit_err "ERROR: No root (/) partition specified!!" 596 fi 597 598 # Check if we made a root partition 599 if [ "$FOUNDROOT" = "1" -a "${USINGBOOTPART}" != "0" ] 600 then 601 exit_err "ERROR: (/) partition isn't first partition on disk!" 602 fi 603 604 if [ "${USINGENCROOT}" = "0" -a "${USINGBOOTPART}" != "0" ] 605 then 606 exit_err "ERROR: Can't encrypt (/) with no (/boot) partition!" 607 fi 608}; 609 610check_fstab_mbr() 611{ 612 local SLICE 613 local FSTAB 614 615 if [ -z "$2" ] 616 then 617 return 1 618 fi 619 620 SLICE="$1" 621 FSTAB="$2/etc/fstab" 622 623 if [ -f "${FSTAB}" ] 624 then 625 PARTLETTER=`echo "$SLICE" | sed -E 's|^.+([a-h])$|\1|'` 626 627 cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1 628 if [ $? -eq 0 ] 629 then 630 if [ "${PARTLETTER}" = "a" ] 631 then 632 FOUNDROOT="0" 633 else 634 FOUNDROOT="1" 635 fi 636 637 ROOTIMAGE="1" 638 639 export FOUNDROOT 640 export ROOTIMAGE 641 fi 642 643 cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1 644 if [ $? -eq 0 ] 645 then 646 if [ "${PARTLETTER}" = "a" ] 647 then 648 USINGBOOTPART="0" 649 else 650 exit_err "/boot partition must be first partition" 651 fi 652 export USINGBOOTPART 653 fi 654 655 return 0 656 fi 657 658 return 1 659}; 660 661check_fstab_gpt() 662{ 663 local SLICE 664 local FSTAB 665 666 if [ -z "$2" ] 667 then 668 return 1 669 fi 670 671 SLICE="$1" 672 FSTAB="$2/etc/fstab" 673 674 if [ -f "${FSTAB}" ] 675 then 676 PARTNUMBER=`echo "${SLICE}" | sed -E 's|^.+p([0-9]*)$|\1|'` 677 678 cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1 679 if [ $? -eq 0 ] 680 then 681 if [ "${PARTNUMBER}" = "2" ] 682 then 683 FOUNDROOT="0" 684 else 685 FOUNDROOT="1" 686 fi 687 688 ROOTIMAGE="1" 689 690 export FOUNDROOT 691 export ROOTIMAGE 692 fi 693 694 cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1 695 if [ $? -eq 0 ] 696 then 697 if [ "${PARTNUMBER}" = "2" ] 698 then 699 USINGBOOTPART="0" 700 else 701 exit_err "/boot partition must be first partition" 702 fi 703 export USINGBOOTPART 704 fi 705 706 return 0 707 fi 708 709 710 return 1 711}; 712 713check_disk_layout() 714{ 715 local SLICES 716 local TYPE 717 local DISK 718 local RES 719 local F 720 721 DISK="$1" 722 TYPE="MBR" 723 724 if [ -z "${DISK}" ] 725 then 726 return 1 727 fi 728 729 SLICES_MBR=`ls /dev/${DISK}s[1-4]*[a-h]* 2>/dev/null` 730 SLICES_GPT=`ls /dev/${DISK}p[0-9]* 2>/dev/null` 731 SLICES_SLICE=`ls /dev/${DISK}[a-h]* 2>/dev/null` 732 733 if [ -n "${SLICES_MBR}" ] 734 then 735 SLICES="${SLICES_MBR}" 736 TYPE="MBR" 737 RES=0 738 fi 739 if [ -n "${SLICES_GPT}" ] 740 then 741 SLICES="${SLICES_GPT}" 742 TYPE="GPT" 743 RES=0 744 fi 745 if [ -n "${SLICES_SLICE}" ] 746 then 747 SLICES="${SLICES_SLICE}" 748 TYPE="MBR" 749 RES=0 750 fi 751 752 for slice in ${SLICES} 753 do 754 F=1 755 mount ${slice} /mnt 2>/dev/null 756 if [ $? -ne 0 ] 757 then 758 continue 759 fi 760 761 if [ "${TYPE}" = "MBR" ] 762 then 763 check_fstab_mbr "${slice}" "/mnt" 764 F="$?" 765 766 elif [ "${TYPE}" = "GPT" ] 767 then 768 check_fstab_gpt "${slice}" "/mnt" 769 F="$?" 770 fi 771 772 if [ ${F} -eq 0 ] 773 then 774 umount /mnt 775 break 776 fi 777 778 umount /mnt 779 done 780 781 return ${RES} 782}; 783