diff options
Diffstat (limited to 'usr/sbin/pc-sysinstall/backend/functions-disk.sh')
-rwxr-xr-x | usr/sbin/pc-sysinstall/backend/functions-disk.sh | 421 |
1 files changed, 288 insertions, 133 deletions
diff --git a/usr/sbin/pc-sysinstall/backend/functions-disk.sh b/usr/sbin/pc-sysinstall/backend/functions-disk.sh index 3ab86dd..2bb3ecc 100755 --- a/usr/sbin/pc-sysinstall/backend/functions-disk.sh +++ b/usr/sbin/pc-sysinstall/backend/functions-disk.sh @@ -23,18 +23,19 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD: src/usr.sbin/pc-sysinstall/backend/functions-disk.sh,v 1.2 2010/06/27 16:46:11 imp Exp $ +# $FreeBSD: src/usr.sbin/pc-sysinstall/backend/functions-disk.sh,v 1.8 2010/11/10 05:32:36 imp Exp $ # Functions related to disk operations using gpart # See if device is a full disk or partition/slice -is_disk() { - for _dsk in `sysctl -n kern.disks` - do - if [ "$_dsk" = "${1}" ] ; then return 0 ; fi - done +is_disk() +{ + for _dsk in `sysctl -n kern.disks` + do + if [ "$_dsk" = "${1}" ] ; then return 0 ; fi + done - return 1 + return 1 } # Get a MBR partitions sysid @@ -190,9 +191,9 @@ get_disk_partitions() for i in ${SLICES} do case $type in - MBR) name="${1}s${i}" ;; - GPT) name="${1}p${i}";; - *) name="${1}s${i}";; + MBR) name="${1}s${i}" ;; + GPT) name="${1}p${i}";; + *) name="${1}s${i}";; esac if [ -z "${RSLICES}" ] then @@ -226,8 +227,16 @@ get_disk_heads() VAL="${head}" ; export VAL }; +# Function which returns a target disks mediasize in sectors +get_disk_mediasize() +{ + mediasize=`diskinfo -v ${1} | grep "# mediasize in sectors" | tr -s ' ' | cut -f 2` + VAL="${mediasize}" ; export VAL +}; + # Function which exports all zpools, making them safe to overwrite potentially -export_all_zpools() { +export_all_zpools() +{ # Export any zpools for i in `zpool list -H -o name` do @@ -324,144 +333,216 @@ setup_disk_slice() # We are ready to start setting up the disks, lets read the config and do the actions while read line do - echo $line | grep "^disk${disknum}=" >/dev/null 2>/dev/null - if [ "$?" = "0" ] - then - - # Found a disk= entry, lets get the disk we are working on - get_value_from_string "${line}" - strip_white_space "$VAL" - DISK="$VAL" + echo $line | grep "^disk${disknum}=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] + then + + # Found a disk= entry, lets get the disk we are working on + get_value_from_string "${line}" + strip_white_space "$VAL" + DISK="$VAL" - # Before we go further, lets confirm this disk really exists - if [ ! -e "/dev/${DISK}" ] - then - exit_err "ERROR: The disk ${DISK} does not exist!" - fi + # Before we go further, lets confirm this disk really exists + if [ ! -e "/dev/${DISK}" ] + then + exit_err "ERROR: The disk ${DISK} does not exist!" + fi - # Make sure we stop any gmirrors on this disk - stop_all_gmirror ${DISK} + # Make sure we stop any gmirrors on this disk + stop_all_gmirror ${DISK} - # Make sure we stop any geli stuff on this disk - stop_all_geli ${DISK} + # Make sure we stop any geli stuff on this disk + stop_all_geli ${DISK} - # Make sure we don't have any zpools loaded - stop_all_zfs + # Make sure we don't have any zpools loaded + stop_all_zfs - fi + fi - # Lets look if this device will be mirrored on another disk - echo $line | grep "^mirror=" >/dev/null 2>/dev/null - if [ "$?" = "0" ] - then + # Lets look if this device will be mirrored on another disk + echo $line | grep "^mirror=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] + then - # Found a disk= entry, lets get the disk we are working on - get_value_from_string "${line}" - strip_white_space "$VAL" - MIRRORDISK="$VAL" + # Found a disk= entry, lets get the disk we are working on + get_value_from_string "${line}" + strip_white_space "$VAL" + MIRRORDISK="$VAL" - # Before we go further, lets confirm this disk really exists - if [ ! -e "/dev/${MIRRORDISK}" ] - then - exit_err "ERROR: The mirror disk ${MIRRORDISK} does not exist!" - fi - fi + # Before we go further, lets confirm this disk really exists + if [ ! -e "/dev/${MIRRORDISK}" ] + then + exit_err "ERROR: The mirror disk ${MIRRORDISK} does not exist!" + fi + fi - # Lets see if we have been given a mirror balance choice - echo $line | grep "^mirrorbal=" >/dev/null 2>/dev/null - if [ "$?" = "0" ] - then + # Lets see if we have been given a mirror balance choice + echo $line | grep "^mirrorbal=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] + then - # Found a disk= entry, lets get the disk we are working on - get_value_from_string "${line}" - strip_white_space "$VAL" - MIRRORBAL="$VAL" - fi + # Found a disk= entry, lets get the disk we are working on + get_value_from_string "${line}" + strip_white_space "$VAL" + MIRRORBAL="$VAL" + fi - echo $line | grep "^partition=" >/dev/null 2>/dev/null - if [ "$?" = "0" ] - then - # Found a partition= entry, lets read / set it - get_value_from_string "${line}" - strip_white_space "$VAL" - PTYPE="$VAL" - - # We are using free space, figure out the slice number - if [ "${PTYPE}" = "free" -o "${PTYPE}" = "FREE" ] - then - # Lets figure out what number this slice will be - LASTSLICE="`gpart show ${DISK} | grep -v ${DISK} | grep -v ' free' |tr -s '\t' ' ' | cut -d ' ' -f 4 | sed '/^$/d' | tail -n 1`" - if [ -z "${LASTSLICE}" ] - then - LASTSLICE="1" - else - LASTSLICE="`expr $LASTSLICE + 1`" - fi - - if [ $LASTSLICE -gt 4 ] - then - exit_err "ERROR: BSD only supports primary partitions, and there are none availble on $DISK" - fi + echo $line | grep "^partition=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] + then + # Found a partition= entry, lets read / set it + get_value_from_string "${line}" + strip_white_space "$VAL" + PTYPE=`echo $VAL|tr A-Z a-z` + + # We are using free space, figure out the slice number + if [ "${PTYPE}" = "free" ] + then + # Lets figure out what number this slice will be + LASTSLICE="`gpart show ${DISK} \ + | grep -v ${DISK} \ + | grep -v ' free' \ + | tr -s '\t' ' ' \ + | cut -d ' ' -f 4 \ + | sed '/^$/d' \ + | tail -n 1`" + + if [ -z "${LASTSLICE}" ] + then + LASTSLICE="1" + else + LASTSLICE="`expr $LASTSLICE + 1`" + fi + + if [ $LASTSLICE -gt 4 ] + then + exit_err "ERROR: BSD only supports primary partitions, and there are none availble on $DISK" + fi + + fi + fi - fi - fi + # Check if we have an image file defined + echo $line | grep "^image=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] ; then + # Found an image= entry, lets read / set it + get_value_from_string "${line}" + strip_white_space "$VAL" + IMAGE="$VAL" + if [ ! -f "$IMAGE" ] ; then + exit_err "$IMAGE file does not exist" + fi + fi - echo $line | grep "^bootManager=" >/dev/null 2>/dev/null - if [ "$?" = "0" ] - then - # Found a bootManager= entry, lets read /set it - get_value_from_string "${line}" - strip_white_space "$VAL" - BMANAGER="$VAL" - fi + # Check if we have a partscheme specified + echo $line | grep "^partscheme=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] ; then + # Found a partscheme= entry, lets read / set it + get_value_from_string "${line}" + strip_white_space "$VAL" + PSCHEME="$VAL" + if [ "$PSCHEME" != "GPT" -a "$PSCHEME" != "MBR" ] ; then + exit_err "Unknown partition scheme: $PSCHEME" + fi + fi - echo $line | grep "^commitDiskPart" >/dev/null 2>/dev/null - if [ "$?" = "0" ] - then - # Found our flag to commit this disk setup / lets do sanity check and do it - if [ ! -z "${DISK}" -a ! -z "${PTYPE}" ] - then - case ${PTYPE} in - all|ALL) tmpSLICE="${DISK}p1" - run_gpart_full "${DISK}" "${BMANAGER}" ;; - s1|s2|s3|s4) tmpSLICE="${DISK}${PTYPE}" - # Get the number of the slice we are working on - s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" - run_gpart_slice "${DISK}" "${BMANAGER}" "${s}" ;; - free|FREE) tmpSLICE="${DISK}s${LASTSLICE}" - run_gpart_free "${DISK}" "${LASTSLICE}" "${BMANAGER}" ;; - *) exit_err "ERROR: Unknown PTYPE: $PTYPE" ;; - esac - - # Now save which disk<num> this is, so we can parse it later during slice partition setup - echo "disk${disknum}" >${SLICECFGDIR}/$tmpSLICE - - # Save any mirror config - if [ ! -z "$MIRRORDISK" ] - then - # Default to round-robin if the user didn't specify - if [ -z "$MIRRORBAL" ] - then - MIRRORBAL="round-robin" - fi - echo "$MIRRORDISK:$MIRRORBAL" >${MIRRORCFGDIR}/$DISK - fi - - - # Increment our disk counter to look for next disk and unset - unset BMANAGER PTYPE DISK MIRRORDISK MIRRORBAL - disknum="`expr $disknum + 1`" - else - exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" - fi - fi + echo $line | grep "^bootManager=" >/dev/null 2>/dev/null + if [ "$?" = "0" ] + then + # Found a bootManager= entry, lets read /set it + get_value_from_string "${line}" + strip_white_space "$VAL" + BMANAGER="$VAL" + fi + + echo $line | grep "^commitDiskPart" >/dev/null 2>/dev/null + if [ "$?" = "0" ] + then + # Found our flag to commit this disk setup / lets do sanity check and do it + if [ ! -z "${DISK}" -a ! -z "${PTYPE}" ] + then + case ${PTYPE} in + all) + if [ "$PSCHEME" = "MBR" -o -z "$PSCHEME" ] ; then + PSCHEME="MBR" + tmpSLICE="${DISK}s1" + else + tmpSLICE="${DISK}p1" + fi + + run_gpart_full "${DISK}" "${BMANAGER}" "${PSCHEME}" + ;; + + s1|s2|s3|s4) + tmpSLICE="${DISK}${PTYPE}" + # Get the number of the slice we are working on + s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" + run_gpart_slice "${DISK}" "${BMANAGER}" "${s}" + ;; + + free) + tmpSLICE="${DISK}s${LASTSLICE}" + run_gpart_free "${DISK}" "${LASTSLICE}" "${BMANAGER}" + ;; + + image) + if [ -z "${IMAGE}" ] + then + exit_err "ERROR: partition type image specified with no image!" + fi + ;; + + *) exit_err "ERROR: Unknown PTYPE: $PTYPE" ;; + esac + + + if [ -n "${IMAGE}" ] + then + local DEST + + if [ -n "${tmpSLICE}" ] + then + DEST="${tmpSLICE}" + else + DEST="${DISK}" + fi + + write_image "${IMAGE}" "${DEST}" + check_disk_layout "${DEST}" + fi + + # Now save which disk<num> this is, so we can parse it later during slice partition setup + if [ -z "${IMAGE}" ] + then + echo "disk${disknum}" >${SLICECFGDIR}/$tmpSLICE + fi + + # Save any mirror config + if [ ! -z "$MIRRORDISK" ] + then + # Default to round-robin if the user didn't specify + if [ -z "$MIRRORBAL" ] + then + MIRRORBAL="round-robin" + fi + echo "$MIRRORDISK:$MIRRORBAL" >${MIRRORCFGDIR}/$DISK + fi + + # Increment our disk counter to look for next disk and unset + unset BMANAGER PTYPE DISK MIRRORDISK MIRRORBAL PSCHEME IMAGE + disknum="`expr $disknum + 1`" + else + exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" + fi + fi done <${CFGF} }; # Stop all gjournals on disk / slice -stop_gjournal() { +stop_gjournal() +{ _gdsk="$1" # Check if we need to shutdown any journals on this drive ls /dev/${_gdsk}*.journal >/dev/null 2>/dev/null @@ -477,7 +558,7 @@ stop_gjournal() { fi } ; -# Function which runs gpart and creates a single large slice +# Function which runs gpart and creates a single large GPT partition scheme init_gpt_full_disk() { _intDISK=$1 @@ -506,14 +587,88 @@ init_gpt_full_disk() } +# Function which runs gpart and creates a single large MBR partition scheme +init_mbr_full_disk() +{ + _intDISK=$1 + _intBOOT=$2 + + startblock="63" + + # Set our sysctl so we can overwrite any geom using drives + sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT} + + # Stop any journaling + stop_gjournal "${_intDISK}" + + # Remove any existing partitions + delete_all_gpart "${_intDISK}" + + #Erase any existing bootloader + echo_log "Cleaning up ${_intDISK}" + rc_halt "dd if=/dev/zero of=/dev/${_intDISK} count=2048" + + sleep 2 + + echo_log "Running gpart on ${_intDISK}" + rc_halt "gpart create -s mbr ${_intDISK}" + + # Lets figure out disk size in blocks + # Get the cyl of this disk + get_disk_cyl "${_intDISK}" + cyl="${VAL}" + + # Get the heads of this disk + get_disk_heads "${_intDISK}" + head="${VAL}" + + # Get the tracks/sectors of this disk + get_disk_sectors "${_intDISK}" + sec="${VAL}" + + # Multiply them all together to get our total blocks + totalblocks="`expr ${cyl} \* ${head}`" + totalblocks="`expr ${totalblocks} \* ${sec}`" + if [ -z "${totalblocks}" ] + then + totalblocks=`gpart show "${_intDISK}"|tail -2|head -1|awk '{ print $2 }'` + fi + + # Now set the ending block to the total disk block size + sizeblock="`expr ${totalblocks} - ${startblock}`" + + # Install new partition setup + echo_log "Running gpart add on ${_intDISK}" + rc_halt "gpart add -b ${startblock} -s ${sizeblock} -t freebsd -i 1 ${_intDISK}" + sleep 2 + + echo_log "Cleaning up ${_intDISK}s1" + rc_halt "dd if=/dev/zero of=/dev/${_intDISK}s1 count=1024" + + if [ "$_intBOOT" = "bsd" ] ; then + echo_log "Stamping boot0 on ${_intDISK}" + rc_halt "gpart bootcode -b /boot/boot0 ${_intDISK}" + else + echo_log "Stamping boot1 on ${_intDISK}" + rc_halt "gpart bootcode -b /boot/boot1 ${_intDISK}" + fi + +} + # Function which runs gpart and creates a single large slice run_gpart_full() { DISK=$1 + BOOT=$2 + SCHEME=$3 - init_gpt_full_disk "$DISK" - - slice="${DISK}-1-gpt" + if [ "$SCHEME" = "MBR" ] ; then + init_mbr_full_disk "$DISK" "$BOOT" + slice="${DISK}-1-mbr" + else + init_gpt_full_disk "$DISK" + slice="${DISK}-1-gpt" + fi # Lets save our slice, so we know what to look for in the config file later on if [ -z "$WORKINGSLICES" ] |