functions-disk.sh revision 297346
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 297346 2016-03-28 09:36:52Z 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  if [ ! -c /dev/zfs ]; then
267    return;
268  fi
269  local DISK="`echo ${1} | sed 's|/dev/||g'`"
270
271  # Export any zpools using this device so we can overwrite
272  for i in `zpool list -H -o name`
273  do
274    ztst=`zpool status ${i} | grep "ONLINE" | awk '{print $1}' | grep -q ${DISK}`
275    if [ "$ztst" = "$DISK" ] ; then
276      zpool export -f ${i}
277    fi
278  done
279};
280
281# Function which stops all gmirrors before doing any disk manipulation
282stop_all_gmirror()
283{
284  if [ ! -d /dev/mirror ]; then
285    return;
286  fi
287  local DISK="`echo ${1} | sed 's|/dev/||g'`"
288  GPROV="`gmirror list | grep ". Name: mirror/" | cut -d '/' -f 2`"
289  for gprov in $GPROV 
290  do
291    gmirror list | grep -q "Name: ${DISK}" 2>/dev/null
292    if [ $? -eq 0 ]
293    then
294      echo_log "Stopping mirror $gprov $DISK"
295      rc_nohalt "gmirror remove $gprov $DISK"
296      wipe_metadata "${DISK}"
297    fi
298  done
299};
300
301# Make sure we don't have any geli providers active on this disk
302stop_all_geli()
303{
304  local _geld="`echo ${1} | sed 's|/dev/||g'`"
305  cd /dev
306
307  for i in `ls ${_geld}*`
308  do
309    echo $i | grep -q '.eli' 2>/dev/null
310    if [ $? -eq 0 ]
311    then
312      echo_log "Detaching GELI on ${i}"
313      rc_halt "geli detach ${i}"
314    fi
315  done
316
317};
318
319# Function which reads in the disk slice config, and performs it
320setup_disk_slice()
321{
322
323  # Cleanup any slice / mirror dirs
324  rm -rf ${SLICECFGDIR} >/dev/null 2>/dev/null
325  mkdir ${SLICECFGDIR}
326  rm -rf ${MIRRORCFGDIR} >/dev/null 2>/dev/null
327  mkdir ${MIRRORCFGDIR}
328
329  # Start with disk0 and gm0
330  disknum="0"
331  gmnum="0"
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 -q "^disk${disknum}=" 2>/dev/null
337    if [ $? -eq 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      echo "${DISK}" | grep -q '^/dev/'
346      if [ $? -ne 0 ] ; then DISK="/dev/$DISK" ; fi
347     
348      # Before we go further, lets confirm this disk really exists
349      if [ ! -e "${DISK}" ] ; then
350        exit_err "ERROR: The disk ${DISK} does not exist!"
351      fi
352
353      # Make sure we stop any gmirrors on this disk
354      stop_all_gmirror ${DISK}
355
356      # Make sure we stop any geli stuff on this disk
357      stop_all_geli ${DISK}
358
359      # Make sure we don't have any zpools loaded
360      stop_all_zfs ${DISK}
361
362     fi
363
364    # Lets look if this device will be mirrored on another disk
365    echo $line | grep -q "^mirror=" 2>/dev/null
366    if [ $? -eq 0 ]
367    then
368
369      # Found a disk= entry, lets get the disk we are working on
370      get_value_from_string "${line}"
371      strip_white_space "$VAL"
372      MIRRORDISK="$VAL"
373      echo "${MIRRORDISK}" | grep -q '^/dev/'
374      if [ $? -ne 0 ] ; then MIRRORDISK="/dev/$MIRRORDISK" ; fi
375     
376      # Before we go further, lets confirm this disk really exists
377      if [ ! -e "${MIRRORDISK}" ]
378      then
379        exit_err "ERROR: The mirror disk ${MIRRORDISK} does not exist!"
380      fi
381
382      # Make sure we stop any gmirrors on this mirror disk
383      stop_all_gmirror ${MIRRORDISK}
384
385      # Make sure we stop any geli stuff on this mirror disk
386      stop_all_geli ${MIRRORDISK}
387
388      # Make sure we don't have any zpools mirror loaded
389      stop_all_zfs ${MIRRORDISK}
390
391    fi
392
393    # Lets see if we have been given a mirror balance choice
394    echo $line | grep -q "^mirrorbal=" 2>/dev/null
395    if [ $? -eq 0 ]
396    then
397
398      # Found a disk= entry, lets get the disk we are working on
399      get_value_from_string "${line}"
400      strip_white_space "$VAL"
401      MIRRORBAL="$VAL"
402    fi
403
404    echo $line | grep -q "^partition=" 2>/dev/null
405    if [ $? -eq 0 ]
406    then
407      # Found a partition= entry, lets read / set it 
408      get_value_from_string "${line}"
409      strip_white_space "$VAL"
410      PTYPE=`echo $VAL|tr A-Z a-z`
411
412      # We are using free space, figure out the slice number
413      if [ "${PTYPE}" = "free" ]
414      then
415        # Lets figure out what number this slice will be
416        LASTSLICE="`gpart show ${DISK} \
417          | grep -v ${DISK} \
418          | grep -v ' free' \
419          | tr -s '\t' ' ' \
420          | cut -d ' ' -f 4 \
421          | sed '/^$/d' \
422          | tail -n 1`"
423
424        if [ -z "${LASTSLICE}" ]
425        then
426          LASTSLICE="1"
427        else
428            LASTSLICE=$((LASTSLICE+1))
429        fi
430
431        if [ $LASTSLICE -gt 4 ]
432        then
433          exit_err "ERROR: BSD only supports primary partitions, and there are none available on $DISK"
434        fi
435
436      fi
437    fi
438
439    # Check if we have an image file defined
440    echo $line | grep -q "^image=" 2>/dev/null
441    if [ $? -eq 0 ] ; then
442      # Found an image= entry, lets read / set it
443      get_value_from_string "${line}"
444      strip_white_space "$VAL"
445      IMAGE="$VAL"
446      if [ ! -f "$IMAGE" ] ; then
447        exit_err "$IMAGE file does not exist"
448      fi
449    fi
450
451    # Check if we have a partscheme specified
452    echo $line | grep -q "^partscheme=" 2>/dev/null
453    if [ $? -eq 0 ] ; then
454      # Found a partscheme= entry, lets read / set it 
455      get_value_from_string "${line}"
456      strip_white_space "$VAL"
457      PSCHEME="$VAL"
458      if [ "$PSCHEME" != "GPT" -a "$PSCHEME" != "MBR" ] ; then
459        exit_err "Unknown partition scheme: $PSCHEME" 
460      fi
461    fi
462
463    echo $line | grep -q "^bootManager=" 2>/dev/null
464    if [ $? -eq 0 ]
465    then
466      # Found a bootManager= entry, lets read /set it
467      get_value_from_string "${line}"
468      strip_white_space "$VAL"
469      BMANAGER="$VAL"
470    fi
471
472    echo $line | grep -q "^commitDiskPart" 2>/dev/null
473    if [ $? -eq 0 ]
474    then
475      # Found our flag to commit this disk setup / lets do sanity check and do it
476      if [ ! -z "${DISK}" -a ! -z "${PTYPE}" ]
477      then
478	# Make sure we are only installing ppc to full disk
479	if [ `uname -m` = "powerpc" -o `uname -m` = "powerpc64" ]; then
480	  if [ "$PTYPE" != "all" ] ; then
481	    exit_err "powerpc can only be installed to a full disk"
482	  fi
483	fi
484
485        case ${PTYPE} in
486          all)
487            # If we have a gmirror, lets set it up
488            if [ -n "$MIRRORDISK" ]; then
489              # Default to round-robin if the user didn't specify
490              if [ -z "$MIRRORBAL" ]; then MIRRORBAL="round-robin" ; fi
491
492	      _mFile=`echo $DISK | sed 's|/|%|g'`
493              echo "$MIRRORDISK:$MIRRORBAL:gm${gmnum}" >${MIRRORCFGDIR}/$_mFile
494	      init_gmirror "$gmnum" "$MIRRORBAL" "$DISK" "$MIRRORDISK"
495
496	      # Reset DISK to the gmirror device
497	      DISK="/dev/mirror/gm${gmnum}"
498              gmnum=$((gmknum+1))
499            fi
500
501            if [ "$PSCHEME" = "MBR" -o -z "$PSCHEME" ] ; then
502              PSCHEME="MBR"
503              tmpSLICE="${DISK}s1"  
504            else
505              tmpSLICE="${DISK}p1"  
506            fi
507
508	    if [ `uname -m` = "powerpc" -o `uname -m` = "powerpc64" ]
509	    then
510              PSCHEME="APM"
511              tmpSLICE="${DISK}s1"  
512	    fi
513
514            run_gpart_full "${DISK}" "${BMANAGER}" "${PSCHEME}"
515            ;;
516
517          s1|s2|s3|s4)
518            tmpSLICE="${DISK}${PTYPE}" 
519            # Get the number of the slice we are working on
520            s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" 
521            run_gpart_slice "${DISK}" "${BMANAGER}" "${s}"
522            ;;
523
524          p1|p2|p3|p4|p5|p6|p7|p8|p9|p10|p11|p12|p13|p14|p15|p16|p17|p18|p19|p20)
525            tmpSLICE="${DISK}${PTYPE}" 
526            # Get the number of the gpt partition we are working on
527            s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" 
528            run_gpart_gpt_part "${DISK}" "${BMANAGER}" "${s}"
529            ;;
530
531          free)
532            tmpSLICE="${DISK}s${LASTSLICE}"
533            run_gpart_free "${DISK}" "${LASTSLICE}" "${BMANAGER}"
534            ;;
535
536          image)
537            if [ -z "${IMAGE}" ]
538            then
539              exit_err "ERROR: partition type image specified with no image!"
540            fi 
541            ;;
542
543          *) exit_err "ERROR: Unknown PTYPE: $PTYPE" ;;
544        esac
545        
546
547		if [ -n "${IMAGE}" ]
548		then 
549          local DEST
550          
551		  if [ -n "${tmpSLICE}" ]
552          then
553			DEST="${tmpSLICE}"
554          else 
555			DEST="${DISK}"
556          fi 
557
558          write_image "${IMAGE}" "${DEST}"
559          check_disk_layout "${DEST}"
560		fi
561
562        # Now save which disk<num> this is, so we can parse it later during slice partition setup
563        if [ -z "${IMAGE}" ]
564        then
565	  _sFile=`echo $tmpSLICE | sed 's|/|-|g'`
566          echo "disk${disknum}" >${SLICECFGDIR}/$_sFile
567        fi
568
569        # Increment our disk counter to look for next disk and unset
570        unset BMANAGER PTYPE DISK MIRRORDISK MIRRORBAL PSCHEME IMAGE
571        disknum=$((disknum+1))
572      else
573        exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" 
574      fi
575    fi
576
577  done <${CFGF}
578
579};
580
581
582# Init the gmirror device
583init_gmirror()
584{
585    local _mNum=$1
586    local _mBal=$2
587    local _mDisk=$3
588
589    # Create this mirror device
590    rc_halt "gmirror label -vb ${_mBal} gm${_mNum} ${_mDisk}"
591
592    sleep 3
593
594}
595
596# Stop all gjournals on disk / slice
597stop_gjournal()
598{
599  _gdsk="`echo $1 | sed 's|/dev/||g'`"
600  # Check if we need to shutdown any journals on this drive
601  ls /dev/${_gdsk}*.journal >/dev/null 2>/dev/null
602  if [ $? -eq 0 ]
603  then
604    cd /dev
605    for i in `ls ${_gdsk}*.journal`
606    do
607      rawjournal="`echo ${i} | cut -d '.' -f 1`"
608      gjournal stop -f ${rawjournal} >>${LOGOUT} 2>>${LOGOUT}
609      gjournal clear ${rawjournal} >>${LOGOUT} 2>>${LOGOUT}
610    done
611  fi
612} ;
613
614
615# Function to wipe the potential metadata from a disk
616wipe_metadata()
617{
618  echo_log "Wiping possible metadata on ${1}"
619  local SIZE="`diskinfo ${1} | awk '{print int($3/(1024*1024)) }'`"
620  if [ "$SIZE" -gt "5" ]  ; then
621    rc_halt "dd if=/dev/zero of=${1} bs=1m count=1"
622    rc_nohalt "dd if=/dev/zero of=${1} bs=1m oseek=$((SIZE-4))"
623  else
624    rc_nohalt "dd if=/dev/zero of=${1} bs=128k"
625  fi
626} ;
627
628# Function which runs gpart and creates a single large APM partition scheme
629init_apm_full_disk()
630{
631  _intDISK=$1
632 
633  # Set our sysctl so we can overwrite any geom using drives
634  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
635
636  # Stop any journaling
637  stop_gjournal "${_intDISK}"
638
639  # Remove any existing partitions
640  delete_all_gpart "${_intDISK}"
641
642  sleep 2
643
644  echo_log "Running gpart on ${_intDISK}"
645  rc_halt "gpart create -s APM ${_intDISK}"
646  rc_halt "gpart add -s 800k -t freebsd-boot ${_intDISK}"
647  
648  echo_log "Stamping boot sector on ${_intDISK}"
649  rc_halt "gpart bootcode -p /boot/boot1.hfs -i 1 ${_intDISK}"
650
651}
652
653# Function which runs gpart and creates a single large GPT partition scheme
654init_gpt_full_disk()
655{
656  _intDISK=$1
657 
658  # Set our sysctl so we can overwrite any geom using drives
659  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
660
661  # Stop any journaling
662  stop_gjournal "${_intDISK}"
663
664  # Remove any existing partitions
665  delete_all_gpart "${_intDISK}"
666
667  sleep 2
668
669  echo_log "Running gpart on ${_intDISK}"
670  rc_halt "gpart create -s GPT ${_intDISK}"
671  rc_halt "gpart add -b 34 -s 128 -t freebsd-boot ${_intDISK}"
672  
673  echo_log "Stamping boot sector on ${_intDISK}"
674  rc_halt "gpart bootcode -b /boot/pmbr ${_intDISK}"
675
676}
677
678# Function which runs gpart and creates a single large MBR partition scheme
679init_mbr_full_disk()
680{
681  _intDISK=$1
682  _intBOOT=$2
683 
684  startblock="2016"
685
686  # Set our sysctl so we can overwrite any geom using drives
687  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
688
689  # Stop any journaling
690  stop_gjournal "${_intDISK}"
691
692  # Remove any existing partitions
693  delete_all_gpart "${_intDISK}"
694
695  sleep 2
696
697  echo_log "Running gpart on ${_intDISK}"
698  rc_halt "gpart create -s mbr -f active ${_intDISK}"
699
700  # Install new partition setup
701  echo_log "Running gpart add on ${_intDISK}"
702  rc_halt "gpart add -a 4k -t freebsd -i 1 ${_intDISK}"
703  sleep 2
704  
705  wipe_metadata "${_intDISK}s1"
706  
707  # Make the partition active
708  rc_halt "gpart set -a active -i 1 ${_intDISK}"
709
710  if [ "$_intBOOT" = "bsd" ] ; then
711    echo_log "Stamping boot0 on ${_intDISK}"
712    rc_halt "gpart bootcode -b /boot/boot0 ${_intDISK}"
713  else
714    echo_log "Stamping boot1 on ${_intDISK}"
715    rc_halt "gpart bootcode -b /boot/boot1 ${_intDISK}"
716  fi
717
718}
719
720# Function which runs gpart and creates a single large slice
721run_gpart_full()
722{
723  DISK=$1
724  BOOT=$2
725  SCHEME=$3
726
727  if [ "$SCHEME" = "APM" ] ; then
728    init_apm_full_disk "$DISK"
729    slice=`echo "${DISK}:1:apm" | sed 's|/|-|g'`
730  elif [ "$SCHEME" = "MBR" ] ; then
731    init_mbr_full_disk "$DISK" "$BOOT"
732    slice=`echo "${DISK}:1:mbr" | sed 's|/|-|g'`
733  else
734    init_gpt_full_disk "$DISK"
735    slice=`echo "${DISK}:1:gpt" | sed 's|/|-|g'`
736  fi
737
738  # Lets save our slice, so we know what to look for in the config file later on
739  if [ -z "$WORKINGSLICES" ]
740  then
741    WORKINGSLICES="${slice}"
742    export WORKINGSLICES
743  else
744    WORKINGSLICES="${WORKINGSLICES} ${slice}"
745    export WORKINGSLICES
746  fi
747};
748
749# Function which runs gpart on a specified gpt partition
750run_gpart_gpt_part()
751{
752  DISK=$1
753
754  # Set the slice we will use later
755  slice="${1}p${3}"
756 
757  # Set our sysctl so we can overwrite any geom using drives
758  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
759
760  # Get the number of the slice we are working on
761  slicenum="$3"
762
763  # Stop any journaling
764  stop_gjournal "${slice}"
765
766  # Make sure we have disabled swap on this drive
767  if [ -e "${slice}b" ]
768  then
769   swapoff ${slice}b >/dev/null 2>/dev/null
770   swapoff ${slice}b.eli >/dev/null 2>/dev/null
771  fi
772
773  # Modify partition type
774  echo_log "Running gpart modify on ${DISK}"
775  rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}"
776  sleep 2
777
778  wipe_metadata "${slice}"
779
780  sleep 4
781
782  # Init the MBR partition
783  rc_halt "gpart create -s BSD ${DISK}p${slicenum}"
784
785  # Stamp the bootloader
786  sleep 4
787  rc_halt "gpart bootcode -b /boot/boot ${DISK}p${slicenum}"
788
789  # Set the slice to the format we'll be using for gpart later
790  slice=`echo "${1}:${3}:gptslice" | sed 's|/|-|g'`
791
792  # Lets save our slice, so we know what to look for in the config file later on
793  if [ -z "$WORKINGSLICES" ]
794  then
795    WORKINGSLICES="${slice}"
796    export WORKINGSLICES
797  else
798    WORKINGSLICES="${WORKINGSLICES} ${slice}"
799    export WORKINGSLICES
800  fi
801};
802
803# Function which runs gpart on a specified s1-4 slice
804run_gpart_slice()
805{
806  DISK=$1
807  if [ -n "$2" ]
808  then
809    BMANAGER="$2"
810  fi
811
812  # Set the slice we will use later
813  slice="${1}s${3}"
814 
815  # Set our sysctl so we can overwrite any geom using drives
816  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
817
818  # Get the number of the slice we are working on
819  slicenum="$3"
820
821  # Stop any journaling
822  stop_gjournal "${slice}"
823
824  # Make sure we have disabled swap on this drive
825  if [ -e "${slice}b" ]
826  then
827   swapoff ${slice}b >/dev/null 2>/dev/null
828   swapoff ${slice}b.eli >/dev/null 2>/dev/null
829  fi
830
831  # Modify partition type
832  echo_log "Running gpart modify on ${DISK}"
833  rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}"
834  sleep 2
835
836  wipe_metadata "${slice}"
837
838  sleep 1
839
840  if [ "${BMANAGER}" = "bsd" ]
841  then
842    echo_log "Stamping boot sector on ${DISK}"
843    rc_halt "gpart bootcode -b /boot/boot0 ${DISK}"
844  fi
845
846  # Set the slice to the format we'll be using for gpart later
847  slice=`echo "${1}:${3}:mbr" | sed 's|/|-|g'`
848
849  # Lets save our slice, so we know what to look for in the config file later on
850  if [ -z "$WORKINGSLICES" ]
851  then
852    WORKINGSLICES="${slice}"
853    export WORKINGSLICES
854  else
855    WORKINGSLICES="${WORKINGSLICES} ${slice}"
856    export WORKINGSLICES
857  fi
858};
859
860# Function which runs gpart and creates a new slice from free disk space
861run_gpart_free()
862{
863  DISK=$1
864  SLICENUM=$2
865  if [ -n "$3" ]
866  then
867    BMANAGER="$3"
868  fi
869
870  # Set our sysctl so we can overwrite any geom using drives
871  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
872
873  slice="${DISK}s${SLICENUM}"
874  slicenum="${SLICENUM}" 
875
876  # Working on the first slice, make sure we have MBR setup
877  gpart show ${DISK} >/dev/null 2>/dev/null
878  if [ $? -ne 0 -a "$SLICENUM" = "1" ] ; then
879    echo_log "Initializing disk, no existing MBR setup"
880    rc_halt "gpart create -s mbr ${DISK}"
881  fi
882
883  # Install new partition setup
884  echo_log "Running gpart on ${DISK}"
885  rc_halt "gpart add -a 4k -t freebsd -i ${slicenum} ${DISK}"
886  sleep 2
887
888  wipe_metadata "${slice}"
889
890  sleep 1
891
892  if [ "${BMANAGER}" = "bsd" ]
893  then
894    echo_log "Stamping boot sector on ${DISK}"
895    rc_halt "gpart bootcode -b /boot/boot0 ${DISK}"
896  fi
897
898  slice=`echo "${DISK}:${SLICENUM}:mbr" | sed 's|/|-|g'`
899  # Lets save our slice, so we know what to look for in the config file later on
900  if [ -z "$WORKINGSLICES" ]
901  then
902    WORKINGSLICES="${slice}"
903    export WORKINGSLICES
904  else
905    WORKINGSLICES="${WORKINGSLICES} ${slice}"
906    export WORKINGSLICES
907  fi
908};
909