1#!/bin/sh
2#-
3# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4#
5# Copyright (c) 2010 iXsystems, Inc.  All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28# $FreeBSD$
29
30# Functions related to disk operations using gpart
31
32# See if device is a full disk or partition/slice
33is_disk()
34{
35  for _dsk in `sysctl -n kern.disks`
36  do
37    [ "$_dsk" = "${1}" ] && return 0
38    [ "/dev/$_dsk" = "${1}" ] && return 0
39  done
40
41  return 1
42}
43
44# Get a MBR partitions sysid
45get_partition_sysid_mbr()
46{
47  INPART="0"
48  DISK="$1"
49  PARTNUM=`echo ${2} | sed "s|${DISK}s||g"`
50  fdisk ${DISK} >${TMPDIR}/disk-${DISK} 2>/dev/null
51  while read i
52  do
53    echo "$i" | grep -q "The data for partition" 2>/dev/null
54    if [ $? -eq 0 ] ; then
55       INPART="0"
56       PART="`echo ${i} | cut -d ' ' -f 5`"
57       if [ "$PART" = "$PARTNUM" ] ; then
58          INPART="1"
59       fi
60    fi
61
62    # In the partition section
63    if [ "$INPART" = "1" ] ; then
64       echo "$i" | grep -q "^sysid" 2>/dev/null
65       if [ $? -eq 0 ] ; then
66         SYSID="`echo ${i} | tr -s '\t' ' ' | cut -d ' ' -f 2`"
67         break
68       fi
69
70    fi
71
72  done < ${TMPDIR}/disk-${DISK}
73  rm ${TMPDIR}/disk-${DISK}
74
75  export VAL="${SYSID}"
76};
77
78# Get the partitions MBR label
79get_partition_label_mbr()
80{
81  INPART="0"
82  DISK="$1"
83  PARTNUM=`echo ${2} | sed "s|${DISK}s||g"`
84  fdisk ${DISK} >${TMPDIR}/disk-${DISK} 2>/dev/null
85  while read i
86  do
87    echo "$i" | grep -q "The data for partition" 2>/dev/null
88    if [ $? -eq 0 ] ; then
89       INPART="0"
90       PART="`echo ${i} | cut -d ' ' -f 5`"
91       if [ "$PART" = "$PARTNUM" ] ; then
92          INPART="1"
93       fi
94    fi
95
96    # In the partition section
97    if [ "$INPART" = "1" ] ; then
98       echo "$i" | grep -q "^sysid" 2>/dev/null
99       if [ $? -eq 0 ] ; then
100         LABEL="`echo ${i} | tr -s '\t' ' ' | cut -d ',' -f 2-10`"
101         break
102       fi
103
104    fi
105
106  done < ${TMPDIR}/disk-${DISK}
107  rm ${TMPDIR}/disk-${DISK}
108
109  export VAL="${LABEL}"
110};
111
112# Get a GPT partitions label
113get_partition_label_gpt()
114{
115  DISK="${1}"
116  PARTNUM=`echo ${2} | sed "s|${DISK}p||g"`
117
118  gpart show ${DISK} >${TMPDIR}/disk-${DISK}
119  while read i
120  do
121     SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`"
122     if [ "${SLICE}" = "${PARTNUM}" ] ; then
123       LABEL="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 4`"
124       break
125     fi
126  done <${TMPDIR}/disk-${DISK}
127  rm ${TMPDIR}/disk-${DISK}
128
129  export VAL="${LABEL}"
130};
131
132# Get a partitions startblock
133get_partition_startblock()
134{
135  DISK="${1}"
136  PARTNUM=`echo ${2} | sed "s|${DISK}p||g" | sed "s|${DISK}s||g"`
137
138  gpart show ${DISK} >${TMPDIR}/disk-${DISK}
139  while read i
140  do
141     SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`"
142     if [ "$SLICE" = "${PARTNUM}" ] ; then
143       SB="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 1`"
144       break
145     fi
146  done <${TMPDIR}/disk-${DISK}
147  rm ${TMPDIR}/disk-${DISK}
148
149  export VAL="${SB}"
150};
151
152# Get a partitions blocksize
153get_partition_blocksize()
154{
155  DISK="${1}"
156  PARTNUM=`echo ${2} | sed "s|${DISK}p||g" | sed "s|${DISK}s||g"`
157
158  gpart show ${DISK} >${TMPDIR}/disk-${DISK}
159  while read i
160  do
161     SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`"
162     if [ "$SLICE" = "${PARTNUM}" ] ; then
163       BS="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 2`"
164       break
165     fi
166  done <${TMPDIR}/disk-${DISK}
167  rm ${TMPDIR}/disk-${DISK}
168
169  export VAL="${BS}"
170};
171
172# Function which returns the partitions on a target disk
173get_disk_partitions()
174{
175  gpart show ${1} >/dev/null 2>/dev/null
176  if [ $? -ne 0 ] ; then
177    export VAL=""
178    return
179  fi
180
181  type=`gpart show ${1} | awk '/^=>/ { printf("%s",$5); }'`
182
183  SLICES="`gpart show ${1} | grep -v ${1} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 4 | sed '/^$/d'`"
184  for i in ${SLICES}
185  do
186    case $type in
187      MBR) name="${1}s${i}" ;;
188      GPT) name="${1}p${i}";;
189      *) name="${1}s${i}";;
190    esac
191    if [ -z "${RSLICES}" ]
192    then
193      RSLICES="${name}"
194    else
195      RSLICES="${RSLICES} ${name}"
196    fi
197  done
198
199  export VAL="${RSLICES}"
200};
201
202# Function which returns a target disks cylinders
203get_disk_cyl()
204{
205  cyl=`diskinfo -v ${1} | grep "# Cylinders" | tr -s ' ' | cut -f 2`
206  export VAL="${cyl}"
207};
208
209# Function which returns a target disks sectors
210get_disk_sectors()
211{
212  sec=`diskinfo -v ${1} | grep "# Sectors" | tr -s ' ' | cut -f 2`
213  export VAL="${sec}"
214};
215
216# Function which returns a target disks heads
217get_disk_heads()
218{
219  head=`diskinfo -v ${1} | grep "# Heads" | tr -s ' ' | cut -f 2`
220  export VAL="${head}"
221};
222
223# Function which returns a target disks mediasize in sectors
224get_disk_mediasize()
225{
226  mediasize=`diskinfo -v ${1} | grep "# mediasize in sectors" | tr -s ' ' | cut -f 2`
227  export VAL="${mediasize}"
228};
229
230# Function which returns a target disks mediasize in megabytes
231get_disk_mediasize_mb()
232{
233  mediasize=`diskinfo -v ${1} | grep "# mediasize in bytes" | tr -s ' ' | cut -f 2`
234  mediasize=`expr $mediasize / 1024`
235  mediasize=`expr $mediasize / 1024`
236  export VAL="${mediasize}"
237};
238
239# Function to delete all gparts before starting an install
240delete_all_gpart()
241{
242  echo_log "Deleting all gparts"
243  local DISK="$1"
244
245  # Check for any swaps to stop
246  for i in `swapctl -l | grep "$DISK" | awk '{print $1}'`
247  do
248    swapoff ${i} >/dev/null 2>/dev/null
249  done
250
251  # Delete the gparts now
252  for i in `gpart show ${DISK} 2>/dev/null | tr -s ' ' | cut -d ' ' -f 4`
253  do
254   if [ "/dev/${i}" != "${DISK}" -a "${i}" != "-" ] ; then
255     rc_nohalt "gpart delete -i ${i} ${DISK}"
256   fi
257  done
258
259  # Destroy the disk geom
260  rc_nohalt "gpart destroy ${DISK}"
261
262  wipe_metadata "${DISK}"
263};
264
265# Function to export all zpools before starting an install
266stop_all_zfs()
267{
268  if [ ! -c /dev/zfs ]; then
269    return;
270  fi
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  if [ ! -d /dev/mirror ]; then
287    return;
288  fi
289  local DISK="`echo ${1} | sed 's|/dev/||g'`"
290  GPROV="`gmirror list | grep ". Name: mirror/" | cut -d '/' -f 2`"
291  for gprov in $GPROV
292  do
293    gmirror list | grep -q "Name: ${DISK}" 2>/dev/null
294    if [ $? -eq 0 ]
295    then
296      echo_log "Stopping mirror $gprov $DISK"
297      rc_nohalt "gmirror remove $gprov $DISK"
298      wipe_metadata "${DISK}"
299    fi
300  done
301};
302
303# Make sure we don't have any geli providers active on this disk
304stop_all_geli()
305{
306  local _geld="`echo ${1} | sed 's|/dev/||g'`"
307  cd /dev
308
309  for i in `ls ${_geld}*`
310  do
311    echo $i | grep -q '.eli' 2>/dev/null
312    if [ $? -eq 0 ]
313    then
314      echo_log "Detaching GELI on ${i}"
315      rc_halt "geli detach ${i}"
316    fi
317  done
318
319};
320
321# Function which reads in the disk slice config, and performs it
322setup_disk_slice()
323{
324
325  # Cleanup any slice / mirror dirs
326  rm -rf ${SLICECFGDIR} >/dev/null 2>/dev/null
327  mkdir ${SLICECFGDIR}
328  rm -rf ${MIRRORCFGDIR} >/dev/null 2>/dev/null
329  mkdir ${MIRRORCFGDIR}
330
331  # Start with disk0 and gm0
332  disknum="0"
333  gmnum="0"
334
335  # We are ready to start setting up the disks, lets read the config and do the actions
336  while read line
337  do
338    echo $line | grep -q "^disk${disknum}=" 2>/dev/null
339    if [ $? -eq 0 ]
340    then
341
342      # Found a disk= entry, lets get the disk we are working on
343      get_value_from_string "${line}"
344      strip_white_space "$VAL"
345      DISK="$VAL"
346
347      echo "${DISK}" | grep -q '^/dev/'
348      if [ $? -ne 0 ] ; then DISK="/dev/$DISK" ; fi
349
350      # Before we go further, lets confirm this disk really exists
351      if [ ! -e "${DISK}" ] ; then
352        exit_err "ERROR: The disk ${DISK} does not exist!"
353      fi
354
355      # Make sure we stop any gmirrors on this disk
356      stop_all_gmirror ${DISK}
357
358      # Make sure we stop any geli stuff on this disk
359      stop_all_geli ${DISK}
360
361      # Make sure we don't have any zpools loaded
362      stop_all_zfs ${DISK}
363
364     fi
365
366    # Lets look if this device will be mirrored on another disk
367    echo $line | grep -q "^mirror=" 2>/dev/null
368    if [ $? -eq 0 ]
369    then
370
371      # Found a disk= entry, lets get the disk we are working on
372      get_value_from_string "${line}"
373      strip_white_space "$VAL"
374      MIRRORDISK="$VAL"
375      echo "${MIRRORDISK}" | grep -q '^/dev/'
376      if [ $? -ne 0 ] ; then MIRRORDISK="/dev/$MIRRORDISK" ; fi
377
378      # Before we go further, lets confirm this disk really exists
379      if [ ! -e "${MIRRORDISK}" ]
380      then
381        exit_err "ERROR: The mirror disk ${MIRRORDISK} does not exist!"
382      fi
383
384      # Make sure we stop any gmirrors on this mirror disk
385      stop_all_gmirror ${MIRRORDISK}
386
387      # Make sure we stop any geli stuff on this mirror disk
388      stop_all_geli ${MIRRORDISK}
389
390      # Make sure we don't have any zpools mirror loaded
391      stop_all_zfs ${MIRRORDISK}
392
393    fi
394
395    # Lets see if we have been given a mirror balance choice
396    echo $line | grep -q "^mirrorbal=" 2>/dev/null
397    if [ $? -eq 0 ]
398    then
399
400      # Found a disk= entry, lets get the disk we are working on
401      get_value_from_string "${line}"
402      strip_white_space "$VAL"
403      MIRRORBAL="$VAL"
404    fi
405
406    echo $line | grep -q "^partition=" 2>/dev/null
407    if [ $? -eq 0 ]
408    then
409      # Found a partition= entry, lets read / set it
410      get_value_from_string "${line}"
411      strip_white_space "$VAL"
412      PTYPE=`echo $VAL|tr A-Z a-z`
413
414      # We are using free space, figure out the slice number
415      if [ "${PTYPE}" = "free" ]
416      then
417        # Lets figure out what number this slice will be
418        LASTSLICE="`gpart show ${DISK} \
419          | grep -v ${DISK} \
420          | grep -v ' free' \
421          | tr -s '\t' ' ' \
422          | cut -d ' ' -f 4 \
423          | sed '/^$/d' \
424          | tail -n 1`"
425
426        if [ -z "${LASTSLICE}" ]
427        then
428          LASTSLICE="1"
429        else
430            LASTSLICE=$((LASTSLICE+1))
431        fi
432
433        if [ $LASTSLICE -gt 4 ]
434        then
435          exit_err "ERROR: BSD only supports primary partitions, and there are none available on $DISK"
436        fi
437
438      fi
439    fi
440
441    # Check if we have an image file defined
442    echo $line | grep -q "^image=" 2>/dev/null
443    if [ $? -eq 0 ] ; then
444      # Found an image= entry, lets read / set it
445      get_value_from_string "${line}"
446      strip_white_space "$VAL"
447      IMAGE="$VAL"
448      if [ ! -f "$IMAGE" ] ; then
449        exit_err "$IMAGE file does not exist"
450      fi
451    fi
452
453    # Check if we have a partscheme specified
454    echo $line | grep -q "^partscheme=" 2>/dev/null
455    if [ $? -eq 0 ] ; then
456      # Found a partscheme= entry, lets read / set it
457      get_value_from_string "${line}"
458      strip_white_space "$VAL"
459      PSCHEME="$VAL"
460      if [ "$PSCHEME" != "GPT" -a "$PSCHEME" != "MBR" ] ; then
461        exit_err "Unknown partition scheme: $PSCHEME"
462      fi
463    fi
464
465    echo $line | grep -q "^bootManager=" 2>/dev/null
466    if [ $? -eq 0 ]
467    then
468      # Found a bootManager= entry, lets read /set it
469      get_value_from_string "${line}"
470      strip_white_space "$VAL"
471      BMANAGER="$VAL"
472    fi
473
474    echo $line | grep -q "^commitDiskPart" 2>/dev/null
475    if [ $? -eq 0 ]
476    then
477      # Found our flag to commit this disk setup / lets do sanity check and do it
478      if [ ! -z "${DISK}" -a ! -z "${PTYPE}" ]
479      then
480	# Make sure we are only installing ppc to full disk
481	if [ `uname -m` = "powerpc" -o `uname -m` = "powerpc64" ]; then
482	  if [ "$PTYPE" != "all" ] ; then
483	    exit_err "powerpc can only be installed to a full disk"
484	  fi
485	fi
486
487        case ${PTYPE} in
488          all)
489            # If we have a gmirror, lets set it up
490            if [ -n "$MIRRORDISK" ]; then
491              # Default to round-robin if the user didn't specify
492              if [ -z "$MIRRORBAL" ]; then MIRRORBAL="round-robin" ; fi
493
494	      _mFile=`echo $DISK | sed 's|/|%|g'`
495              echo "$MIRRORDISK:$MIRRORBAL:gm${gmnum}" >${MIRRORCFGDIR}/$_mFile
496	      init_gmirror "$gmnum" "$MIRRORBAL" "$DISK" "$MIRRORDISK"
497
498	      # Reset DISK to the gmirror device
499	      DISK="/dev/mirror/gm${gmnum}"
500              gmnum=$((gmknum+1))
501            fi
502
503            if [ "$PSCHEME" = "MBR" -o -z "$PSCHEME" ] ; then
504              PSCHEME="MBR"
505              tmpSLICE="${DISK}s1"
506            else
507              tmpSLICE="${DISK}p1"
508            fi
509
510	    if [ `uname -m` = "powerpc" -o `uname -m` = "powerpc64" ]
511	    then
512              PSCHEME="APM"
513              tmpSLICE="${DISK}s1"
514	    fi
515
516            run_gpart_full "${DISK}" "${BMANAGER}" "${PSCHEME}"
517            ;;
518
519          s1|s2|s3|s4)
520            tmpSLICE="${DISK}${PTYPE}"
521            # Get the number of the slice we are working on
522            s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`"
523            run_gpart_slice "${DISK}" "${BMANAGER}" "${s}"
524            ;;
525
526          p1|p2|p3|p4|p5|p6|p7|p8|p9|p10|p11|p12|p13|p14|p15|p16|p17|p18|p19|p20)
527            tmpSLICE="${DISK}${PTYPE}"
528            # Get the number of the gpt partition we are working on
529            s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`"
530            run_gpart_gpt_part "${DISK}" "${BMANAGER}" "${s}"
531            ;;
532
533          free)
534            tmpSLICE="${DISK}s${LASTSLICE}"
535            run_gpart_free "${DISK}" "${LASTSLICE}" "${BMANAGER}"
536            ;;
537
538          image)
539            if [ -z "${IMAGE}" ]
540            then
541              exit_err "ERROR: partition type image specified with no image!"
542            fi
543            ;;
544
545          *) exit_err "ERROR: Unknown PTYPE: $PTYPE" ;;
546        esac
547
548
549		if [ -n "${IMAGE}" ]
550		then
551          local DEST
552
553		  if [ -n "${tmpSLICE}" ]
554          then
555			DEST="${tmpSLICE}"
556          else
557			DEST="${DISK}"
558          fi
559
560          write_image "${IMAGE}" "${DEST}"
561          check_disk_layout "${DEST}"
562		fi
563
564        # Now save which disk<num> this is, so we can parse it later during slice partition setup
565        if [ -z "${IMAGE}" ]
566        then
567	  _sFile=`echo $tmpSLICE | sed 's|/|-|g'`
568          echo "disk${disknum}" >${SLICECFGDIR}/$_sFile
569        fi
570
571        # Increment our disk counter to look for next disk and unset
572        unset BMANAGER PTYPE DISK MIRRORDISK MIRRORBAL PSCHEME IMAGE
573        disknum=$((disknum+1))
574      else
575        exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!"
576      fi
577    fi
578
579  done <${CFGF}
580
581};
582
583
584# Init the gmirror device
585init_gmirror()
586{
587    local _mNum=$1
588    local _mBal=$2
589    local _mDisk=$3
590
591    # Create this mirror device
592    rc_halt "gmirror label -vb ${_mBal} gm${_mNum} ${_mDisk}"
593
594    sleep 3
595
596}
597
598# Stop all gjournals on disk / slice
599stop_gjournal()
600{
601  _gdsk="`echo $1 | sed 's|/dev/||g'`"
602  # Check if we need to shutdown any journals on this drive
603  ls /dev/${_gdsk}*.journal >/dev/null 2>/dev/null
604  if [ $? -eq 0 ]
605  then
606    cd /dev
607    for i in `ls ${_gdsk}*.journal`
608    do
609      rawjournal="`echo ${i} | cut -d '.' -f 1`"
610      gjournal stop -f ${rawjournal} >>${LOGOUT} 2>>${LOGOUT}
611      gjournal clear ${rawjournal} >>${LOGOUT} 2>>${LOGOUT}
612    done
613  fi
614} ;
615
616
617# Function to wipe the potential metadata from a disk
618wipe_metadata()
619{
620  echo_log "Wiping possible metadata on ${1}"
621  local SIZE="`diskinfo ${1} | awk '{print int($3/(1024*1024)) }'`"
622  if [ "$SIZE" -gt "5" ]  ; then
623    rc_halt "dd if=/dev/zero of=${1} bs=1m count=1"
624    rc_nohalt "dd if=/dev/zero of=${1} bs=1m oseek=$((SIZE-4))"
625  else
626    rc_nohalt "dd if=/dev/zero of=${1} bs=128k"
627  fi
628} ;
629
630# Function which runs gpart and creates a single large APM partition scheme
631init_apm_full_disk()
632{
633  _intDISK=$1
634
635  # Set our sysctl so we can overwrite any geom using drives
636  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
637
638  # Stop any journaling
639  stop_gjournal "${_intDISK}"
640
641  # Remove any existing partitions
642  delete_all_gpart "${_intDISK}"
643
644  sleep 2
645
646  echo_log "Running gpart on ${_intDISK}"
647  rc_halt "gpart create -s APM ${_intDISK}"
648  rc_halt "gpart add -s 800k -t freebsd-boot ${_intDISK}"
649
650  echo_log "Stamping boot sector on ${_intDISK}"
651  rc_halt "gpart bootcode -p /boot/boot1.hfs -i 1 ${_intDISK}"
652
653}
654
655# Function which runs gpart and creates a single large GPT partition scheme
656init_gpt_full_disk()
657{
658  _intDISK=$1
659
660  # Set our sysctl so we can overwrite any geom using drives
661  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
662
663  # Stop any journaling
664  stop_gjournal "${_intDISK}"
665
666  # Remove any existing partitions
667  delete_all_gpart "${_intDISK}"
668
669  sleep 2
670
671  echo_log "Running gpart on ${_intDISK}"
672  rc_halt "gpart create -s GPT ${_intDISK}"
673  rc_halt "gpart add -b 34 -s 128 -t freebsd-boot ${_intDISK}"
674
675  echo_log "Stamping boot sector on ${_intDISK}"
676  rc_halt "gpart bootcode -b /boot/pmbr ${_intDISK}"
677
678}
679
680# Function which runs gpart and creates a single large MBR partition scheme
681init_mbr_full_disk()
682{
683  _intDISK=$1
684  _intBOOT=$2
685
686  startblock="2016"
687
688  # Set our sysctl so we can overwrite any geom using drives
689  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
690
691  # Stop any journaling
692  stop_gjournal "${_intDISK}"
693
694  # Remove any existing partitions
695  delete_all_gpart "${_intDISK}"
696
697  sleep 2
698
699  echo_log "Running gpart on ${_intDISK}"
700  rc_halt "gpart create -s mbr -f active ${_intDISK}"
701
702  # Install new partition setup
703  echo_log "Running gpart add on ${_intDISK}"
704  rc_halt "gpart add -a 4k -t freebsd -i 1 ${_intDISK}"
705  sleep 2
706
707  wipe_metadata "${_intDISK}s1"
708
709  # Make the partition active
710  rc_halt "gpart set -a active -i 1 ${_intDISK}"
711
712  if [ "$_intBOOT" = "bsd" ] ; then
713    echo_log "Stamping boot0 on ${_intDISK}"
714    rc_halt "gpart bootcode -b /boot/boot0 ${_intDISK}"
715  else
716    echo_log "Stamping boot1 on ${_intDISK}"
717    rc_halt "gpart bootcode -b /boot/boot1 ${_intDISK}"
718  fi
719
720}
721
722# Function which runs gpart and creates a single large slice
723run_gpart_full()
724{
725  DISK=$1
726  BOOT=$2
727  SCHEME=$3
728
729  if [ "$SCHEME" = "APM" ] ; then
730    init_apm_full_disk "$DISK"
731    slice=`echo "${DISK}:1:apm" | sed 's|/|-|g'`
732  elif [ "$SCHEME" = "MBR" ] ; then
733    init_mbr_full_disk "$DISK" "$BOOT"
734    slice=`echo "${DISK}:1:mbr" | sed 's|/|-|g'`
735  else
736    init_gpt_full_disk "$DISK"
737    slice=`echo "${DISK}:1:gpt" | sed 's|/|-|g'`
738  fi
739
740  # Lets save our slice, so we know what to look for in the config file later on
741  if [ -z "$WORKINGSLICES" ]
742  then
743    WORKINGSLICES="${slice}"
744    export WORKINGSLICES
745  else
746    WORKINGSLICES="${WORKINGSLICES} ${slice}"
747    export WORKINGSLICES
748  fi
749};
750
751# Function which runs gpart on a specified gpt partition
752run_gpart_gpt_part()
753{
754  DISK=$1
755
756  # Set the slice we will use later
757  slice="${1}p${3}"
758
759  # Set our sysctl so we can overwrite any geom using drives
760  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
761
762  # Get the number of the slice we are working on
763  slicenum="$3"
764
765  # Stop any journaling
766  stop_gjournal "${slice}"
767
768  # Make sure we have disabled swap on this drive
769  if [ -e "${slice}b" ]
770  then
771   swapoff ${slice}b >/dev/null 2>/dev/null
772   swapoff ${slice}b.eli >/dev/null 2>/dev/null
773  fi
774
775  # Modify partition type
776  echo_log "Running gpart modify on ${DISK}"
777  rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}"
778  sleep 2
779
780  wipe_metadata "${slice}"
781
782  sleep 4
783
784  # Init the MBR partition
785  rc_halt "gpart create -s BSD ${DISK}p${slicenum}"
786
787  # Stamp the bootloader
788  sleep 4
789  rc_halt "gpart bootcode -b /boot/boot ${DISK}p${slicenum}"
790
791  # Set the slice to the format we'll be using for gpart later
792  slice=`echo "${1}:${3}:gptslice" | sed 's|/|-|g'`
793
794  # Lets save our slice, so we know what to look for in the config file later on
795  if [ -z "$WORKINGSLICES" ]
796  then
797    WORKINGSLICES="${slice}"
798    export WORKINGSLICES
799  else
800    WORKINGSLICES="${WORKINGSLICES} ${slice}"
801    export WORKINGSLICES
802  fi
803};
804
805# Function which runs gpart on a specified s1-4 slice
806run_gpart_slice()
807{
808  DISK=$1
809  if [ -n "$2" ]
810  then
811    BMANAGER="$2"
812  fi
813
814  # Set the slice we will use later
815  slice="${1}s${3}"
816
817  # Set our sysctl so we can overwrite any geom using drives
818  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
819
820  # Get the number of the slice we are working on
821  slicenum="$3"
822
823  # Stop any journaling
824  stop_gjournal "${slice}"
825
826  # Make sure we have disabled swap on this drive
827  if [ -e "${slice}b" ]
828  then
829   swapoff ${slice}b >/dev/null 2>/dev/null
830   swapoff ${slice}b.eli >/dev/null 2>/dev/null
831  fi
832
833  # Modify partition type
834  echo_log "Running gpart modify on ${DISK}"
835  rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}"
836  sleep 2
837
838  wipe_metadata "${slice}"
839
840  sleep 1
841
842  if [ "${BMANAGER}" = "bsd" ]
843  then
844    echo_log "Stamping boot sector on ${DISK}"
845    rc_halt "gpart bootcode -b /boot/boot0 ${DISK}"
846  fi
847
848  # Set the slice to the format we'll be using for gpart later
849  slice=`echo "${1}:${3}:mbr" | sed 's|/|-|g'`
850
851  # Lets save our slice, so we know what to look for in the config file later on
852  if [ -z "$WORKINGSLICES" ]
853  then
854    WORKINGSLICES="${slice}"
855    export WORKINGSLICES
856  else
857    WORKINGSLICES="${WORKINGSLICES} ${slice}"
858    export WORKINGSLICES
859  fi
860};
861
862# Function which runs gpart and creates a new slice from free disk space
863run_gpart_free()
864{
865  DISK=$1
866  SLICENUM=$2
867  if [ -n "$3" ]
868  then
869    BMANAGER="$3"
870  fi
871
872  # Set our sysctl so we can overwrite any geom using drives
873  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
874
875  slice="${DISK}s${SLICENUM}"
876  slicenum="${SLICENUM}"
877
878  # Working on the first slice, make sure we have MBR setup
879  gpart show ${DISK} >/dev/null 2>/dev/null
880  if [ $? -ne 0 -a "$SLICENUM" = "1" ] ; then
881    echo_log "Initializing disk, no existing MBR setup"
882    rc_halt "gpart create -s mbr ${DISK}"
883  fi
884
885  # Install new partition setup
886  echo_log "Running gpart on ${DISK}"
887  rc_halt "gpart add -a 4k -t freebsd -i ${slicenum} ${DISK}"
888  sleep 2
889
890  wipe_metadata "${slice}"
891
892  sleep 1
893
894  if [ "${BMANAGER}" = "bsd" ]
895  then
896    echo_log "Stamping boot sector on ${DISK}"
897    rc_halt "gpart bootcode -b /boot/boot0 ${DISK}"
898  fi
899
900  slice=`echo "${DISK}:${SLICENUM}:mbr" | sed 's|/|-|g'`
901  # Lets save our slice, so we know what to look for in the config file later on
902  if [ -z "$WORKINGSLICES" ]
903  then
904    WORKINGSLICES="${slice}"
905    export WORKINGSLICES
906  else
907    WORKINGSLICES="${WORKINGSLICES} ${slice}"
908    export WORKINGSLICES
909  fi
910};
911