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