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