1209513Simp#!/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: releng/11.0/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh 247735 2013-03-03 23:07:27Z jpaetzel $
27209513Simp
28209513Simp# Functions related to disk operations using bsdlabel
29209513Simp
30209513Simp# Check if we are are provided a geli password on the nextline of the config
31209513Simpcheck_for_enc_pass()
32209513Simp{
33209513Simp  CURLINE="${1}"
34209513Simp 
35209513Simp  get_next_cfg_line "${CFGF}" "${CURLINE}" 
36220059Sjpaetzel  echo ${VAL} | grep -q "^encpass=" 2>/dev/null
37220059Sjpaetzel  if [ $? -eq 0 ] ; then
38209513Simp    # Found a password, return it
39209513Simp    get_value_from_string "${VAL}"
40209513Simp    return
41209513Simp  fi
42209513Simp
43220059Sjpaetzel  export VAL=""
44209513Simp  return
45209513Simp};
46209513Simp
47209513Simp# On check on the disk-label line if we have any extra vars for this device
48209513Simpget_fs_line_xvars()
49209513Simp{
50209513Simp  ACTIVEDEV="${1}"
51209513Simp  LINE="${2}"
52209513Simp
53234990Sjpaetzel  echo $LINE | cut -d ' ' -f 4 | grep -q '(' 2>/dev/null
54234990Sjpaetzel  if [ $? -ne 0 ] ; then return ; fi
55234990Sjpaetzel
56234990Sjpaetzel  # See if we are looking for ZFS specific options
57234990Sjpaetzel  echo $LINE | grep -q '^ZFS' 2>/dev/null
58220059Sjpaetzel  if [ $? -eq 0 ] ; then
59234990Sjpaetzel    ZTYPE="NONE"
60234990Sjpaetzel    ZFSVARS="`echo $LINE | cut -d ' ' -f 4-20 |cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`"
61209513Simp
62234990Sjpaetzel    echo $ZFSVARS | grep -qE "^(disk|file|mirror|raidz(1|2|3)?|spare|log|cache):" 2>/dev/null
63220059Sjpaetzel    if [ $? -eq 0 ] ; then
64211488Simp       ZTYPE=`echo $ZFSVARS | cut -f1 -d:`
65247735Sjpaetzel       tmpVars=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"`
66247735Sjpaetzel       ZFSVARS=""
67247735Sjpaetzel       # make sure we have a '/dev' in front of the extra devices
68247735Sjpaetzel       for i in $tmpVars
69247735Sjpaetzel       do
70247735Sjpaetzel          echo $i | grep -q '/dev/'
71247735Sjpaetzel          if [ $? -ne 0 ] ; then
72247735Sjpaetzel             ZFSVARS="$ZFSVARS /dev/${i}"
73247735Sjpaetzel          else
74247735Sjpaetzel             ZFSVARS="$ZFSVARS $i"
75247735Sjpaetzel          fi
76247735Sjpaetzel       done
77234990Sjpaetzel    fi
78209513Simp
79234990Sjpaetzel    # Return the ZFS options
80234990Sjpaetzel    if [ "${ZTYPE}" = "NONE" ] ; then
81234990Sjpaetzel      VAR="${ACTIVEDEV} ${ZFSVARS}"
82234990Sjpaetzel    else
83234990Sjpaetzel      VAR="${ZTYPE} ${ACTIVEDEV} ${ZFSVARS}"
84225657Sjpaetzel    fi
85234990Sjpaetzel    export VAR
86234990Sjpaetzel    return
87234990Sjpaetzel  fi # End of ZFS block
88225657Sjpaetzel
89234990Sjpaetzel  # See if we are looking for UFS specific newfs options
90234990Sjpaetzel  echo $LINE | grep -q '^UFS' 2>/dev/null
91234990Sjpaetzel  if [ $? -eq 0 ] ; then
92234990Sjpaetzel    FSVARS="`echo $LINE | cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`"
93234990Sjpaetzel    VAR="${FSVARS}"
94234990Sjpaetzel    export VAR
95234990Sjpaetzel    return
96234990Sjpaetzel  fi
97209513Simp
98209513Simp  # If we got here, set VAR to empty and export
99220059Sjpaetzel  export VAR=""
100209513Simp  return
101209513Simp};
102209513Simp
103209513Simp# Init each zfs mirror disk with a boot sector so we can failover
104211730Simpsetup_zfs_mirror_parts()
105211730Simp{
106211730Simp  _nZFS=""
107209513Simp
108234990Sjpaetzel  ZTYPE="`echo ${1} | awk '{print $1}'`"
109234990Sjpaetzel
110211730Simp  # Using mirroring, setup boot partitions on each disk
111234990Sjpaetzel  _mirrline="`echo ${1} | sed 's|mirror ||g' | sed 's|raidz1 ||g' | sed 's|raidz2 ||g' | sed 's|raidz3 ||g' | sed 's|raidz ||g'`"
112211730Simp  for _zvars in $_mirrline
113211730Simp  do
114211730Simp    echo "Looping through _zvars: $_zvars" >>${LOGOUT}
115220059Sjpaetzel    echo "$_zvars" | grep -q "${2}" 2>/dev/null
116220059Sjpaetzel    if [ $? -eq 0 ] ; then continue ; fi
117211730Simp    if [ -z "$_zvars" ] ; then continue ; fi
118211730Simp
119211730Simp    is_disk "$_zvars" >/dev/null 2>/dev/null
120220059Sjpaetzel    if [ $? -eq 0 ] ; then
121234990Sjpaetzel      echo "Setting up ZFS disk $_zvars" >>${LOGOUT}
122211730Simp      init_gpt_full_disk "$_zvars" >/dev/null 2>/dev/null
123234990Sjpaetzel      rc_halt "gpart add -a 4k -t freebsd-zfs ${_zvars}" >/dev/null 2>/dev/null
124234990Sjpaetzel      rc_halt "gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${_zvars}" >/dev/null 2>/dev/null
125211730Simp      _nZFS="$_nZFS ${_zvars}p2"	
126211730Simp    else
127211730Simp      _nZFS="$_nZFS ${_zvars}"	
128211730Simp    fi	
129211730Simp  done
130234990Sjpaetzel  echo "$ZTYPE $2 `echo $_nZFS | tr -s ' '`"
131209513Simp} ;
132209513Simp
133209513Simp# Function which creates a unique label name for the specified mount
134209513Simpgen_glabel_name()
135209513Simp{
136209513Simp  MOUNT="$1"
137209513Simp  TYPE="$2"
138209513Simp  NUM="0"
139209513Simp  MAXNUM="20"
140209513Simp
141232899Sjpaetzel  if [ "$TYPE" = "ZFS" ] ; then
142232899Sjpaetzel    NAME="zpool"
143232899Sjpaetzel  elif [ "$MOUNT" = "/" ] ; then
144209513Simp    NAME="rootfs"
145209513Simp  else
146209513Simp    # If doing a swap partition, also rename it
147209513Simp    if [ "${TYPE}" = "SWAP" ]
148209513Simp    then
149209513Simp      NAME="swap"
150209513Simp    else
151209513Simp      NAME="`echo $MOUNT | sed 's|/||g' | sed 's| ||g'`"
152209513Simp    fi
153209513Simp  fi
154209513Simp
155209513Simp  # Loop through and break when we find our first available label
156209513Simp  while
157209513Simp  Z=1
158209513Simp  do
159220059Sjpaetzel    glabel status | grep -q "${NAME}${NUM}" 2>/dev/null
160220059Sjpaetzel    if [ $? -ne 0 ]
161209513Simp    then
162209513Simp      break
163209513Simp    else
164220059Sjpaetzel        NUM=$((NUM+1))
165209513Simp    fi
166209513Simp
167209513Simp    if [ $NUM -gt $MAXNUM ]
168209513Simp    then
169209513Simp      exit_err "Cannot allocate additional glabel name for $NAME"
170209513Simp      break
171209513Simp    fi
172209513Simp  done 
173209513Simp   
174209513Simp
175220059Sjpaetzel  export VAL="${NAME}${NUM}" 
176209513Simp};
177209513Simp
178240165Sjpaetzel# Function to determine the size we can safely use when 0 is specified
179240165Sjpaetzelget_autosize()
180240165Sjpaetzel{
181240165Sjpaetzel  # Disk tag to look for
182240165Sjpaetzel  dTag="$1"
183240165Sjpaetzel
184240165Sjpaetzel  # Total MB Avail
185240165Sjpaetzel  get_disk_mediasize_mb "$2"
186240165Sjpaetzel  local _aSize=$VAL
187240165Sjpaetzel
188240165Sjpaetzel  while read line
189240165Sjpaetzel  do
190240165Sjpaetzel    # Check for data on this slice
191240165Sjpaetzel    echo $line | grep -q "^${_dTag}-part=" 2>/dev/null
192240165Sjpaetzel    if [ $? -ne 0 ] ; then continue ; fi
193240165Sjpaetzel
194240165Sjpaetzel    get_value_from_string "${line}"
195240165Sjpaetzel    STRING="$VAL"
196240165Sjpaetzel
197240165Sjpaetzel    # Get the size of this partition
198240165Sjpaetzel    SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 
199240165Sjpaetzel    if [ $SIZE -eq 0 ] ; then continue ; fi
200240165Sjpaetzel    _aSize=`expr $_aSize - $SIZE`
201240165Sjpaetzel  done <${CFGF}
202240165Sjpaetzel
203240165Sjpaetzel  # Pad the size a bit
204240165Sjpaetzel  _aSize=`expr $_aSize - 2`
205240165Sjpaetzel
206240165Sjpaetzel  VAL="$_aSize"
207240165Sjpaetzel  export VAL
208240165Sjpaetzel};
209240165Sjpaetzel
210217229Sjpaetzel# Function to setup partitions using gpart
211217229Sjpaetzelsetup_gpart_partitions()
212209513Simp{
213217229Sjpaetzel  local _dTag="$1"
214217229Sjpaetzel  local _pDisk="$2"
215217229Sjpaetzel  local _wSlice="$3"
216217229Sjpaetzel  local _sNum="$4"
217217229Sjpaetzel  local _pType="$5"
218209513Simp  FOUNDPARTS="1"
219240165Sjpaetzel  USEDAUTOSIZE=0
220209513Simp
221217229Sjpaetzel  # Lets read in the config file now and setup our partitions
222217229Sjpaetzel  if [ "${_pType}" = "gpt" ] ; then
223217229Sjpaetzel    CURPART="2"
224235006Sjpaetzel  elif [ "${_pType}" = "apm" ] ; then
225235006Sjpaetzel    CURPART="3"
226217229Sjpaetzel  else
227217229Sjpaetzel    PARTLETTER="a"
228217229Sjpaetzel    CURPART="1"
229227368Sjpaetzel    if [ "${_pType}" = "mbr" ] ; then
230227368Sjpaetzel      rc_halt "gpart create -s BSD ${_wSlice}"
231227368Sjpaetzel    fi
232217229Sjpaetzel  fi
233209513Simp
234209513Simp  while read line
235209513Simp  do
236209513Simp    # Check for data on this slice
237220059Sjpaetzel    echo $line | grep -q "^${_dTag}-part=" 2>/dev/null
238220059Sjpaetzel    if [ $? -eq 0 ]
239209513Simp    then
240209513Simp      FOUNDPARTS="0"
241209513Simp      # Found a slice- entry, lets get the slice info
242209513Simp      get_value_from_string "${line}"
243209513Simp      STRING="$VAL"
244209513Simp
245209513Simp      # We need to split up the string now, and pick out the variables
246209513Simp      FS=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 1` 
247209513Simp      SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 
248209513Simp      MNT=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 3` 
249209513Simp
250209513Simp      # Check if we have a .eli extension on this FS
251220059Sjpaetzel      echo ${FS} | grep -q ".eli" 2>/dev/null
252220059Sjpaetzel      if [ $? -eq 0 ]
253209513Simp      then
254209513Simp        FS="`echo ${FS} | cut -d '.' -f 1`"
255209513Simp        ENC="ON"
256209513Simp        check_for_enc_pass "${line}"
257209513Simp        if [ "${VAL}" != "" ] ; then
258209513Simp          # We have a user supplied password, save it for later
259209513Simp          ENCPASS="${VAL}" 
260209513Simp        fi
261209513Simp      else
262209513Simp        ENC="OFF"
263209513Simp      fi
264209513Simp
265209513Simp      # Check if the user tried to setup / as an encrypted partition
266209513Simp      check_for_mount "${MNT}" "/"
267220059Sjpaetzel      if [ $? -eq 0 -a "${ENC}" = "ON" ]
268209513Simp      then
269220059Sjpaetzel        export USINGENCROOT="0"
270209513Simp      fi
271209513Simp          
272209513Simp      # Now check that these values are sane
273209513Simp      case $FS in
274213647Simp        UFS|UFS+S|UFS+J|UFS+SUJ|ZFS|SWAP) ;;
275209513Simp       *) exit_err "ERROR: Invalid file system specified on $line" ;;
276209513Simp      esac
277209513Simp
278209513Simp      # Check that we have a valid size number
279209513Simp      expr $SIZE + 1 >/dev/null 2>/dev/null
280220059Sjpaetzel      if [ $? -ne 0 ]; then
281209513Simp        exit_err "ERROR: The size specified on $line is invalid"
282209513Simp      fi
283209513Simp
284209513Simp      # Check that the mount-point starts with /
285220059Sjpaetzel      echo "$MNT" | grep -qe "^/" -e "^none" 2>/dev/null
286220059Sjpaetzel      if [ $? -ne 0 ]; then
287209513Simp        exit_err "ERROR: The mount-point specified on $line is invalid"
288209513Simp      fi
289209513Simp
290209513Simp      if [ "$SIZE" = "0" ]
291209513Simp      then
292240165Sjpaetzel	if [ $USEDAUTOSIZE -eq 1 ] ; then
293240165Sjpaetzel          exit_err "ERROR: You can not have two partitions with a size of 0 specified!"
294240165Sjpaetzel	fi
295240165Sjpaetzel        case ${_pType} in
296240165Sjpaetzel	  gpt|apm) get_autosize "${_dTag}" "$_pDisk" ;;
297240165Sjpaetzel	        *) get_autosize "${_dTag}" "$_wSlice" ;;
298240165Sjpaetzel        esac
299240165Sjpaetzel        SOUT="-s ${VAL}M"
300240165Sjpaetzel	USEDAUTOSIZE=1
301209513Simp      else
302209513Simp        SOUT="-s ${SIZE}M"
303209513Simp      fi
304209513Simp
305209513Simp      # Check if we found a valid root partition
306209513Simp      check_for_mount "${MNT}" "/"
307220059Sjpaetzel      if [ $? -eq 0 ] ; then
308220059Sjpaetzel        export FOUNDROOT="1"
309217229Sjpaetzel        if [ "${CURPART}" = "2" -a "$_pType" = "gpt" ] ; then
310220059Sjpaetzel          export FOUNDROOT="0"
311209513Simp        fi
312235006Sjpaetzel        if [ "${CURPART}" = "3" -a "$_pType" = "apm" ] ; then
313235006Sjpaetzel          export FOUNDROOT="0"
314235006Sjpaetzel        fi
315217229Sjpaetzel        if [ "${CURPART}" = "1" -a "$_pType" = "mbr" ] ; then
316220059Sjpaetzel          export FOUNDROOT="0"
317217229Sjpaetzel        fi
318227368Sjpaetzel        if [ "${CURPART}" = "1" -a "$_pType" = "gptslice" ] ; then
319227368Sjpaetzel          export FOUNDROOT="0"
320227368Sjpaetzel        fi
321209513Simp      fi
322209513Simp
323209513Simp      check_for_mount "${MNT}" "/boot"
324220059Sjpaetzel      if [ $? -eq 0 ] ; then
325220059Sjpaetzel        export USINGBOOTPART="0"
326217229Sjpaetzel        if [ "${CURPART}" != "2" -a "${_pType}" = "gpt" ] ; then
327209513Simp            exit_err "/boot partition must be first partition"
328209513Simp        fi
329235006Sjpaetzel        if [ "${CURPART}" != "3" -a "${_pType}" = "apm" ] ; then
330235006Sjpaetzel            exit_err "/boot partition must be first partition"
331235006Sjpaetzel        fi
332217229Sjpaetzel        if [ "${CURPART}" != "1" -a "${_pType}" = "mbr" ] ; then
333217229Sjpaetzel            exit_err "/boot partition must be first partition"
334217229Sjpaetzel        fi
335227368Sjpaetzel        if [ "${CURPART}" != "1" -a "${_pType}" = "gptslice" ] ; then
336227368Sjpaetzel            exit_err "/boot partition must be first partition"
337227368Sjpaetzel        fi
338217229Sjpaetzel
339217229Sjpaetzel        if [ "${FS}" != "UFS" -a "${FS}" != "UFS+S" -a "${FS}" != "UFS+J" -a "${FS}" != "UFS+SUJ" ] ; then
340217229Sjpaetzel          exit_err "/boot partition must be formatted with UFS"
341217229Sjpaetzel        fi
342209513Simp      fi
343209513Simp
344209513Simp      # Generate a unique label name for this mount
345209513Simp      gen_glabel_name "${MNT}" "${FS}"
346209513Simp      PLABEL="${VAL}"
347209513Simp
348209513Simp      # Get any extra options for this fs / line
349217229Sjpaetzel      if [ "${_pType}" = "gpt" ] ; then
350217229Sjpaetzel        get_fs_line_xvars "${_pDisk}p${CURPART}" "${STRING}"
351235006Sjpaetzel      elif [ "${_pType}" = "apm" ] ; then
352235006Sjpaetzel        get_fs_line_xvars "${_pDisk}s${CURPART}" "${STRING}"
353217229Sjpaetzel      else
354227118Sjpaetzel        get_fs_line_xvars "${_wSlice}${PARTLETTER}" "${STRING}"
355217229Sjpaetzel      fi
356234990Sjpaetzel      XTRAOPTS="$VAR"
357209513Simp
358209513Simp      # Check if using zfs mirror
359234990Sjpaetzel      echo ${XTRAOPTS} | grep -q -e "mirror" -e "raidz"
360225657Sjpaetzel      if [ $? -eq 0 -a "$FS" = "ZFS" ] ; then
361227368Sjpaetzel        if [ "${_pType}" = "gpt" -o "${_pType}" = "gptslice" ] ; then
362217229Sjpaetzel       	  XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}p${CURPART}")
363235006Sjpaetzel        elif [ "${_pType}" = "apm" ] ; then
364235006Sjpaetzel       	  XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_pDisk}s${CURPART}")
365217229Sjpaetzel        else
366234990Sjpaetzel       	  XTRAOPTS=$(setup_zfs_mirror_parts "$XTRAOPTS" "${_wSlice}${PARTLETTER}")
367217229Sjpaetzel        fi
368209513Simp      fi
369209513Simp
370209513Simp      # Figure out the gpart type to use
371209513Simp      case ${FS} in
372211730Simp        ZFS) PARTYPE="freebsd-zfs" ;;
373211730Simp        SWAP) PARTYPE="freebsd-swap" ;;
374211730Simp        *) PARTYPE="freebsd-ufs" ;;
375209513Simp      esac
376209513Simp
377209513Simp      # Create the partition
378217229Sjpaetzel      if [ "${_pType}" = "gpt" ] ; then
379217229Sjpaetzel	if [ "$CURPART" = "2" ] ; then
380217229Sjpaetzel	  # If this is GPT, make sure first partition is aligned to 4k
381227368Sjpaetzel          sleep 2
382232901Sjpaetzel          rc_halt "gpart add -a 4k ${SOUT} -t ${PARTYPE} ${_pDisk}"
383217229Sjpaetzel	else
384227368Sjpaetzel          sleep 2
385217229Sjpaetzel          rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}"
386217229Sjpaetzel	fi
387227368Sjpaetzel      elif [ "${_pType}" = "gptslice" ]; then
388227368Sjpaetzel        sleep 2
389227368Sjpaetzel        rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_wSlice}"
390235006Sjpaetzel      elif [ "${_pType}" = "apm" ]; then
391235006Sjpaetzel        sleep 2
392235006Sjpaetzel        rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}"
393217229Sjpaetzel      else
394227368Sjpaetzel        sleep 2
395217229Sjpaetzel        rc_halt "gpart add ${SOUT} -t ${PARTYPE} -i ${CURPART} ${_wSlice}"
396217229Sjpaetzel      fi
397209513Simp
398209513Simp      # Check if this is a root / boot partition, and stamp the right loader
399209513Simp      for TESTMNT in `echo ${MNT} | sed 's|,| |g'`
400209513Simp      do
401209513Simp        if [ "${TESTMNT}" = "/" -a -z "${BOOTTYPE}" ] ; then
402209513Simp           BOOTTYPE="${PARTYPE}" 
403209513Simp        fi 
404209513Simp        if [ "${TESTMNT}" = "/boot" ]  ; then
405209513Simp           BOOTTYPE="${PARTYPE}" 
406209513Simp        fi 
407209513Simp      done 
408209513Simp
409209513Simp      # Save this data to our partition config dir
410217229Sjpaetzel      if [ "${_pType}" = "gpt" ] ; then
411220909Sjpaetzel	_dFile="`echo $_pDisk | sed 's|/|-|g'`"
412232899Sjpaetzel        echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}p${CURPART}
413209513Simp
414217229Sjpaetzel        # Clear out any headers
415217229Sjpaetzel        sleep 2
416220059Sjpaetzel        dd if=/dev/zero of=${_pDisk}p${CURPART} count=2048 2>/dev/null
417209513Simp
418217229Sjpaetzel        # If we have a enc password, save it as well
419220059Sjpaetzel        if [ -n "${ENCPASS}" ] ; then
420220909Sjpaetzel          echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}p${CURPART}-encpass
421217229Sjpaetzel        fi
422235006Sjpaetzel      elif [ "${_pType}" = "apm" ] ; then
423235006Sjpaetzel	_dFile="`echo $_pDisk | sed 's|/|-|g'`"
424235006Sjpaetzel        echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}s${CURPART}
425235006Sjpaetzel
426235006Sjpaetzel        # Clear out any headers
427235006Sjpaetzel        sleep 2
428235006Sjpaetzel        dd if=/dev/zero of=${_pDisk}s${CURPART} count=2048 2>/dev/null
429235006Sjpaetzel
430235006Sjpaetzel        # If we have a enc password, save it as well
431235006Sjpaetzel        if [ -n "${ENCPASS}" ] ; then
432235006Sjpaetzel          echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}s${CURPART}-encpass
433235006Sjpaetzel        fi
434217229Sjpaetzel      else
435227368Sjpaetzel	# MBR Partition or GPT slice
436220909Sjpaetzel	_dFile="`echo $_wSlice | sed 's|/|-|g'`"
437232899Sjpaetzel        echo "${FS}#${MNT}#${ENC}#${PLABEL}#MBR#${XTRAOPTS}#${IMAGE}" >${PARTDIR}/${_dFile}${PARTLETTER}
438217229Sjpaetzel        # Clear out any headers
439217229Sjpaetzel        sleep 2
440220059Sjpaetzel        dd if=/dev/zero of=${_wSlice}${PARTLETTER} count=2048 2>/dev/null
441217229Sjpaetzel
442217229Sjpaetzel        # If we have a enc password, save it as well
443220059Sjpaetzel        if [ -n "${ENCPASS}" ] ; then
444220909Sjpaetzel          echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}${PARTLETTER}-encpass
445217229Sjpaetzel        fi
446209513Simp      fi
447209513Simp
448217229Sjpaetzel
449209513Simp      # Increment our parts counter
450235006Sjpaetzel      if [ "$_pType" = "gpt" -o "$_pType" = "apm" ] ; then 
451220059Sjpaetzel          CURPART=$((CURPART+1))
452235006Sjpaetzel        # If this is a gpt/apm partition, 
453235006Sjpaetzel        # we can continue and skip the MBR part letter stuff
454217229Sjpaetzel        continue
455217229Sjpaetzel      else
456220059Sjpaetzel          CURPART=$((CURPART+1))
457217229Sjpaetzel        if [ "$CURPART" = "3" ] ; then CURPART="4" ; fi
458217229Sjpaetzel      fi
459209513Simp
460217229Sjpaetzel
461217229Sjpaetzel      # This partition letter is used, get the next one
462217229Sjpaetzel      case ${PARTLETTER} in
463217229Sjpaetzel        a) PARTLETTER="b" ;;
464217229Sjpaetzel        b) PARTLETTER="d" ;;
465217229Sjpaetzel        d) PARTLETTER="e" ;;
466217229Sjpaetzel        e) PARTLETTER="f" ;;
467217229Sjpaetzel        f) PARTLETTER="g" ;;
468217229Sjpaetzel        g) PARTLETTER="h" ;;
469217229Sjpaetzel        h) PARTLETTER="ERR" ;;
470217229Sjpaetzel        *) exit_err "ERROR: bsdlabel only supports up to letter h for partitions." ;;
471217229Sjpaetzel      esac
472217229Sjpaetzel
473209513Simp    fi # End of subsection locating a slice in config
474209513Simp
475220059Sjpaetzel    echo $line | grep -q "^commitDiskLabel" 2>/dev/null
476220059Sjpaetzel    if [ $? -eq 0 -a "${FOUNDPARTS}" = "0" ]
477209513Simp    then
478209513Simp
479209513Simp      # If this is the boot disk, stamp the right gptboot
480217229Sjpaetzel      if [ ! -z "${BOOTTYPE}" -a "$_pType" = "gpt" ] ; then
481209513Simp        case ${BOOTTYPE} in
482217229Sjpaetzel          freebsd-ufs) rc_halt "gpart bootcode -p /boot/gptboot -i 1 ${_pDisk}" ;;
483217229Sjpaetzel          freebsd-zfs) rc_halt "gpart bootcode -p /boot/gptzfsboot -i 1 ${_pDisk}" ;;
484209513Simp        esac 
485209513Simp      fi
486209513Simp
487217229Sjpaetzel      # Make sure to stamp the MBR loader
488217229Sjpaetzel      if [ "$_pType" = "mbr" ] ; then
489217229Sjpaetzel	rc_halt "gpart bootcode -b /boot/boot ${_wSlice}"
490217229Sjpaetzel      fi
491209513Simp
492209513Simp      # Found our flag to commit this label setup, check that we found at least 1 partition
493232899Sjpaetzel      if [ "${CURPART}" = "1" ] ; then
494209513Simp        exit_err "ERROR: commitDiskLabel was called without any partition entries for it!"
495209513Simp      fi
496209513Simp
497209513Simp      break
498209513Simp    fi
499209513Simp  done <${CFGF}
500209513Simp};
501209513Simp
502209513Simp# Reads through the config and sets up a BSDLabel for the given slice
503209513Simppopulate_disk_label()
504209513Simp{
505209513Simp  if [ -z "${1}" ]
506209513Simp  then
507209513Simp    exit_err "ERROR: populate_disk_label() called without argument!"
508209513Simp  fi
509209513Simp
510209513Simp  # Set some vars from the given working slice
511220909Sjpaetzel  diskid="`echo $1 | cut -d ':' -f 1`" 
512220909Sjpaetzel  disk="`echo $1 | cut -d ':' -f 1 | sed 's|-|/|g'`" 
513220909Sjpaetzel  slicenum="`echo $1 | cut -d ':' -f 2`" 
514220909Sjpaetzel  type="`echo $1 | cut -d ':' -f 3`" 
515209513Simp  
516209513Simp  # Set WRKSLICE based upon format we are using
517209513Simp  if [ "$type" = "mbr" ] ; then
518220909Sjpaetzel    wrkslice="${diskid}s${slicenum}"
519209513Simp  fi
520235006Sjpaetzel  if [ "$type" = "apm" ] ; then
521235006Sjpaetzel    wrkslice="${diskid}s${slicenum}"
522235006Sjpaetzel  fi
523227368Sjpaetzel  if [ "$type" = "gpt" -o "$type" = "gptslice" ] ; then
524220909Sjpaetzel    wrkslice="${diskid}p${slicenum}"
525209513Simp  fi
526209513Simp
527220909Sjpaetzel  if [ ! -e "${SLICECFGDIR}/${wrkslice}" ] ; then
528209513Simp    exit_err "ERROR: Missing SLICETAG data. This shouldn't happen - please let the developers know"
529209513Simp  fi
530209513Simp
531220909Sjpaetzel  disktag="`cat ${SLICECFGDIR}/${wrkslice}`"
532220909Sjpaetzel  slicedev="`echo $wrkslice | sed 's|-|/|g'`"
533220909Sjpaetzel  
534217229Sjpaetzel  # Setup the partitions with gpart
535220909Sjpaetzel  setup_gpart_partitions "${disktag}" "${disk}" "${slicedev}" "${slicenum}" "${type}"
536209513Simp
537209513Simp};
538209513Simp
539209513Simp# Function which reads in the disk slice config, and performs it
540209513Simpsetup_disk_label()
541209513Simp{
542209513Simp  # We are ready to start setting up the label, lets read the config and do the actions
543209513Simp  # First confirm that we have a valid WORKINGSLICES
544213650Simp  if [ -z "${WORKINGSLICES}" ]; then
545209513Simp    exit_err "ERROR: No slices were setup! Please report this to the maintainers"
546209513Simp  fi
547209513Simp
548209513Simp  # Check that the slices we have did indeed get setup and gpart worked
549209513Simp  for i in $WORKINGSLICES
550209513Simp  do
551209513Simp    disk="`echo $i | cut -d '-' -f 1`" 
552209513Simp    pnum="`echo $i | cut -d '-' -f 2`" 
553209513Simp    type="`echo $i | cut -d '-' -f 3`" 
554220909Sjpaetzel    if [ "$type" = "mbr" -a ! -e "${disk}s${pnum}" ] ; then
555209513Simp      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
556209513Simp    fi
557220909Sjpaetzel    if [ "$type" = "gpt" -a ! -e "${disk}p${pnum}" ] ; then
558209513Simp      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
559209513Simp    fi
560235006Sjpaetzel    if [ "$type" = "apm" -a ! -e "${disk}s${pnum}" ] ; then
561235006Sjpaetzel      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
562235006Sjpaetzel    fi
563227368Sjpaetzel    if [ "$type" = "gptslice" -a ! -e "${disk}p${pnum}" ] ; then
564227368Sjpaetzel      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
565227368Sjpaetzel    fi
566209513Simp  done
567209513Simp
568209513Simp  # Setup some files which we'll be referring to
569220059Sjpaetzel  export LABELLIST="${TMPDIR}/workingLabels"
570209513Simp  rm $LABELLIST >/dev/null 2>/dev/null
571209513Simp
572209513Simp  # Set our flag to determine if we've got a valid root partition in this setup
573220059Sjpaetzel  export FOUNDROOT="-1"
574209513Simp
575209513Simp  # Check if we are using a /boot partition
576220059Sjpaetzel  export USINGBOOTPART="1"
577209513Simp 
578209513Simp  # Set encryption on root check
579220059Sjpaetzel  export USINGENCROOT="1"
580209513Simp  
581209513Simp  # Make the tmp directory where we'll store FS info & mount-points
582209513Simp  rm -rf ${PARTDIR} >/dev/null 2>/dev/null
583209513Simp  mkdir -p ${PARTDIR} >/dev/null 2>/dev/null
584209513Simp  rm -rf ${PARTDIR}-enc >/dev/null 2>/dev/null
585209513Simp  mkdir -p ${PARTDIR}-enc >/dev/null 2>/dev/null
586209513Simp
587209513Simp  for i in $WORKINGSLICES
588209513Simp  do
589209513Simp    populate_disk_label "${i}"
590209513Simp  done
591209513Simp
592209513Simp  # Check if we made a root partition
593209513Simp  if [ "$FOUNDROOT" = "-1" ]
594209513Simp  then
595209513Simp    exit_err "ERROR: No root (/) partition specified!!"
596209513Simp  fi
597209513Simp
598209513Simp  # Check if we made a root partition
599209513Simp  if [ "$FOUNDROOT" = "1" -a "${USINGBOOTPART}" != "0" ]
600209513Simp  then
601209513Simp    exit_err "ERROR: (/) partition isn't first partition on disk!"
602209513Simp  fi
603209513Simp
604209513Simp  if [ "${USINGENCROOT}" = "0" -a "${USINGBOOTPART}" != "0" ]
605209513Simp  then
606209513Simp    exit_err "ERROR: Can't encrypt (/) with no (/boot) partition!"
607209513Simp  fi
608209513Simp};
609209513Simp
610212337Simpcheck_fstab_mbr()
611212337Simp{
612212337Simp  local SLICE
613212337Simp  local FSTAB
614212337Simp
615212337Simp  if [ -z "$2" ]
616212337Simp  then
617212337Simp	return 1
618212337Simp  fi
619212337Simp
620212337Simp  SLICE="$1"
621212337Simp  FSTAB="$2/etc/fstab"
622212337Simp
623212337Simp  if [ -f "${FSTAB}" ]
624212337Simp  then
625212337Simp    PARTLETTER=`echo "$SLICE" | sed -E 's|^.+([a-h])$|\1|'`
626212337Simp
627220059Sjpaetzel    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1
628220059Sjpaetzel    if [ $? -eq 0 ]
629212337Simp    then
630212337Simp      if [ "${PARTLETTER}" = "a" ]
631212337Simp      then
632212337Simp        FOUNDROOT="0"
633212337Simp      else
634212337Simp        FOUNDROOT="1"
635212337Simp      fi
636213650Simp
637213650Simp      ROOTIMAGE="1"
638213650Simp
639212337Simp      export FOUNDROOT
640213650Simp      export ROOTIMAGE
641212337Simp    fi
642212337Simp
643220059Sjpaetzel    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1
644220059Sjpaetzel    if [ $? -eq 0 ]
645212337Simp    then
646212337Simp      if [ "${PARTLETTER}" = "a" ]
647212337Simp      then
648212337Simp        USINGBOOTPART="0"
649212337Simp      else 
650212337Simp        exit_err "/boot partition must be first partition"
651212337Simp      fi 
652212337Simp      export USINGBOOTPART
653212337Simp    fi
654212337Simp
655212337Simp    return 0
656212337Simp  fi
657212337Simp
658212337Simp  return 1
659212337Simp};
660212337Simp
661212337Simpcheck_fstab_gpt()
662212337Simp{
663212337Simp  local SLICE
664212337Simp  local FSTAB
665212337Simp
666212337Simp  if [ -z "$2" ]
667212337Simp  then
668212337Simp	return 1
669212337Simp  fi
670212337Simp
671212337Simp  SLICE="$1"
672212337Simp  FSTAB="$2/etc/fstab"
673212337Simp
674212337Simp  if [ -f "${FSTAB}" ]
675212337Simp  then
676212337Simp    PARTNUMBER=`echo "${SLICE}" | sed -E 's|^.+p([0-9]*)$|\1|'`
677212337Simp
678220059Sjpaetzel    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1
679220059Sjpaetzel    if [ $? -eq 0 ]
680212337Simp    then
681212337Simp      if [ "${PARTNUMBER}" = "2" ]
682212337Simp      then
683212337Simp        FOUNDROOT="0"
684212337Simp      else
685212337Simp        FOUNDROOT="1"
686212337Simp      fi
687213650Simp
688213650Simp      ROOTIMAGE="1"
689213650Simp
690212337Simp      export FOUNDROOT
691213650Simp      export ROOTIMAGE
692212337Simp    fi
693212337Simp
694220059Sjpaetzel    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1
695220059Sjpaetzel    if [ $? -eq 0 ]
696212337Simp    then
697212337Simp      if [ "${PARTNUMBER}" = "2" ]
698212337Simp      then
699212337Simp        USINGBOOTPART="0"
700212337Simp      else 
701212337Simp        exit_err "/boot partition must be first partition"
702212337Simp      fi 
703212337Simp      export USINGBOOTPART
704212337Simp    fi
705212337Simp
706212337Simp    return 0
707212337Simp  fi
708212337Simp
709212337Simp
710212337Simp  return 1
711212337Simp};
712212337Simp
713213650Simpcheck_disk_layout()
714212337Simp{
715212337Simp  local SLICES
716212337Simp  local TYPE
717213650Simp  local DISK
718212337Simp  local RES
719212337Simp  local F
720212337Simp
721213650Simp  DISK="$1"
722212337Simp  TYPE="MBR"
723212337Simp
724213650Simp  if [ -z "${DISK}" ]
725212337Simp  then
726212337Simp	return 1
727212337Simp  fi
728212337Simp
729213650Simp  SLICES_MBR=`ls /dev/${DISK}s[1-4]*[a-h]* 2>/dev/null`
730213650Simp  SLICES_GPT=`ls /dev/${DISK}p[0-9]* 2>/dev/null`
731213650Simp  SLICES_SLICE=`ls /dev/${DISK}[a-h]* 2>/dev/null`
732213650Simp
733213650Simp  if [ -n "${SLICES_MBR}" ]
734212337Simp  then
735213650Simp    SLICES="${SLICES_MBR}"
736213650Simp    TYPE="MBR"
737213650Simp    RES=0
738212337Simp  fi
739213650Simp  if [ -n "${SLICES_GPT}" ]
740212337Simp  then
741213650Simp    SLICES="${SLICES_GPT}"
742213650Simp    TYPE="GPT"
743212337Simp    RES=0
744212337Simp  fi
745213650Simp  if [ -n "${SLICES_SLICE}" ]
746213650Simp  then
747213650Simp    SLICES="${SLICES_SLICE}"
748213650Simp    TYPE="MBR"
749213650Simp    RES=0
750213650Simp  fi
751213650Simp  
752212337Simp  for slice in ${SLICES}
753212337Simp  do
754212337Simp    F=1
755212337Simp    mount ${slice} /mnt 2>/dev/null
756220059Sjpaetzel    if [ $? -ne 0 ]
757212337Simp    then
758212337Simp      continue
759212337Simp    fi 
760212337Simp
761212337Simp    if [ "${TYPE}" = "MBR" ]
762212337Simp    then
763212337Simp	  check_fstab_mbr "${slice}" "/mnt"
764212337Simp      F="$?"
765212337Simp
766212337Simp    elif [ "${TYPE}" = "GPT" ]
767212337Simp    then
768212337Simp	  check_fstab_gpt "${slice}" "/mnt"
769212337Simp      F="$?"
770212337Simp    fi 
771212337Simp
772220059Sjpaetzel    if [ ${F} -eq 0 ]
773212337Simp    then
774212337Simp      umount /mnt
775212337Simp      break 
776212337Simp    fi
777212337Simp
778212337Simp    umount /mnt
779212337Simp  done
780212337Simp
781212337Simp  return ${RES}
782212337Simp};
783