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$ 27 28# Functions related to disk operations using gpart 29 30# See if device is a full disk or partition/slice 31is_disk() 32{ 33 for _dsk in `sysctl -n kern.disks` 34 do 35 if [ "$_dsk" = "${1}" ] ; then return 0 ; fi 36 done 37 38 return 1 39} 40 41# Get a MBR partitions sysid 42get_partition_sysid_mbr() 43{ 44 INPART="0" 45 DISK="$1" 46 PARTNUM=`echo ${2} | sed "s|${DISK}s||g"` 47 fdisk ${DISK} >${TMPDIR}/disk-${DISK} 2>/dev/null 48 while read i 49 do 50 echo "$i" | grep "The data for partition" >/dev/null 2>/dev/null 51 if [ "$?" = "0" ] ; then 52 INPART="0" 53 PART="`echo ${i} | cut -d ' ' -f 5`" 54 if [ "$PART" = "$PARTNUM" ] ; then 55 INPART="1" 56 fi 57 fi 58 59 # In the partition section 60 if [ "$INPART" = "1" ] ; then 61 echo "$i" | grep "^sysid" >/dev/null 2>/dev/null 62 if [ "$?" = "0" ] ; then 63 SYSID="`echo ${i} | tr -s '\t' ' ' | cut -d ' ' -f 2`" 64 break 65 fi 66 67 fi 68 69 done < ${TMPDIR}/disk-${DISK} 70 rm ${TMPDIR}/disk-${DISK} 71 72 VAL="${SYSID}" 73 export VAL 74}; 75 76# Get the partitions MBR label 77get_partition_label_mbr() 78{ 79 INPART="0" 80 DISK="$1" 81 PARTNUM=`echo ${2} | sed "s|${DISK}s||g"` 82 fdisk ${DISK} >${TMPDIR}/disk-${DISK} 2>/dev/null 83 while read i 84 do 85 echo "$i" | grep "The data for partition" >/dev/null 2>/dev/null 86 if [ "$?" = "0" ] ; then 87 INPART="0" 88 PART="`echo ${i} | cut -d ' ' -f 5`" 89 if [ "$PART" = "$PARTNUM" ] ; then 90 INPART="1" 91 fi 92 fi 93 94 # In the partition section 95 if [ "$INPART" = "1" ] ; then 96 echo "$i" | grep "^sysid" >/dev/null 2>/dev/null 97 if [ "$?" = "0" ] ; then 98 LABEL="`echo ${i} | tr -s '\t' ' ' | cut -d ',' -f 2-10`" 99 break 100 fi 101 102 fi 103 104 done < ${TMPDIR}/disk-${DISK} 105 rm ${TMPDIR}/disk-${DISK} 106 107 VAL="${LABEL}" 108 export VAL 109}; 110 111# Get a GPT partitions label 112get_partition_label_gpt() 113{ 114 DISK="${1}" 115 PARTNUM=`echo ${2} | sed "s|${DISK}p||g"` 116 117 gpart show ${DISK} >${TMPDIR}/disk-${DISK} 118 while read i 119 do 120 SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`" 121 if [ "${SLICE}" = "${PARTNUM}" ] ; then 122 LABEL="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 4`" 123 break 124 fi 125 done <${TMPDIR}/disk-${DISK} 126 rm ${TMPDIR}/disk-${DISK} 127 128 VAL="${LABEL}" 129 export VAL 130}; 131 132# Get a partitions startblock 133get_partition_startblock() 134{ 135 DISK="${1}" 136 PARTNUM=`echo ${2} | sed "s|${DISK}p||g" | sed "s|${DISK}s||g"` 137 138 gpart show ${DISK} >${TMPDIR}/disk-${DISK} 139 while read i 140 do 141 SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`" 142 if [ "$SLICE" = "${PARTNUM}" ] ; then 143 SB="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 1`" 144 break 145 fi 146 done <${TMPDIR}/disk-${DISK} 147 rm ${TMPDIR}/disk-${DISK} 148 149 VAL="${SB}" 150 export VAL 151}; 152 153# Get a partitions blocksize 154get_partition_blocksize() 155{ 156 DISK="${1}" 157 PARTNUM=`echo ${2} | sed "s|${DISK}p||g" | sed "s|${DISK}s||g"` 158 159 gpart show ${DISK} >${TMPDIR}/disk-${DISK} 160 while read i 161 do 162 SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`" 163 if [ "$SLICE" = "${PARTNUM}" ] ; then 164 BS="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 2`" 165 break 166 fi 167 done <${TMPDIR}/disk-${DISK} 168 rm ${TMPDIR}/disk-${DISK} 169 170 VAL="${BS}" 171 export VAL 172}; 173 174# Function which returns the partitions on a target disk 175get_disk_partitions() 176{ 177 gpart show ${1} >/dev/null 2>/dev/null 178 if [ "$?" != "0" ] ; then 179 VAL="" ; export VAL 180 return 181 fi 182 183 gpart show ${1} | grep "MBR" >/dev/null 2>/dev/null 184 if [ "$?" = "0" ] ; then 185 type="MBR" 186 else 187 type="GPT" 188 fi 189 190 SLICES="`gpart show ${1} | grep -v ${1} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 4 | sed '/^$/d'`" 191 for i in ${SLICES} 192 do 193 case $type in 194 MBR) name="${1}s${i}" ;; 195 GPT) name="${1}p${i}";; 196 *) name="${1}s${i}";; 197 esac 198 if [ -z "${RSLICES}" ] 199 then 200 RSLICES="${name}" 201 else 202 RSLICES="${RSLICES} ${name}" 203 fi 204 done 205 206 VAL="${RSLICES}" ; export VAL 207}; 208 209# Function which returns a target disks cylinders 210get_disk_cyl() 211{ 212 cyl=`diskinfo -v ${1} | grep "# Cylinders" | tr -s ' ' | cut -f 2` 213 VAL="${cyl}" ; export VAL 214}; 215 216# Function which returns a target disks sectors 217get_disk_sectors() 218{ 219 sec=`diskinfo -v ${1} | grep "# Sectors" | tr -s ' ' | cut -f 2` 220 VAL="${sec}" ; export VAL 221}; 222 223# Function which returns a target disks heads 224get_disk_heads() 225{ 226 head=`diskinfo -v ${1} | grep "# Heads" | tr -s ' ' | cut -f 2` 227 VAL="${head}" ; export VAL 228}; 229 230# Function which returns a target disks mediasize in sectors 231get_disk_mediasize() 232{ 233 mediasize=`diskinfo -v ${1} | grep "# mediasize in sectors" | tr -s ' ' | cut -f 2` 234 VAL="${mediasize}" ; export VAL 235}; 236 237# Function which exports all zpools, making them safe to overwrite potentially 238export_all_zpools() 239{ 240 # Export any zpools 241 for i in `zpool list -H -o name` 242 do 243 zpool export -f ${i} 244 done 245}; 246 247# Function to delete all gparts before starting an install 248delete_all_gpart() 249{ 250 echo_log "Deleting all gparts" 251 DISK="$1" 252 253 # Check for any swaps to stop 254 for i in `gpart show ${DISK} 2>/dev/null | grep 'freebsd-swap' | tr -s ' ' | cut -d ' ' -f 4` 255 do 256 swapoff /dev/${DISK}s${i}b >/dev/null 2>/dev/null 257 swapoff /dev/${DISK}p${i} >/dev/null 2>/dev/null 258 done 259 260 # Delete the gparts now 261 for i in `gpart show ${DISK} 2>/dev/null | tr -s ' ' | cut -d ' ' -f 4` 262 do 263 if [ "${i}" != "${DISK}" -a "${i}" != "-" ] ; then 264 rc_nohalt "gpart delete -i ${i} ${DISK}" 265 fi 266 done 267 268 rc_nohalt "dd if=/dev/zero of=/dev/${DISK} count=3000" 269 270}; 271 272# Function to export all zpools before starting an install 273stop_all_zfs() 274{ 275 # Export all zpools again, so that we can overwrite these partitions potentially 276 for i in `zpool list -H -o name` 277 do 278 zpool export -f ${i} 279 done 280}; 281 282# Function which stops all gmirrors before doing any disk manipulation 283stop_all_gmirror() 284{ 285 DISK="${1}" 286 GPROV="`gmirror list | grep ". Name: mirror/" | cut -d '/' -f 2`" 287 for gprov in $GPROV 288 do 289 gmirror list | grep "Name: ${DISK}" >/dev/null 2>/dev/null 290 if [ "$?" = "0" ] 291 then 292 echo_log "Stopping mirror $gprov $DISK" 293 rc_nohalt "gmirror remove $gprov $DISK" 294 rc_nohalt "dd if=/dev/zero of=/dev/${DISK} count=4096" 295 fi 296 done 297}; 298 299# Make sure we don't have any geli providers active on this disk 300stop_all_geli() 301{ 302 _geld="${1}" 303 cd /dev 304 305 for i in `ls ${_geld}*` 306 do 307 echo $i | grep '.eli' >/dev/null 2>/dev/null 308 if [ "$?" = "0" ] 309 then 310 echo_log "Detaching GELI on ${i}" 311 rc_halt "geli detach ${i}" 312 fi 313 done 314 315}; 316 317# Function which reads in the disk slice config, and performs it 318setup_disk_slice() 319{ 320 321 # Cleanup any slice / mirror dirs 322 rm -rf ${SLICECFGDIR} >/dev/null 2>/dev/null 323 mkdir ${SLICECFGDIR} 324 rm -rf ${MIRRORCFGDIR} >/dev/null 2>/dev/null 325 mkdir ${MIRRORCFGDIR} 326 327 # Start with disk0 328 disknum="0" 329 330 # Make sure all zpools are exported 331 export_all_zpools 332 333 # We are ready to start setting up the disks, lets read the config and do the actions 334 while read line 335 do 336 echo $line | grep "^disk${disknum}=" >/dev/null 2>/dev/null 337 if [ "$?" = "0" ] 338 then 339 340 # Found a disk= entry, lets get the disk we are working on 341 get_value_from_string "${line}" 342 strip_white_space "$VAL" 343 DISK="$VAL" 344 345 # Before we go further, lets confirm this disk really exists 346 if [ ! -e "/dev/${DISK}" ] 347 then 348 exit_err "ERROR: The disk ${DISK} does not exist!" 349 fi 350 351 # Make sure we stop any gmirrors on this disk 352 stop_all_gmirror ${DISK} 353 354 # Make sure we stop any geli stuff on this disk 355 stop_all_geli ${DISK} 356 357 # Make sure we don't have any zpools loaded 358 stop_all_zfs 359 360 fi 361 362 # Lets look if this device will be mirrored on another disk 363 echo $line | grep "^mirror=" >/dev/null 2>/dev/null 364 if [ "$?" = "0" ] 365 then 366 367 # Found a disk= entry, lets get the disk we are working on 368 get_value_from_string "${line}" 369 strip_white_space "$VAL" 370 MIRRORDISK="$VAL" 371 372 # Before we go further, lets confirm this disk really exists 373 if [ ! -e "/dev/${MIRRORDISK}" ] 374 then 375 exit_err "ERROR: The mirror disk ${MIRRORDISK} does not exist!" 376 fi 377 fi 378 379 # Lets see if we have been given a mirror balance choice 380 echo $line | grep "^mirrorbal=" >/dev/null 2>/dev/null 381 if [ "$?" = "0" ] 382 then 383 384 # Found a disk= entry, lets get the disk we are working on 385 get_value_from_string "${line}" 386 strip_white_space "$VAL" 387 MIRRORBAL="$VAL" 388 fi 389 390 echo $line | grep "^partition=" >/dev/null 2>/dev/null 391 if [ "$?" = "0" ] 392 then 393 # Found a partition= entry, lets read / set it 394 get_value_from_string "${line}" 395 strip_white_space "$VAL" 396 PTYPE=`echo $VAL|tr A-Z a-z` 397 398 # We are using free space, figure out the slice number 399 if [ "${PTYPE}" = "free" ] 400 then 401 # Lets figure out what number this slice will be 402 LASTSLICE="`gpart show ${DISK} \ 403 | grep -v ${DISK} \ 404 | grep -v ' free' \ 405 | tr -s '\t' ' ' \ 406 | cut -d ' ' -f 4 \ 407 | sed '/^$/d' \ 408 | tail -n 1`" 409 410 if [ -z "${LASTSLICE}" ] 411 then 412 LASTSLICE="1" 413 else 414 LASTSLICE="`expr $LASTSLICE + 1`" 415 fi 416 417 if [ $LASTSLICE -gt 4 ] 418 then 419 exit_err "ERROR: BSD only supports primary partitions, and there are none availble on $DISK" 420 fi 421 422 fi 423 fi 424 425 # Check if we have an image file defined 426 echo $line | grep "^image=" >/dev/null 2>/dev/null 427 if [ "$?" = "0" ] ; then 428 # Found an image= entry, lets read / set it 429 get_value_from_string "${line}" 430 strip_white_space "$VAL" 431 IMAGE="$VAL" 432 if [ ! -f "$IMAGE" ] ; then 433 exit_err "$IMAGE file does not exist" 434 fi 435 fi 436 437 # Check if we have a partscheme specified 438 echo $line | grep "^partscheme=" >/dev/null 2>/dev/null 439 if [ "$?" = "0" ] ; then 440 # Found a partscheme= entry, lets read / set it 441 get_value_from_string "${line}" 442 strip_white_space "$VAL" 443 PSCHEME="$VAL" 444 if [ "$PSCHEME" != "GPT" -a "$PSCHEME" != "MBR" ] ; then 445 exit_err "Unknown partition scheme: $PSCHEME" 446 fi 447 fi 448 449 echo $line | grep "^bootManager=" >/dev/null 2>/dev/null 450 if [ "$?" = "0" ] 451 then 452 # Found a bootManager= entry, lets read /set it 453 get_value_from_string "${line}" 454 strip_white_space "$VAL" 455 BMANAGER="$VAL" 456 fi 457 458 echo $line | grep "^commitDiskPart" >/dev/null 2>/dev/null 459 if [ "$?" = "0" ] 460 then 461 # Found our flag to commit this disk setup / lets do sanity check and do it 462 if [ ! -z "${DISK}" -a ! -z "${PTYPE}" ] 463 then 464 case ${PTYPE} in 465 all) 466 if [ "$PSCHEME" = "MBR" -o -z "$PSCHEME" ] ; then 467 PSCHEME="MBR" 468 tmpSLICE="${DISK}s1" 469 else 470 tmpSLICE="${DISK}p1" 471 fi 472 473 run_gpart_full "${DISK}" "${BMANAGER}" "${PSCHEME}" 474 ;; 475 476 s1|s2|s3|s4) 477 tmpSLICE="${DISK}${PTYPE}" 478 # Get the number of the slice we are working on 479 s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" 480 run_gpart_slice "${DISK}" "${BMANAGER}" "${s}" 481 ;; 482 483 free) 484 tmpSLICE="${DISK}s${LASTSLICE}" 485 run_gpart_free "${DISK}" "${LASTSLICE}" "${BMANAGER}" 486 ;; 487 488 image) 489 if [ -z "${IMAGE}" ] 490 then 491 exit_err "ERROR: partition type image specified with no image!" 492 fi 493 ;; 494 495 *) exit_err "ERROR: Unknown PTYPE: $PTYPE" ;; 496 esac 497 498 499 if [ -n "${IMAGE}" ] 500 then 501 local DEST 502 503 if [ -n "${tmpSLICE}" ] 504 then 505 DEST="${tmpSLICE}" 506 else 507 DEST="${DISK}" 508 fi 509 510 if iscompressed "${IMAGE}" 511 then 512 local COMPRESSION 513 514 get_compression_type "${IMAGE}" 515 COMPRESSION="${VAL}" 516 517 decompress_file "${IMAGE}" "${COMPRESSION}" 518 IMAGE="${VAL}" 519 fi 520 521 write_image "${IMAGE}" "${DEST}" 522 check_disk_layout "${DEST}" 523 fi 524 525 # Now save which disk<num> this is, so we can parse it later during slice partition setup 526 if [ -z "${IMAGE}" ] 527 then 528 echo "disk${disknum}" >${SLICECFGDIR}/$tmpSLICE 529 fi 530 531 # Save any mirror config 532 if [ ! -z "$MIRRORDISK" ] 533 then 534 # Default to round-robin if the user didn't specify 535 if [ -z "$MIRRORBAL" ] 536 then 537 MIRRORBAL="round-robin" 538 fi 539 echo "$MIRRORDISK:$MIRRORBAL" >${MIRRORCFGDIR}/$DISK 540 fi 541 542 # Increment our disk counter to look for next disk and unset 543 unset BMANAGER PTYPE DISK MIRRORDISK MIRRORBAL PSCHEME IMAGE 544 disknum="`expr $disknum + 1`" 545 else 546 exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" 547 fi 548 fi 549 550 done <${CFGF} 551 552}; 553 554# Stop all gjournals on disk / slice 555stop_gjournal() 556{ 557 _gdsk="$1" 558 # Check if we need to shutdown any journals on this drive 559 ls /dev/${_gdsk}*.journal >/dev/null 2>/dev/null 560 if [ "$?" = "0" ] 561 then 562 cd /dev 563 for i in `ls ${_gdsk}*.journal` 564 do 565 rawjournal="`echo ${i} | cut -d '.' -f 1`" 566 gjournal stop -f ${rawjournal} >>${LOGOUT} 2>>${LOGOUT} 567 gjournal clear ${rawjournal} >>${LOGOUT} 2>>${LOGOUT} 568 done 569 fi 570} ; 571 572# Function which runs gpart and creates a single large GPT partition scheme 573init_gpt_full_disk() 574{ 575 _intDISK=$1 576 577 # Set our sysctl so we can overwrite any geom using drives 578 sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT} 579 580 # Stop any journaling 581 stop_gjournal "${_intDISK}" 582 583 # Remove any existing partitions 584 delete_all_gpart "${_intDISK}" 585 586 #Erase any existing bootloader 587 echo_log "Cleaning up ${_intDISK}" 588 rc_halt "dd if=/dev/zero of=/dev/${_intDISK} count=2048" 589 590 sleep 2 591 592 echo_log "Running gpart on ${_intDISK}" 593 rc_halt "gpart create -s GPT ${_intDISK}" 594 rc_halt "gpart add -b 34 -s 128 -t freebsd-boot ${_intDISK}" 595 596 echo_log "Stamping boot sector on ${_intDISK}" 597 rc_halt "gpart bootcode -b /boot/pmbr ${_intDISK}" 598 599} 600 601# Function which runs gpart and creates a single large MBR partition scheme 602init_mbr_full_disk() 603{ 604 _intDISK=$1 605 _intBOOT=$2 606 607 startblock="63" 608 609 # Set our sysctl so we can overwrite any geom using drives 610 sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT} 611 612 # Stop any journaling 613 stop_gjournal "${_intDISK}" 614 615 # Remove any existing partitions 616 delete_all_gpart "${_intDISK}" 617 618 #Erase any existing bootloader 619 echo_log "Cleaning up ${_intDISK}" 620 rc_halt "dd if=/dev/zero of=/dev/${_intDISK} count=2048" 621 622 sleep 2 623 624 echo_log "Running gpart on ${_intDISK}" 625 rc_halt "gpart create -s mbr ${_intDISK}" 626 627 # Lets figure out disk size in blocks 628 # Get the cyl of this disk 629 get_disk_cyl "${_intDISK}" 630 cyl="${VAL}" 631 632 # Get the heads of this disk 633 get_disk_heads "${_intDISK}" 634 head="${VAL}" 635 636 # Get the tracks/sectors of this disk 637 get_disk_sectors "${_intDISK}" 638 sec="${VAL}" 639 640 # Multiply them all together to get our total blocks 641 totalblocks="`expr ${cyl} \* ${head}`" 642 totalblocks="`expr ${totalblocks} \* ${sec}`" 643 if [ -z "${totalblocks}" ] 644 then 645 totalblocks=`gpart show "${_intDISK}"|tail -2|head -1|awk '{ print $2 }'` 646 fi 647 648 # Now set the ending block to the total disk block size 649 sizeblock="`expr ${totalblocks} - ${startblock}`" 650 651 # Install new partition setup 652 echo_log "Running gpart add on ${_intDISK}" 653 rc_halt "gpart add -b ${startblock} -s ${sizeblock} -t freebsd -i 1 ${_intDISK}" 654 sleep 2 655 656 echo_log "Cleaning up ${_intDISK}s1" 657 rc_halt "dd if=/dev/zero of=/dev/${_intDISK}s1 count=1024" 658 659 if [ "$_intBOOT" = "bsd" ] ; then 660 echo_log "Stamping boot sector on ${_intDISK}" 661 rc_halt "gpart bootcode -b /boot/boot0 ${_intDISK}" 662 fi 663 664} 665 666# Function which runs gpart and creates a single large slice 667run_gpart_full() 668{ 669 DISK=$1 670 BOOT=$2 671 SCHEME=$3 672 673 if [ "$SCHEME" = "MBR" ] ; then 674 init_mbr_full_disk "$DISK" "$BOOT" 675 slice="${DISK}-1-mbr" 676 else 677 init_gpt_full_disk "$DISK" 678 slice="${DISK}-1-gpt" 679 fi 680 681 # Lets save our slice, so we know what to look for in the config file later on 682 if [ -z "$WORKINGSLICES" ] 683 then 684 WORKINGSLICES="${slice}" 685 export WORKINGSLICES 686 else 687 WORKINGSLICES="${WORKINGSLICES} ${slice}" 688 export WORKINGSLICES 689 fi 690}; 691 692# Function which runs gpart on a specified s1-4 slice 693run_gpart_slice() 694{ 695 DISK=$1 696 if [ ! -z "$2" ] 697 then 698 BMANAGER="$2" 699 fi 700 701 # Set the slice we will use later 702 slice="${1}s${3}" 703 704 # Set our sysctl so we can overwrite any geom using drives 705 sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT} 706 707 # Get the number of the slice we are working on 708 slicenum="$3" 709 710 # Stop any journaling 711 stop_gjournal "${slice}" 712 713 # Make sure we have disabled swap on this drive 714 if [ -e "${slice}b" ] 715 then 716 swapoff ${slice}b >/dev/null 2>/dev/null 717 swapoff ${slice}b.eli >/dev/null 2>/dev/null 718 fi 719 720 # Modify partition type 721 echo_log "Running gpart modify on ${DISK}" 722 rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}" 723 sleep 2 724 725 # Clean up old partition 726 echo_log "Cleaning up $slice" 727 rc_halt "dd if=/dev/zero of=/dev/${DISK}s${slicenum} count=1024" 728 729 sleep 1 730 731 if [ "${BMANAGER}" = "bsd" ] 732 then 733 echo_log "Stamping boot sector on ${DISK}" 734 rc_halt "gpart bootcode -b /boot/boot0 ${DISK}" 735 fi 736 737 # Set the slice to the format we'll be using for gpart later 738 slice="${1}-${3}-mbr" 739 740 # Lets save our slice, so we know what to look for in the config file later on 741 if [ -z "$WORKINGSLICES" ] 742 then 743 WORKINGSLICES="${slice}" 744 export WORKINGSLICES 745 else 746 WORKINGSLICES="${WORKINGSLICES} ${slice}" 747 export WORKINGSLICES 748 fi 749}; 750 751# Function which runs gpart and creates a new slice from free disk space 752run_gpart_free() 753{ 754 DISK=$1 755 SLICENUM=$2 756 if [ ! -z "$3" ] 757 then 758 BMANAGER="$3" 759 fi 760 761 # Set our sysctl so we can overwrite any geom using drives 762 sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT} 763 764 slice="${DISK}s${SLICENUM}" 765 slicenum="${SLICENUM}" 766 767 # Working on the first slice, make sure we have MBR setup 768 gpart show ${DISK} >/dev/null 2>/dev/null 769 if [ "$?" != "0" -a "$SLICENUM" = "1" ] ; then 770 echo_log "Initializing disk, no existing MBR setup" 771 rc_halt "gpart create -s mbr ${DISK}" 772 fi 773 774 # Lets get the starting block first 775 if [ "${slicenum}" = "1" ] 776 then 777 startblock="63" 778 else 779 # Lets figure out where the prior slice ends 780 checkslice="`expr ${slicenum} - 1`" 781 782 # Get starting block of this slice 783 sblk=`gpart show ${DISK} | grep -v ${DISK} | tr -s '\t' ' ' | sed '/^$/d' | grep " ${checkslice} " | cut -d ' ' -f 2` 784 blksize=`gpart show ${DISK} | grep -v ${DISK} | tr -s '\t' ' ' | sed '/^$/d' | grep " ${checkslice} " | cut -d ' ' -f 3` 785 startblock="`expr ${sblk} + ${blksize}`" 786 fi 787 788 # No slice after the new slice, lets figure out the free space remaining and use it 789 # Get the cyl of this disk 790 get_disk_cyl "${DISK}" 791 cyl="${VAL}" 792 793 # Get the heads of this disk 794 get_disk_heads "${DISK}" 795 head="${VAL}" 796 797 # Get the tracks/sectors of this disk 798 get_disk_sectors "${DISK}" 799 sec="${VAL}" 800 801 # Multiply them all together to get our total blocks 802 totalblocks="`expr ${cyl} \* ${head}`" 803 totalblocks="`expr ${totalblocks} \* ${sec}`" 804 805 806 # Now set the ending block to the total disk block size 807 sizeblock="`expr ${totalblocks} - ${startblock}`" 808 809 # Install new partition setup 810 echo_log "Running gpart on ${DISK}" 811 rc_halt "gpart add -b ${startblock} -s ${sizeblock} -t freebsd -i ${slicenum} ${DISK}" 812 sleep 2 813 814 echo_log "Cleaning up $slice" 815 rc_halt "dd if=/dev/zero of=/dev/${slice} count=1024" 816 817 sleep 1 818 819 if [ "${BMANAGER}" = "bsd" ] 820 then 821 echo_log "Stamping boot sector on ${DISK}" 822 rc_halt "gpart bootcode -b /boot/boot0 ${DISK}" 823 fi 824 825 slice="${DISK}-${SLICENUM}-mbr" 826 # Lets save our slice, so we know what to look for in the config file later on 827 if [ -z "$WORKINGSLICES" ] 828 then 829 WORKINGSLICES="${slice}" 830 export WORKINGSLICES 831 else 832 WORKINGSLICES="${WORKINGSLICES} ${slice}" 833 export WORKINGSLICES 834 fi 835}; 836