1296673Smav#!/bin/sh
2209513Simp#-
3209552Simp# Copyright (c) 2010 iXsystems, Inc.  All rights reserved.
4209513Simp#
5209513Simp# Redistribution and use in source and binary forms, with or without
6209513Simp# modification, are permitted provided that the following conditions
7209513Simp# are met:
8209513Simp# 1. Redistributions of source code must retain the above copyright
9209513Simp#    notice, this list of conditions and the following disclaimer.
10209513Simp# 2. Redistributions in binary form must reproduce the above copyright
11209513Simp#    notice, this list of conditions and the following disclaimer in the
12209513Simp#    documentation and/or other materials provided with the distribution.
13209513Simp#
14209513Simp# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15209513Simp# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16209513Simp# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17209513Simp# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18209513Simp# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19209513Simp# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20209513Simp# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21209513Simp# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22209513Simp# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23209513Simp# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24209513Simp# SUCH DAMAGE.
25209513Simp#
26209513Simp# $FreeBSD$
27209513Simp
28209513Simp# Functions related to disk operations using gpart
29209513Simp
30209513Simp# See if device is a full disk or partition/slice
31211730Simpis_disk()
32211730Simp{
33211730Simp  for _dsk in `sysctl -n kern.disks`
34211730Simp  do
35220059Sjpaetzel    [ "$_dsk" = "${1}" ] && return 0
36247735Sjpaetzel    [ "/dev/$_dsk" = "${1}" ] && return 0
37211730Simp  done
38209513Simp
39211730Simp  return 1
40209513Simp}
41209513Simp
42209513Simp# Get a MBR partitions sysid
43209513Simpget_partition_sysid_mbr()
44209513Simp{
45209513Simp  INPART="0"
46209513Simp  DISK="$1"
47209513Simp  PARTNUM=`echo ${2} | sed "s|${DISK}s||g"`
48209513Simp  fdisk ${DISK} >${TMPDIR}/disk-${DISK} 2>/dev/null
49209513Simp  while read i
50209513Simp  do
51220059Sjpaetzel    echo "$i" | grep -q "The data for partition" 2>/dev/null
52220059Sjpaetzel    if [ $? -eq 0 ] ; then
53209513Simp       INPART="0"
54209513Simp       PART="`echo ${i} | cut -d ' ' -f 5`"
55209513Simp       if [ "$PART" = "$PARTNUM" ] ; then
56209513Simp          INPART="1"
57209513Simp       fi
58209513Simp    fi
59209513Simp
60209513Simp    # In the partition section
61209513Simp    if [ "$INPART" = "1" ] ; then
62220059Sjpaetzel       echo "$i" | grep -q "^sysid" 2>/dev/null
63220059Sjpaetzel       if [ $? -eq 0 ] ; then
64209513Simp         SYSID="`echo ${i} | tr -s '\t' ' ' | cut -d ' ' -f 2`"
65209513Simp         break
66209513Simp       fi
67209513Simp
68209513Simp    fi
69209513Simp
70209513Simp  done < ${TMPDIR}/disk-${DISK}
71209513Simp  rm ${TMPDIR}/disk-${DISK}
72209513Simp
73220059Sjpaetzel  export VAL="${SYSID}"
74209513Simp};
75209513Simp
76209513Simp# Get the partitions MBR label
77209513Simpget_partition_label_mbr()
78209513Simp{
79209513Simp  INPART="0"
80209513Simp  DISK="$1"
81209513Simp  PARTNUM=`echo ${2} | sed "s|${DISK}s||g"`
82209513Simp  fdisk ${DISK} >${TMPDIR}/disk-${DISK} 2>/dev/null
83209513Simp  while read i
84209513Simp  do
85220059Sjpaetzel    echo "$i" | grep -q "The data for partition" 2>/dev/null
86220059Sjpaetzel    if [ $? -eq 0 ] ; then
87209513Simp       INPART="0"
88209513Simp       PART="`echo ${i} | cut -d ' ' -f 5`"
89209513Simp       if [ "$PART" = "$PARTNUM" ] ; then
90209513Simp          INPART="1"
91209513Simp       fi
92209513Simp    fi
93209513Simp
94209513Simp    # In the partition section
95209513Simp    if [ "$INPART" = "1" ] ; then
96220059Sjpaetzel       echo "$i" | grep -q "^sysid" 2>/dev/null
97220059Sjpaetzel       if [ $? -eq 0 ] ; then
98209513Simp         LABEL="`echo ${i} | tr -s '\t' ' ' | cut -d ',' -f 2-10`"
99209513Simp         break
100209513Simp       fi
101209513Simp
102209513Simp    fi
103209513Simp
104209513Simp  done < ${TMPDIR}/disk-${DISK}
105209513Simp  rm ${TMPDIR}/disk-${DISK}
106209513Simp
107220059Sjpaetzel  export VAL="${LABEL}"
108209513Simp};
109209513Simp
110209513Simp# Get a GPT partitions label
111209513Simpget_partition_label_gpt()
112209513Simp{
113209513Simp  DISK="${1}"
114209513Simp  PARTNUM=`echo ${2} | sed "s|${DISK}p||g"`
115209513Simp
116209513Simp  gpart show ${DISK} >${TMPDIR}/disk-${DISK}
117209513Simp  while read i
118209513Simp  do
119209513Simp     SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`"
120209513Simp     if [ "${SLICE}" = "${PARTNUM}" ] ; then
121209513Simp       LABEL="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 4`"
122209513Simp       break
123209513Simp     fi
124209513Simp  done <${TMPDIR}/disk-${DISK}
125209513Simp  rm ${TMPDIR}/disk-${DISK}
126209513Simp
127220059Sjpaetzel  export VAL="${LABEL}"
128209513Simp};
129209513Simp
130209513Simp# Get a partitions startblock
131209513Simpget_partition_startblock()
132209513Simp{
133209513Simp  DISK="${1}"
134209513Simp  PARTNUM=`echo ${2} | sed "s|${DISK}p||g" | sed "s|${DISK}s||g"`
135209513Simp
136209513Simp  gpart show ${DISK} >${TMPDIR}/disk-${DISK}
137209513Simp  while read i
138209513Simp  do
139209513Simp     SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`"
140209513Simp     if [ "$SLICE" = "${PARTNUM}" ] ; then
141209513Simp       SB="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 1`"
142209513Simp       break
143209513Simp     fi
144209513Simp  done <${TMPDIR}/disk-${DISK}
145209513Simp  rm ${TMPDIR}/disk-${DISK}
146209513Simp
147220059Sjpaetzel  export VAL="${SB}"
148209513Simp};
149209513Simp
150209513Simp# Get a partitions blocksize
151209513Simpget_partition_blocksize()
152209513Simp{
153209513Simp  DISK="${1}"
154209513Simp  PARTNUM=`echo ${2} | sed "s|${DISK}p||g" | sed "s|${DISK}s||g"`
155209513Simp
156209513Simp  gpart show ${DISK} >${TMPDIR}/disk-${DISK}
157209513Simp  while read i
158209513Simp  do
159209513Simp     SLICE="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 3`"
160209513Simp     if [ "$SLICE" = "${PARTNUM}" ] ; then
161209513Simp       BS="`echo ${i} | grep -v ${DISK} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 2`"
162209513Simp       break
163209513Simp     fi
164209513Simp  done <${TMPDIR}/disk-${DISK}
165209513Simp  rm ${TMPDIR}/disk-${DISK}
166209513Simp
167220059Sjpaetzel  export VAL="${BS}"
168209513Simp};
169209513Simp
170209513Simp# Function which returns the partitions on a target disk
171209513Simpget_disk_partitions()
172209513Simp{
173209513Simp  gpart show ${1} >/dev/null 2>/dev/null
174220059Sjpaetzel  if [ $? -ne 0 ] ; then
175220059Sjpaetzel    export VAL=""
176209513Simp    return
177209513Simp  fi
178209513Simp
179217164Sjpaetzel  type=`gpart show ${1} | awk '/^=>/ { printf("%s",$5); }'`
180209513Simp
181209513Simp  SLICES="`gpart show ${1} | grep -v ${1} | grep -v ' free ' |tr -s '\t' ' ' | cut -d ' ' -f 4 | sed '/^$/d'`"
182209513Simp  for i in ${SLICES}
183209513Simp  do
184209513Simp    case $type in
185211730Simp      MBR) name="${1}s${i}" ;;
186211730Simp      GPT) name="${1}p${i}";;
187211730Simp      *) name="${1}s${i}";;
188209513Simp    esac
189209513Simp    if [ -z "${RSLICES}" ]
190209513Simp    then
191209513Simp      RSLICES="${name}"
192209513Simp    else
193209513Simp      RSLICES="${RSLICES} ${name}"
194209513Simp    fi
195209513Simp  done
196209513Simp
197220059Sjpaetzel  export VAL="${RSLICES}"
198209513Simp};
199209513Simp
200209513Simp# Function which returns a target disks cylinders
201209513Simpget_disk_cyl()
202209513Simp{
203209513Simp  cyl=`diskinfo -v ${1} | grep "# Cylinders" | tr -s ' ' | cut -f 2`
204220059Sjpaetzel  export VAL="${cyl}"
205209513Simp};
206209513Simp
207209513Simp# Function which returns a target disks sectors
208209513Simpget_disk_sectors()
209209513Simp{
210209513Simp  sec=`diskinfo -v ${1} | grep "# Sectors" | tr -s ' ' | cut -f 2`
211220059Sjpaetzel  export VAL="${sec}"
212209513Simp};
213209513Simp
214209513Simp# Function which returns a target disks heads
215209513Simpget_disk_heads()
216209513Simp{
217209513Simp  head=`diskinfo -v ${1} | grep "# Heads" | tr -s ' ' | cut -f 2`
218220059Sjpaetzel  export VAL="${head}"
219209513Simp};
220209513Simp
221211730Simp# Function which returns a target disks mediasize in sectors
222211730Simpget_disk_mediasize()
223211730Simp{
224211730Simp  mediasize=`diskinfo -v ${1} | grep "# mediasize in sectors" | tr -s ' ' | cut -f 2`
225220059Sjpaetzel  export VAL="${mediasize}"
226211730Simp};
227211730Simp
228240165Sjpaetzel# Function which returns a target disks mediasize in megabytes
229240165Sjpaetzelget_disk_mediasize_mb()
230240165Sjpaetzel{
231240165Sjpaetzel  mediasize=`diskinfo -v ${1} | grep "# mediasize in bytes" | tr -s ' ' | cut -f 2`
232240165Sjpaetzel  mediasize=`expr $mediasize / 1024`
233240165Sjpaetzel  mediasize=`expr $mediasize / 1024`
234240165Sjpaetzel  export VAL="${mediasize}"
235240165Sjpaetzel};
236240165Sjpaetzel
237209513Simp# Function to delete all gparts before starting an install
238209513Simpdelete_all_gpart()
239209513Simp{
240209513Simp  echo_log "Deleting all gparts"
241217229Sjpaetzel  local DISK="$1"
242209513Simp
243209513Simp  # Check for any swaps to stop
244220909Sjpaetzel  for i in `swapctl -l | grep "$DISK" | awk '{print $1}'`
245209513Simp  do
246220909Sjpaetzel    swapoff ${i} >/dev/null 2>/dev/null
247209513Simp  done
248209513Simp
249209513Simp  # Delete the gparts now
250209513Simp  for i in `gpart show ${DISK} 2>/dev/null | tr -s ' ' | cut -d ' ' -f 4`
251209513Simp  do
252220909Sjpaetzel   if [ "/dev/${i}" != "${DISK}" -a "${i}" != "-" ] ; then
253209513Simp     rc_nohalt "gpart delete -i ${i} ${DISK}"
254209513Simp   fi
255209513Simp  done
256209513Simp
257217229Sjpaetzel  # Destroy the disk geom
258217229Sjpaetzel  rc_nohalt "gpart destroy ${DISK}"
259217229Sjpaetzel
260296655Smav  wipe_metadata "${DISK}"
261209513Simp};
262209513Simp
263209513Simp# Function to export all zpools before starting an install
264209513Simpstop_all_zfs()
265209513Simp{
266296656Smav  if [ ! -c /dev/zfs ]; then
267296656Smav    return;
268296656Smav  fi
269232898Sjpaetzel  local DISK="`echo ${1} | sed 's|/dev/||g'`"
270232898Sjpaetzel
271232898Sjpaetzel  # Export any zpools using this device so we can overwrite
272209513Simp  for i in `zpool list -H -o name`
273209513Simp  do
274232898Sjpaetzel    ztst=`zpool status ${i} | grep "ONLINE" | awk '{print $1}' | grep -q ${DISK}`
275232898Sjpaetzel    if [ "$ztst" = "$DISK" ] ; then
276232898Sjpaetzel      zpool export -f ${i}
277232898Sjpaetzel    fi
278209513Simp  done
279209513Simp};
280209513Simp
281209513Simp# Function which stops all gmirrors before doing any disk manipulation
282209513Simpstop_all_gmirror()
283209513Simp{
284296656Smav  if [ ! -d /dev/mirror ]; then
285296656Smav    return;
286296656Smav  fi
287220909Sjpaetzel  local DISK="`echo ${1} | sed 's|/dev/||g'`"
288209513Simp  GPROV="`gmirror list | grep ". Name: mirror/" | cut -d '/' -f 2`"
289209513Simp  for gprov in $GPROV 
290209513Simp  do
291220059Sjpaetzel    gmirror list | grep -q "Name: ${DISK}" 2>/dev/null
292220059Sjpaetzel    if [ $? -eq 0 ]
293209513Simp    then
294209513Simp      echo_log "Stopping mirror $gprov $DISK"
295209513Simp      rc_nohalt "gmirror remove $gprov $DISK"
296296655Smav      wipe_metadata "${DISK}"
297209513Simp    fi
298209513Simp  done
299209513Simp};
300209513Simp
301209513Simp# Make sure we don't have any geli providers active on this disk
302209513Simpstop_all_geli()
303209513Simp{
304220909Sjpaetzel  local _geld="`echo ${1} | sed 's|/dev/||g'`"
305209513Simp  cd /dev
306209513Simp
307209513Simp  for i in `ls ${_geld}*`
308209513Simp  do
309220059Sjpaetzel    echo $i | grep -q '.eli' 2>/dev/null
310220059Sjpaetzel    if [ $? -eq 0 ]
311209513Simp    then
312209513Simp      echo_log "Detaching GELI on ${i}"
313209513Simp      rc_halt "geli detach ${i}"
314209513Simp    fi
315209513Simp  done
316209513Simp
317209513Simp};
318209513Simp
319209513Simp# Function which reads in the disk slice config, and performs it
320209513Simpsetup_disk_slice()
321209513Simp{
322209513Simp
323209513Simp  # Cleanup any slice / mirror dirs
324209513Simp  rm -rf ${SLICECFGDIR} >/dev/null 2>/dev/null
325209513Simp  mkdir ${SLICECFGDIR}
326209513Simp  rm -rf ${MIRRORCFGDIR} >/dev/null 2>/dev/null
327209513Simp  mkdir ${MIRRORCFGDIR}
328209513Simp
329220909Sjpaetzel  # Start with disk0 and gm0
330209513Simp  disknum="0"
331220909Sjpaetzel  gmnum="0"
332209513Simp
333209513Simp  # We are ready to start setting up the disks, lets read the config and do the actions
334209513Simp  while read line
335209513Simp  do
336220059Sjpaetzel    echo $line | grep -q "^disk${disknum}=" 2>/dev/null
337220059Sjpaetzel    if [ $? -eq 0 ]
338212337Simp    then
339209513Simp
340212337Simp      # Found a disk= entry, lets get the disk we are working on
341212337Simp      get_value_from_string "${line}"
342212337Simp      strip_white_space "$VAL"
343212337Simp      DISK="$VAL"
344220909Sjpaetzel
345220909Sjpaetzel      echo "${DISK}" | grep -q '^/dev/'
346220909Sjpaetzel      if [ $? -ne 0 ] ; then DISK="/dev/$DISK" ; fi
347209513Simp     
348212337Simp      # Before we go further, lets confirm this disk really exists
349220909Sjpaetzel      if [ ! -e "${DISK}" ] ; then
350212337Simp        exit_err "ERROR: The disk ${DISK} does not exist!"
351212337Simp      fi
352209513Simp
353212337Simp      # Make sure we stop any gmirrors on this disk
354212337Simp      stop_all_gmirror ${DISK}
355209513Simp
356212337Simp      # Make sure we stop any geli stuff on this disk
357212337Simp      stop_all_geli ${DISK}
358209513Simp
359212337Simp      # Make sure we don't have any zpools loaded
360232898Sjpaetzel      stop_all_zfs ${DISK}
361209513Simp
362220909Sjpaetzel     fi
363209513Simp
364212337Simp    # Lets look if this device will be mirrored on another disk
365220059Sjpaetzel    echo $line | grep -q "^mirror=" 2>/dev/null
366220059Sjpaetzel    if [ $? -eq 0 ]
367212337Simp    then
368209513Simp
369212337Simp      # Found a disk= entry, lets get the disk we are working on
370212337Simp      get_value_from_string "${line}"
371212337Simp      strip_white_space "$VAL"
372212337Simp      MIRRORDISK="$VAL"
373220909Sjpaetzel      echo "${MIRRORDISK}" | grep -q '^/dev/'
374220909Sjpaetzel      if [ $? -ne 0 ] ; then MIRRORDISK="/dev/$MIRRORDISK" ; fi
375209513Simp     
376212337Simp      # Before we go further, lets confirm this disk really exists
377220909Sjpaetzel      if [ ! -e "${MIRRORDISK}" ]
378212337Simp      then
379212337Simp        exit_err "ERROR: The mirror disk ${MIRRORDISK} does not exist!"
380212337Simp      fi
381232898Sjpaetzel
382232898Sjpaetzel      # Make sure we stop any gmirrors on this mirror disk
383232898Sjpaetzel      stop_all_gmirror ${MIRRORDISK}
384232898Sjpaetzel
385232898Sjpaetzel      # Make sure we stop any geli stuff on this mirror disk
386232898Sjpaetzel      stop_all_geli ${MIRRORDISK}
387232898Sjpaetzel
388232898Sjpaetzel      # Make sure we don't have any zpools mirror loaded
389232898Sjpaetzel      stop_all_zfs ${MIRRORDISK}
390232898Sjpaetzel
391212337Simp    fi
392209513Simp
393212337Simp    # Lets see if we have been given a mirror balance choice
394220059Sjpaetzel    echo $line | grep -q "^mirrorbal=" 2>/dev/null
395220059Sjpaetzel    if [ $? -eq 0 ]
396212337Simp    then
397209513Simp
398212337Simp      # Found a disk= entry, lets get the disk we are working on
399212337Simp      get_value_from_string "${line}"
400212337Simp      strip_white_space "$VAL"
401212337Simp      MIRRORBAL="$VAL"
402212337Simp    fi
403209513Simp
404220059Sjpaetzel    echo $line | grep -q "^partition=" 2>/dev/null
405220059Sjpaetzel    if [ $? -eq 0 ]
406212337Simp    then
407212337Simp      # Found a partition= entry, lets read / set it 
408212337Simp      get_value_from_string "${line}"
409212337Simp      strip_white_space "$VAL"
410212337Simp      PTYPE=`echo $VAL|tr A-Z a-z`
411209513Simp
412212337Simp      # We are using free space, figure out the slice number
413212337Simp      if [ "${PTYPE}" = "free" ]
414212337Simp      then
415212337Simp        # Lets figure out what number this slice will be
416212337Simp        LASTSLICE="`gpart show ${DISK} \
417213650Simp          | grep -v ${DISK} \
418213650Simp          | grep -v ' free' \
419213650Simp          | tr -s '\t' ' ' \
420213650Simp          | cut -d ' ' -f 4 \
421213650Simp          | sed '/^$/d' \
422213650Simp          | tail -n 1`"
423209513Simp
424212337Simp        if [ -z "${LASTSLICE}" ]
425212337Simp        then
426212337Simp          LASTSLICE="1"
427212337Simp        else
428220059Sjpaetzel            LASTSLICE=$((LASTSLICE+1))
429212337Simp        fi
430209513Simp
431212337Simp        if [ $LASTSLICE -gt 4 ]
432212337Simp        then
433228990Suqs          exit_err "ERROR: BSD only supports primary partitions, and there are none available on $DISK"
434212337Simp        fi
435209513Simp
436212337Simp      fi
437212337Simp    fi
438211490Simp
439212337Simp    # Check if we have an image file defined
440220059Sjpaetzel    echo $line | grep -q "^image=" 2>/dev/null
441220161Sjpaetzel    if [ $? -eq 0 ] ; then
442212337Simp      # Found an image= entry, lets read / set it
443212337Simp      get_value_from_string "${line}"
444212337Simp      strip_white_space "$VAL"
445212337Simp      IMAGE="$VAL"
446212337Simp      if [ ! -f "$IMAGE" ] ; then
447212337Simp        exit_err "$IMAGE file does not exist"
448212337Simp      fi
449212337Simp    fi
450209513Simp
451212337Simp    # Check if we have a partscheme specified
452220059Sjpaetzel    echo $line | grep -q "^partscheme=" 2>/dev/null
453220059Sjpaetzel    if [ $? -eq 0 ] ; then
454212337Simp      # Found a partscheme= entry, lets read / set it 
455212337Simp      get_value_from_string "${line}"
456212337Simp      strip_white_space "$VAL"
457212337Simp      PSCHEME="$VAL"
458212337Simp      if [ "$PSCHEME" != "GPT" -a "$PSCHEME" != "MBR" ] ; then
459212337Simp        exit_err "Unknown partition scheme: $PSCHEME" 
460212337Simp      fi
461212337Simp    fi
462211730Simp
463220059Sjpaetzel    echo $line | grep -q "^bootManager=" 2>/dev/null
464220059Sjpaetzel    if [ $? -eq 0 ]
465212337Simp    then
466212337Simp      # Found a bootManager= entry, lets read /set it
467212337Simp      get_value_from_string "${line}"
468212337Simp      strip_white_space "$VAL"
469212337Simp      BMANAGER="$VAL"
470212337Simp    fi
471211730Simp
472220059Sjpaetzel    echo $line | grep -q "^commitDiskPart" 2>/dev/null
473220059Sjpaetzel    if [ $? -eq 0 ]
474212337Simp    then
475212337Simp      # Found our flag to commit this disk setup / lets do sanity check and do it
476212337Simp      if [ ! -z "${DISK}" -a ! -z "${PTYPE}" ]
477212337Simp      then
478235006Sjpaetzel	# Make sure we are only installing ppc to full disk
479235006Sjpaetzel	if [ `uname -m` = "powerpc" -o `uname -m` = "powerpc64" ]; then
480235006Sjpaetzel	  if [ "$PTYPE" != "all" ] ; then
481235006Sjpaetzel	    exit_err "powerpc can only be installed to a full disk"
482235006Sjpaetzel	  fi
483235006Sjpaetzel	fi
484220909Sjpaetzel
485212337Simp        case ${PTYPE} in
486212337Simp          all)
487220909Sjpaetzel            # If we have a gmirror, lets set it up
488220909Sjpaetzel            if [ -n "$MIRRORDISK" ]; then
489220909Sjpaetzel              # Default to round-robin if the user didn't specify
490220909Sjpaetzel              if [ -z "$MIRRORBAL" ]; then MIRRORBAL="round-robin" ; fi
491220909Sjpaetzel
492227118Sjpaetzel	      _mFile=`echo $DISK | sed 's|/|%|g'`
493227118Sjpaetzel              echo "$MIRRORDISK:$MIRRORBAL:gm${gmnum}" >${MIRRORCFGDIR}/$_mFile
494220909Sjpaetzel	      init_gmirror "$gmnum" "$MIRRORBAL" "$DISK" "$MIRRORDISK"
495220909Sjpaetzel
496220909Sjpaetzel	      # Reset DISK to the gmirror device
497220909Sjpaetzel	      DISK="/dev/mirror/gm${gmnum}"
498220909Sjpaetzel              gmnum=$((gmknum+1))
499220909Sjpaetzel            fi
500220909Sjpaetzel
501212337Simp            if [ "$PSCHEME" = "MBR" -o -z "$PSCHEME" ] ; then
502212337Simp              PSCHEME="MBR"
503212337Simp              tmpSLICE="${DISK}s1"  
504213650Simp            else
505212337Simp              tmpSLICE="${DISK}p1"  
506212337Simp            fi
507211730Simp
508235006Sjpaetzel	    if [ `uname -m` = "powerpc" -o `uname -m` = "powerpc64" ]
509235006Sjpaetzel	    then
510235006Sjpaetzel              PSCHEME="APM"
511235006Sjpaetzel              tmpSLICE="${DISK}s1"  
512235006Sjpaetzel	    fi
513235006Sjpaetzel
514212337Simp            run_gpart_full "${DISK}" "${BMANAGER}" "${PSCHEME}"
515212337Simp            ;;
516211730Simp
517212337Simp          s1|s2|s3|s4)
518212337Simp            tmpSLICE="${DISK}${PTYPE}" 
519212337Simp            # Get the number of the slice we are working on
520212337Simp            s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" 
521212337Simp            run_gpart_slice "${DISK}" "${BMANAGER}" "${s}"
522212337Simp            ;;
523209513Simp
524227368Sjpaetzel          p1|p2|p3|p4|p5|p6|p7|p8|p9|p10|p11|p12|p13|p14|p15|p16|p17|p18|p19|p20)
525227368Sjpaetzel            tmpSLICE="${DISK}${PTYPE}" 
526227368Sjpaetzel            # Get the number of the gpt partition we are working on
527227368Sjpaetzel            s="`echo ${PTYPE} | awk '{print substr($0,length,1)}'`" 
528227368Sjpaetzel            run_gpart_gpt_part "${DISK}" "${BMANAGER}" "${s}"
529227368Sjpaetzel            ;;
530227368Sjpaetzel
531212337Simp          free)
532212337Simp            tmpSLICE="${DISK}s${LASTSLICE}"
533212337Simp            run_gpart_free "${DISK}" "${LASTSLICE}" "${BMANAGER}"
534212337Simp            ;;
535209513Simp
536212337Simp          image)
537213650Simp            if [ -z "${IMAGE}" ]
538212337Simp            then
539213650Simp              exit_err "ERROR: partition type image specified with no image!"
540212337Simp            fi 
541212337Simp            ;;
542209513Simp
543212337Simp          *) exit_err "ERROR: Unknown PTYPE: $PTYPE" ;;
544212337Simp        esac
545213650Simp        
546212337Simp
547213650Simp		if [ -n "${IMAGE}" ]
548213650Simp		then 
549213650Simp          local DEST
550213650Simp          
551213650Simp		  if [ -n "${tmpSLICE}" ]
552213650Simp          then
553213650Simp			DEST="${tmpSLICE}"
554213650Simp          else 
555213650Simp			DEST="${DISK}"
556213650Simp          fi 
557213650Simp
558213650Simp          write_image "${IMAGE}" "${DEST}"
559213650Simp          check_disk_layout "${DEST}"
560213650Simp		fi
561213650Simp
562212337Simp        # Now save which disk<num> this is, so we can parse it later during slice partition setup
563213650Simp        if [ -z "${IMAGE}" ]
564212337Simp        then
565220909Sjpaetzel	  _sFile=`echo $tmpSLICE | sed 's|/|-|g'`
566220909Sjpaetzel          echo "disk${disknum}" >${SLICECFGDIR}/$_sFile
567212337Simp        fi
568212337Simp
569212337Simp        # Increment our disk counter to look for next disk and unset
570212337Simp        unset BMANAGER PTYPE DISK MIRRORDISK MIRRORBAL PSCHEME IMAGE
571220059Sjpaetzel        disknum=$((disknum+1))
572212337Simp      else
573212337Simp        exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" 
574212337Simp      fi
575212337Simp    fi
576212337Simp
577209513Simp  done <${CFGF}
578209513Simp
579209513Simp};
580209513Simp
581220909Sjpaetzel
582220909Sjpaetzel# Init the gmirror device
583220909Sjpaetzelinit_gmirror()
584220909Sjpaetzel{
585220909Sjpaetzel    local _mNum=$1
586220909Sjpaetzel    local _mBal=$2
587220909Sjpaetzel    local _mDisk=$3
588220909Sjpaetzel
589220909Sjpaetzel    # Create this mirror device
590225657Sjpaetzel    rc_halt "gmirror label -vb ${_mBal} gm${_mNum} ${_mDisk}"
591220909Sjpaetzel
592220909Sjpaetzel    sleep 3
593220909Sjpaetzel
594220909Sjpaetzel}
595220909Sjpaetzel
596209513Simp# Stop all gjournals on disk / slice
597211730Simpstop_gjournal()
598211730Simp{
599220909Sjpaetzel  _gdsk="`echo $1 | sed 's|/dev/||g'`"
600209513Simp  # Check if we need to shutdown any journals on this drive
601209513Simp  ls /dev/${_gdsk}*.journal >/dev/null 2>/dev/null
602220059Sjpaetzel  if [ $? -eq 0 ]
603209513Simp  then
604209513Simp    cd /dev
605209513Simp    for i in `ls ${_gdsk}*.journal`
606209513Simp    do
607209513Simp      rawjournal="`echo ${i} | cut -d '.' -f 1`"
608209513Simp      gjournal stop -f ${rawjournal} >>${LOGOUT} 2>>${LOGOUT}
609209513Simp      gjournal clear ${rawjournal} >>${LOGOUT} 2>>${LOGOUT}
610209513Simp    done
611209513Simp  fi
612209513Simp} ;
613209513Simp
614217229Sjpaetzel
615296655Smav# Function to wipe the potential metadata from a disk
616296655Smavwipe_metadata()
617217229Sjpaetzel{
618296655Smav  echo_log "Wiping possible metadata on ${1}"
619296655Smav  local SIZE="`diskinfo ${1} | awk '{print int($3/(1024*1024)) }'`"
620296655Smav  if [ "$SIZE" -gt "5" ]  ; then
621296655Smav    rc_halt "dd if=/dev/zero of=${1} bs=1m count=1"
622296776Smav    rc_nohalt "dd if=/dev/zero of=${1} bs=1m oseek=$((SIZE-4))"
623296655Smav  else
624296776Smav    rc_nohalt "dd if=/dev/zero of=${1} bs=128k"
625296655Smav  fi
626217229Sjpaetzel} ;
627217229Sjpaetzel
628235006Sjpaetzel# Function which runs gpart and creates a single large APM partition scheme
629235006Sjpaetzelinit_apm_full_disk()
630235006Sjpaetzel{
631235006Sjpaetzel  _intDISK=$1
632235006Sjpaetzel 
633235006Sjpaetzel  # Set our sysctl so we can overwrite any geom using drives
634235006Sjpaetzel  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
635217229Sjpaetzel
636235006Sjpaetzel  # Stop any journaling
637235006Sjpaetzel  stop_gjournal "${_intDISK}"
638235006Sjpaetzel
639235006Sjpaetzel  # Remove any existing partitions
640235006Sjpaetzel  delete_all_gpart "${_intDISK}"
641235006Sjpaetzel
642235006Sjpaetzel  sleep 2
643235006Sjpaetzel
644235006Sjpaetzel  echo_log "Running gpart on ${_intDISK}"
645235006Sjpaetzel  rc_halt "gpart create -s APM ${_intDISK}"
646235006Sjpaetzel  rc_halt "gpart add -s 800k -t freebsd-boot ${_intDISK}"
647235006Sjpaetzel  
648235006Sjpaetzel  echo_log "Stamping boot sector on ${_intDISK}"
649235006Sjpaetzel  rc_halt "gpart bootcode -p /boot/boot1.hfs -i 1 ${_intDISK}"
650235006Sjpaetzel
651235006Sjpaetzel}
652235006Sjpaetzel
653211490Simp# Function which runs gpart and creates a single large GPT partition scheme
654209513Simpinit_gpt_full_disk()
655209513Simp{
656209513Simp  _intDISK=$1
657209513Simp 
658209513Simp  # Set our sysctl so we can overwrite any geom using drives
659209513Simp  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
660209513Simp
661209513Simp  # Stop any journaling
662209513Simp  stop_gjournal "${_intDISK}"
663209513Simp
664209513Simp  # Remove any existing partitions
665209513Simp  delete_all_gpart "${_intDISK}"
666209513Simp
667209513Simp  sleep 2
668209513Simp
669209513Simp  echo_log "Running gpart on ${_intDISK}"
670209513Simp  rc_halt "gpart create -s GPT ${_intDISK}"
671220057Sjpaetzel  rc_halt "gpart add -b 34 -s 128 -t freebsd-boot ${_intDISK}"
672209513Simp  
673209513Simp  echo_log "Stamping boot sector on ${_intDISK}"
674209513Simp  rc_halt "gpart bootcode -b /boot/pmbr ${_intDISK}"
675209513Simp
676209513Simp}
677209513Simp
678211490Simp# Function which runs gpart and creates a single large MBR partition scheme
679211490Simpinit_mbr_full_disk()
680211490Simp{
681211490Simp  _intDISK=$1
682211490Simp  _intBOOT=$2
683211490Simp 
684217229Sjpaetzel  startblock="2016"
685211490Simp
686211490Simp  # Set our sysctl so we can overwrite any geom using drives
687211490Simp  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
688211490Simp
689211490Simp  # Stop any journaling
690211490Simp  stop_gjournal "${_intDISK}"
691211490Simp
692211490Simp  # Remove any existing partitions
693211490Simp  delete_all_gpart "${_intDISK}"
694211490Simp
695211490Simp  sleep 2
696211490Simp
697211490Simp  echo_log "Running gpart on ${_intDISK}"
698232889Sjpaetzel  rc_halt "gpart create -s mbr -f active ${_intDISK}"
699211490Simp
700211490Simp  # Install new partition setup
701211490Simp  echo_log "Running gpart add on ${_intDISK}"
702232901Sjpaetzel  rc_halt "gpart add -a 4k -t freebsd -i 1 ${_intDISK}"
703211490Simp  sleep 2
704211490Simp  
705296655Smav  wipe_metadata "${_intDISK}s1"
706211490Simp  
707235452Sjpaetzel  # Make the partition active
708235452Sjpaetzel  rc_halt "gpart set -a active -i 1 ${_intDISK}"
709235452Sjpaetzel
710211490Simp  if [ "$_intBOOT" = "bsd" ] ; then
711215078Simp    echo_log "Stamping boot0 on ${_intDISK}"
712211490Simp    rc_halt "gpart bootcode -b /boot/boot0 ${_intDISK}"
713215078Simp  else
714215078Simp    echo_log "Stamping boot1 on ${_intDISK}"
715215078Simp    rc_halt "gpart bootcode -b /boot/boot1 ${_intDISK}"
716211490Simp  fi
717211490Simp
718211490Simp}
719211490Simp
720209513Simp# Function which runs gpart and creates a single large slice
721209513Simprun_gpart_full()
722209513Simp{
723209513Simp  DISK=$1
724211490Simp  BOOT=$2
725211490Simp  SCHEME=$3
726209513Simp
727235006Sjpaetzel  if [ "$SCHEME" = "APM" ] ; then
728235006Sjpaetzel    init_apm_full_disk "$DISK"
729235006Sjpaetzel    slice=`echo "${DISK}:1:apm" | sed 's|/|-|g'`
730235006Sjpaetzel  elif [ "$SCHEME" = "MBR" ] ; then
731211490Simp    init_mbr_full_disk "$DISK" "$BOOT"
732220909Sjpaetzel    slice=`echo "${DISK}:1:mbr" | sed 's|/|-|g'`
733211490Simp  else
734211490Simp    init_gpt_full_disk "$DISK"
735220909Sjpaetzel    slice=`echo "${DISK}:1:gpt" | sed 's|/|-|g'`
736211490Simp  fi
737209513Simp
738209513Simp  # Lets save our slice, so we know what to look for in the config file later on
739209513Simp  if [ -z "$WORKINGSLICES" ]
740209513Simp  then
741209513Simp    WORKINGSLICES="${slice}"
742209513Simp    export WORKINGSLICES
743209513Simp  else
744209513Simp    WORKINGSLICES="${WORKINGSLICES} ${slice}"
745209513Simp    export WORKINGSLICES
746209513Simp  fi
747209513Simp};
748209513Simp
749227368Sjpaetzel# Function which runs gpart on a specified gpt partition
750227368Sjpaetzelrun_gpart_gpt_part()
751227368Sjpaetzel{
752227368Sjpaetzel  DISK=$1
753227368Sjpaetzel
754227368Sjpaetzel  # Set the slice we will use later
755227368Sjpaetzel  slice="${1}p${3}"
756227368Sjpaetzel 
757227368Sjpaetzel  # Set our sysctl so we can overwrite any geom using drives
758227368Sjpaetzel  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
759227368Sjpaetzel
760227368Sjpaetzel  # Get the number of the slice we are working on
761227368Sjpaetzel  slicenum="$3"
762227368Sjpaetzel
763227368Sjpaetzel  # Stop any journaling
764227368Sjpaetzel  stop_gjournal "${slice}"
765227368Sjpaetzel
766227368Sjpaetzel  # Make sure we have disabled swap on this drive
767227368Sjpaetzel  if [ -e "${slice}b" ]
768227368Sjpaetzel  then
769227368Sjpaetzel   swapoff ${slice}b >/dev/null 2>/dev/null
770227368Sjpaetzel   swapoff ${slice}b.eli >/dev/null 2>/dev/null
771227368Sjpaetzel  fi
772227368Sjpaetzel
773227368Sjpaetzel  # Modify partition type
774227368Sjpaetzel  echo_log "Running gpart modify on ${DISK}"
775227368Sjpaetzel  rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}"
776227368Sjpaetzel  sleep 2
777227368Sjpaetzel
778296655Smav  wipe_metadata "${slice}"
779227368Sjpaetzel
780227368Sjpaetzel  sleep 4
781227368Sjpaetzel
782227368Sjpaetzel  # Init the MBR partition
783227368Sjpaetzel  rc_halt "gpart create -s BSD ${DISK}p${slicenum}"
784227368Sjpaetzel
785235008Sjpaetzel  # Stamp the bootloader
786235008Sjpaetzel  sleep 4
787235008Sjpaetzel  rc_halt "gpart bootcode -b /boot/boot ${DISK}p${slicenum}"
788235008Sjpaetzel
789227368Sjpaetzel  # Set the slice to the format we'll be using for gpart later
790227368Sjpaetzel  slice=`echo "${1}:${3}:gptslice" | sed 's|/|-|g'`
791227368Sjpaetzel
792227368Sjpaetzel  # Lets save our slice, so we know what to look for in the config file later on
793227368Sjpaetzel  if [ -z "$WORKINGSLICES" ]
794227368Sjpaetzel  then
795227368Sjpaetzel    WORKINGSLICES="${slice}"
796227368Sjpaetzel    export WORKINGSLICES
797227368Sjpaetzel  else
798227368Sjpaetzel    WORKINGSLICES="${WORKINGSLICES} ${slice}"
799227368Sjpaetzel    export WORKINGSLICES
800227368Sjpaetzel  fi
801227368Sjpaetzel};
802227368Sjpaetzel
803209513Simp# Function which runs gpart on a specified s1-4 slice
804209513Simprun_gpart_slice()
805209513Simp{
806209513Simp  DISK=$1
807220059Sjpaetzel  if [ -n "$2" ]
808209513Simp  then
809209513Simp    BMANAGER="$2"
810209513Simp  fi
811209513Simp
812209513Simp  # Set the slice we will use later
813209513Simp  slice="${1}s${3}"
814209513Simp 
815209513Simp  # Set our sysctl so we can overwrite any geom using drives
816209513Simp  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
817209513Simp
818209513Simp  # Get the number of the slice we are working on
819209513Simp  slicenum="$3"
820209513Simp
821209513Simp  # Stop any journaling
822209513Simp  stop_gjournal "${slice}"
823209513Simp
824209513Simp  # Make sure we have disabled swap on this drive
825209513Simp  if [ -e "${slice}b" ]
826209513Simp  then
827209513Simp   swapoff ${slice}b >/dev/null 2>/dev/null
828209513Simp   swapoff ${slice}b.eli >/dev/null 2>/dev/null
829209513Simp  fi
830209513Simp
831209513Simp  # Modify partition type
832209513Simp  echo_log "Running gpart modify on ${DISK}"
833209513Simp  rc_halt "gpart modify -t freebsd -i ${slicenum} ${DISK}"
834209513Simp  sleep 2
835209513Simp
836296655Smav  wipe_metadata "${slice}"
837209513Simp
838209513Simp  sleep 1
839209513Simp
840209513Simp  if [ "${BMANAGER}" = "bsd" ]
841209513Simp  then
842209513Simp    echo_log "Stamping boot sector on ${DISK}"
843209513Simp    rc_halt "gpart bootcode -b /boot/boot0 ${DISK}"
844209513Simp  fi
845209513Simp
846209513Simp  # Set the slice to the format we'll be using for gpart later
847220909Sjpaetzel  slice=`echo "${1}:${3}:mbr" | sed 's|/|-|g'`
848209513Simp
849209513Simp  # Lets save our slice, so we know what to look for in the config file later on
850209513Simp  if [ -z "$WORKINGSLICES" ]
851209513Simp  then
852209513Simp    WORKINGSLICES="${slice}"
853209513Simp    export WORKINGSLICES
854209513Simp  else
855209513Simp    WORKINGSLICES="${WORKINGSLICES} ${slice}"
856209513Simp    export WORKINGSLICES
857209513Simp  fi
858209513Simp};
859209513Simp
860209513Simp# Function which runs gpart and creates a new slice from free disk space
861209513Simprun_gpart_free()
862209513Simp{
863209513Simp  DISK=$1
864209513Simp  SLICENUM=$2
865220059Sjpaetzel  if [ -n "$3" ]
866209513Simp  then
867209513Simp    BMANAGER="$3"
868209513Simp  fi
869209513Simp
870209513Simp  # Set our sysctl so we can overwrite any geom using drives
871209513Simp  sysctl kern.geom.debugflags=16 >>${LOGOUT} 2>>${LOGOUT}
872209513Simp
873209513Simp  slice="${DISK}s${SLICENUM}"
874209513Simp  slicenum="${SLICENUM}" 
875209513Simp
876209513Simp  # Working on the first slice, make sure we have MBR setup
877209513Simp  gpart show ${DISK} >/dev/null 2>/dev/null
878220059Sjpaetzel  if [ $? -ne 0 -a "$SLICENUM" = "1" ] ; then
879209513Simp    echo_log "Initializing disk, no existing MBR setup"
880209513Simp    rc_halt "gpart create -s mbr ${DISK}"
881209513Simp  fi
882209513Simp
883209513Simp  # Install new partition setup
884209513Simp  echo_log "Running gpart on ${DISK}"
885232901Sjpaetzel  rc_halt "gpart add -a 4k -t freebsd -i ${slicenum} ${DISK}"
886209513Simp  sleep 2
887209513Simp
888296655Smav  wipe_metadata "${slice}"
889296655Smav
890209513Simp  sleep 1
891209513Simp
892209513Simp  if [ "${BMANAGER}" = "bsd" ]
893209513Simp  then
894209513Simp    echo_log "Stamping boot sector on ${DISK}"
895209513Simp    rc_halt "gpart bootcode -b /boot/boot0 ${DISK}"
896209513Simp  fi
897209513Simp
898220909Sjpaetzel  slice=`echo "${DISK}:${SLICENUM}:mbr" | sed 's|/|-|g'`
899209513Simp  # Lets save our slice, so we know what to look for in the config file later on
900209513Simp  if [ -z "$WORKINGSLICES" ]
901209513Simp  then
902209513Simp    WORKINGSLICES="${slice}"
903209513Simp    export WORKINGSLICES
904209513Simp  else
905209513Simp    WORKINGSLICES="${WORKINGSLICES} ${slice}"
906209513Simp    export WORKINGSLICES
907209513Simp  fi
908209513Simp};
909