]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - usr.sbin/pc-sysinstall/backend/functions-disk.sh
MFC r296656:
[FreeBSD/stable/10.git] / usr.sbin / pc-sysinstall / backend / functions-disk.sh
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
31 is_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
43 get_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
77 get_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
111 get_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
131 get_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
151 get_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
171 get_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
201 get_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
208 get_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
215 get_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
222 get_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
229 get_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
238 delete_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
264 stop_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
282 stop_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
302 stop_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
320 setup_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
583 init_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
597 stop_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
616 wipe_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
629 init_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
654 init_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
679 init_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
721 run_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
750 run_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
804 run_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
861 run_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 };