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