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