source: src-sh/pc-sysinstall/backend/functions-bsdlabel.sh @ 3018894

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since 3018894 was 3018894, checked in by Kris Moore <kris@…>, 8 months ago

Large update to pc-sysinstall:

  • Improve how we create disk layouts for ZFS mirror/raidz disks
  • Do not blindly create a single freebsd-zfs partition
  • Create partition / sizes to match the parent disk
  • When adding freebsd-swap to a ZFS mirror/raidz parent, we will now setup gmirror on the swap devices and label it as such
  • Property mode set to 100755
File size: 22.4 KB
Line 
1#!/bin/sh
2#-
3# Copyright (c) 2010 iXsystems, Inc.  All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24# SUCH DAMAGE.
25#
26# $FreeBSD: head/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh 247735 2013-03-03 23:07:27Z jpaetzel $
27
28# Functions related to disk operations using bsdlabel
29
30# Check if we are are provided a geli password on the nextline of the config
31check_for_enc_pass()
32{
33  CURLINE="${1}"
34 
35  get_next_cfg_line "${CFGF}" "${CURLINE}" 
36  echo ${VAL} | grep -q "^encpass=" 2>/dev/null
37  if [ $? -eq 0 ] ; then
38    # Found a password, return it
39    get_value_from_string "${VAL}"
40    return
41  fi
42
43  export VAL=""
44  return
45};
46
47# On check on the disk-label line if we have any extra vars for this device
48get_fs_line_xvars()
49{
50  ACTIVEDEV="${1}"
51  LINE="${2}"
52
53  echo $LINE | cut -d ' ' -f 4 | grep -q '(' 2>/dev/null
54  if [ $? -ne 0 ] ; then return ; fi
55
56  # See if we are looking for ZFS specific options
57  echo $LINE | grep -q '^ZFS' 2>/dev/null
58  if [ $? -eq 0 ] ; then
59    ZTYPE="NONE"
60    ZFSVARS="`echo $LINE | cut -d ' ' -f 4-20 |cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`"
61
62    echo $ZFSVARS | grep -qE "^(disk|file|mirror|raidz(1|2|3)?|spare|log|cache):" 2>/dev/null
63    if [ $? -eq 0 ] ; then
64       ZTYPE=`echo $ZFSVARS | cut -f1 -d:`
65       tmpVars=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"`
66       ZFSVARS=""
67       # make sure we have a '/dev' in front of the extra devices
68       for i in $tmpVars
69       do
70          echo $i | grep -q '/dev/'
71          if [ $? -ne 0 ] ; then
72             ZFSVARS="$ZFSVARS /dev/${i}"
73          else
74             ZFSVARS="$ZFSVARS $i"
75          fi
76       done
77    fi
78
79    # Return the ZFS options
80    if [ "${ZTYPE}" = "NONE" ] ; then
81      VAR="${ACTIVEDEV} ${ZFSVARS}"
82    else
83      VAR="${ZTYPE} ${ACTIVEDEV} ${ZFSVARS}"
84    fi
85    export VAR
86    return
87  fi # End of ZFS block
88
89  # See if we are looking for UFS specific newfs options
90  echo $LINE | grep -q '^UFS' 2>/dev/null
91  if [ $? -eq 0 ] ; then
92    FSVARS="`echo $LINE | cut -d '(' -f 2- | cut -d ')' -f 1 | xargs`"
93    VAR="${FSVARS}"
94    export VAR
95    return
96  fi
97
98  # If we got here, set VAR to empty and export
99  export VAR=""
100  return
101};
102
103# Init each zfs mirror disk with a boot sector so we can failover
104setup_zfs_mirror_parts()
105{
106  _nZFS=""
107  SOUT="$4"
108
109  # Check if the target disk is using GRUB
110  grep -q "$3" ${TMPDIR}/.grub-install 2>/dev/null
111  if [ $? -eq 0 ] ; then
112     _tBL="GRUB"
113  else
114     _tBL="bsd"
115  fi
116
117  ZTYPE="`echo ${1} | awk '{print $1}'`"
118
119  # Using mirroring, setup boot partitions on each disk
120  _mirrline="`echo ${1} | sed 's|mirror ||g' | sed 's|raidz1 ||g' | sed 's|raidz2 ||g' | sed 's|raidz3 ||g' | sed 's|raidz ||g'`"
121  for _zvars in $_mirrline
122  do
123    echo "Looping through _zvars: $_zvars" >>${LOGOUT}
124    echo "$_zvars" | grep -q "${2}" 2>/dev/null
125    if [ $? -eq 0 ] ; then continue ; fi
126    if [ -z "$_zvars" ] ; then continue ; fi
127
128    is_disk "$_zvars" >/dev/null 2>/dev/null
129    if [ $? -eq 0 ] ; then
130
131      # Save this disk as one we want to clone the original disk setup to
132      ZFS_CLONE_DISKS="$ZFS_CLONE_DISKS ${_zvars}"
133      export ZFS_CLONE_DISKS
134
135      echo "Setting up ZFS disk $_zvars" >>${LOGOUT}
136      init_gpt_full_disk "$_zvars" "$_tBL" >/dev/null 2>/dev/null
137      #rc_halt "gpart add ${SOUT} -t freebsd-zfs ${_zvars}" >/dev/null 2>/dev/null
138
139      # If we are not using GRUB we need to add pmbr / gptzfsboot
140      if [ "$_tBL" != "GRUB" ] ; then
141        rc_halt "gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${_zvars}" >/dev/null 2>/dev/null
142      fi
143      _nZFS="$_nZFS ${_zvars}p2"       
144    else
145      _nZFS="$_nZFS ${_zvars}" 
146    fi 
147  done
148
149  # Export the ZXTRAOPTS
150  ZXTRAOPTS="$ZTYPE $2 `echo $_nZFS | tr -s ' '`"
151  export ZXTRAOPTS
152} ;
153
154# Function which creates a unique label name for the specified mount
155gen_glabel_name()
156{
157  MOUNT="$1"
158  TYPE="$2"
159  NUM="0"
160  MAXNUM="20"
161
162  if [ "$TYPE" = "ZFS" ] ; then
163    NAME="zpool"
164  elif [ "$MOUNT" = "/" ] ; then
165    NAME="rootfs"
166  else
167    # If doing a swap partition, also rename it
168    if [ "${TYPE}" = "SWAP" ]
169    then
170      NAME="swap"
171    else
172      NAME="`echo $MOUNT | sed 's|/||g' | sed 's| ||g'`"
173    fi
174  fi
175
176  # Loop through and break when we find our first available label
177  while
178  Z=1
179  do
180    glabel status | grep -q "${NAME}${NUM}" 2>/dev/null
181    if [ $? -ne 0 ]
182    then
183      break
184    else
185        NUM=$((NUM+1))
186    fi
187
188    if [ $NUM -gt $MAXNUM ]
189    then
190      exit_err "Cannot allocate additional glabel name for $NAME"
191      break
192    fi
193  done
194   
195
196  export VAL="${NAME}${NUM}" 
197};
198
199# Function to determine the size we can safely use when 0 is specified
200get_autosize()
201{
202  # Disk tag to look for
203  dTag="$1"
204
205  # Total MB Avail
206  get_disk_mediasize_mb "$2"
207  local _aSize=$VAL
208
209  while read line
210  do
211    # Check for data on this slice
212    echo $line | grep -q "^${_dTag}-part=" 2>/dev/null
213    if [ $? -ne 0 ] ; then continue ; fi
214
215    get_value_from_string "${line}"
216    STRING="$VAL"
217
218    # Get the size of this partition
219    SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 
220    if [ $SIZE -eq 0 ] ; then continue ; fi
221    _aSize=`expr $_aSize - $SIZE`
222  done <${CFGF}
223
224  # Pad the size a bit
225  _aSize=`expr $_aSize - 2`
226
227  VAL="$_aSize"
228  export VAL
229};
230
231# Function to setup partitions using gpart
232setup_gpart_partitions()
233{
234  local _dTag="$1"
235  local _pDisk="$2"
236  local _wSlice="$3"
237  local _sNum="$4"
238  local _pType="$5"
239  FOUNDPARTS="1"
240  USEDAUTOSIZE=0
241
242  # Lets read in the config file now and setup our partitions
243  if [ "${_pType}" = "gpt" ] ; then
244    CURPART="2"
245  elif [ "${_pType}" = "apm" ] ; then
246    CURPART="3"
247  else
248    PARTLETTER="a"
249    CURPART="1"
250    if [ "${_pType}" = "mbr" ] ; then
251      rc_halt "gpart create -s BSD ${_wSlice}"
252    fi
253  fi
254
255  # Unset ZFS_CLONE_DISKS
256  #ZFS_CLONE_DISKS=""
257
258  while read line
259  do
260    # Check for data on this slice
261    echo $line | grep -q "^${_dTag}-part=" 2>/dev/null
262    if [ $? -eq 0 ]
263    then
264      FOUNDPARTS="0"
265      # Found a slice- entry, lets get the slice info
266      get_value_from_string "${line}"
267      STRING="$VAL"
268
269      # We need to split up the string now, and pick out the variables
270      FS=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 1` 
271      SIZE=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 2` 
272      MNT=`echo $STRING | tr -s '\t' ' ' | cut -d ' ' -f 3` 
273
274      # Check if we have a .eli extension on this FS
275      echo ${FS} | grep -q ".eli" 2>/dev/null
276      if [ $? -eq 0 ]
277      then
278        FS="`echo ${FS} | cut -d '.' -f 1`"
279        ENC="ON"
280        check_for_enc_pass "${line}"
281        if [ "${VAL}" != "" ] ; then
282          # We have a user supplied password, save it for later
283          ENCPASS="${VAL}" 
284        fi
285      else
286        ENC="OFF"
287      fi
288
289      # Check if the user tried to setup / as an encrypted partition
290      check_for_mount "${MNT}" "/"
291      if [ $? -eq 0 -a "${ENC}" = "ON" ]
292      then
293        export USINGENCROOT="0"
294      fi
295         
296      # Now check that these values are sane
297      case $FS in
298        UFS|UFS+S|UFS+J|UFS+SUJ|ZFS|SWAP) ;;
299       *) exit_err "ERROR: Invalid file system specified on $line" ;;
300      esac
301
302      # Check that we have a valid size number
303      expr $SIZE + 1 >/dev/null 2>/dev/null
304      if [ $? -ne 0 ]; then
305        exit_err "ERROR: The size specified on $line is invalid"
306      fi
307
308      # Check that the mount-point starts with /
309      echo "$MNT" | grep -qe "^/" -e "^none" 2>/dev/null
310      if [ $? -ne 0 ]; then
311        exit_err "ERROR: The mount-point specified on $line is invalid"
312      fi
313
314      if [ "$SIZE" = "0" ]
315      then
316        if [ $USEDAUTOSIZE -eq 1 ] ; then
317          exit_err "ERROR: You can not have two partitions with a size of 0 specified!"
318        fi
319        case ${_pType} in
320          gpt|apm) get_autosize "${_dTag}" "$_pDisk" ;;
321                *) get_autosize "${_dTag}" "$_wSlice" ;;
322        esac
323        SOUT="-s ${VAL}M"
324        USEDAUTOSIZE=1
325      else
326        SOUT="-s ${SIZE}M"
327      fi
328
329      # Check if we found a valid root partition
330      check_for_mount "${MNT}" "/"
331      if [ $? -eq 0 ] ; then
332        export FOUNDROOT="1"
333        if [ "${CURPART}" = "2" -a "$_pType" = "gpt" ] ; then
334          export FOUNDROOT="0"
335        fi
336        if [ "${CURPART}" = "3" -a "$_pType" = "apm" ] ; then
337          export FOUNDROOT="0"
338        fi
339        if [ "${CURPART}" = "1" -a "$_pType" = "mbr" ] ; then
340          export FOUNDROOT="0"
341        fi
342        if [ "${CURPART}" = "1" -a "$_pType" = "gptslice" ] ; then
343          export FOUNDROOT="0"
344        fi
345      fi
346
347      check_for_mount "${MNT}" "/boot"
348      if [ $? -eq 0 ] ; then
349        export USINGBOOTPART="0"
350        if [ "${CURPART}" != "2" -a "${_pType}" = "gpt" ] ; then
351            exit_err "/boot partition must be first partition"
352        fi
353        if [ "${CURPART}" != "3" -a "${_pType}" = "apm" ] ; then
354            exit_err "/boot partition must be first partition"
355        fi
356        if [ "${CURPART}" != "1" -a "${_pType}" = "mbr" ] ; then
357            exit_err "/boot partition must be first partition"
358        fi
359        if [ "${CURPART}" != "1" -a "${_pType}" = "gptslice" ] ; then
360            exit_err "/boot partition must be first partition"
361        fi
362
363        if [ "${FS}" != "UFS" -a "${FS}" != "UFS+S" -a "${FS}" != "UFS+J" -a "${FS}" != "UFS+SUJ" ] ; then
364          exit_err "/boot partition must be formatted with UFS"
365        fi
366      fi
367
368      # Generate a unique label name for this mount
369      gen_glabel_name "${MNT}" "${FS}"
370      PLABEL="${VAL}"
371
372      # Get any extra options for this fs / line
373      if [ "${_pType}" = "gpt" ] ; then
374        get_fs_line_xvars "${_pDisk}p${CURPART}" "${STRING}"
375      elif [ "${_pType}" = "apm" ] ; then
376        get_fs_line_xvars "${_pDisk}s${CURPART}" "${STRING}"
377      else
378        get_fs_line_xvars "${_wSlice}${PARTLETTER}" "${STRING}"
379      fi
380      XTRAOPTS="$VAR"
381
382      # Check if using zfs mirror
383      echo ${XTRAOPTS} | grep -q -e "mirror" -e "raidz"
384      if [ $? -eq 0 -a "$FS" = "ZFS" ] ; then
385        if [ "${_pType}" = "gpt" -o "${_pType}" = "gptslice" ] ; then
386          setup_zfs_mirror_parts "${XTRAOPTS}" "${_pDisk}p${CURPART}" "${_pDisk}" "${SOUT}"
387          XTRAOPTS="${ZXTRAOPTS}"
388        elif [ "${_pType}" = "apm" ] ; then
389          setup_zfs_mirror_parts "${XTRAOPTS}" "${_pDisk}s${CURPART}" "${_pDisk}" "${SOUT}"
390          XTRAOPTS="${ZXTRAOPTS}"
391        else
392          setup_zfs_mirror_parts "${XTRAOPTS}" "${_wSlice}${PARTLETTER}" "${_pDisk}" "${SOUT}"
393          XTRAOPTS="${ZXTRAOPTS}"
394        fi
395      fi
396
397      # Figure out the gpart type to use
398      case ${FS} in
399        ZFS) PARTYPE="freebsd-zfs" ;;
400        SWAP) PARTYPE="freebsd-swap" ;;
401        *) PARTYPE="freebsd-ufs" ;;
402      esac
403
404      # Create the partition
405      if [ "${_pType}" = "gpt" ] ; then
406        sleep 2
407        aCmd="gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}"
408      elif [ "${_pType}" = "gptslice" ]; then
409        sleep 2
410        aCmd="gpart add ${SOUT} -t ${PARTYPE} ${_wSlice}"
411      elif [ "${_pType}" = "apm" ]; then
412        sleep 2
413        aCmd="gpart add ${SOUT} -t ${PARTYPE} ${_pDisk}"
414      else
415        sleep 2
416
417        # When we install to ZFS on a MBR slice, align the partition to 512b
418        # This corrects some issues with cranky disks causing gpart alignment
419        # to 4k to fail, resulting in zfsboot hanging...
420        aOpt=""
421        if [ "$CURPART" = "1" -a "$PARTYPE" = "freebsd-zfs" ] ; then
422           aOpt="-a 512b"
423        fi
424        aCmd="gpart add ${SOUT} ${aOpt} -t ${PARTYPE} -i ${CURPART} ${_wSlice}"
425      fi
426
427      # Run the gpart add command now
428      rc_halt "$aCmd"
429
430      # Check if we need to clone this layout to a ZFS mirror/raidz disk
431      if [ -n "$ZFS_CLONE_DISKS" ] ; then
432         for zC in $ZFS_CLONE_DISKS
433         do
434            echo_log "Cloning disk layout to ZFS disk ${zC}"
435            rc_halt "gpart add ${SOUT} -t ${PARTYPE} ${zC}"
436            if [ "$PARTYPE" = "freebsd-swap" ] ; then
437               # If this is the first device, save the original swap dev
438               if [ -z "$ZFS_SWAP_DEVS" ] ; then
439                  ZFS_SWAP_DEVS="${_pDisk}p${CURPART}"
440               fi
441               # Save this swap device, we will gmirror it later
442               ZFS_SWAP_DEVS="${ZFS_SWAP_DEVS} ${zC}p${CURPART}"
443               export ZFS_SWAP_DEVS
444            fi
445         done
446      fi
447
448      # Check if this is a root / boot partition, and stamp the right loader
449      for TESTMNT in `echo ${MNT} | sed 's|,| |g'`
450      do
451        if [ "${TESTMNT}" = "/" -a -z "${BOOTTYPE}" ] ; then
452           BOOTTYPE="${PARTYPE}" 
453        fi
454        if [ "${TESTMNT}" = "/boot" ]  ; then
455           BOOTTYPE="${PARTYPE}" 
456        fi
457      done 
458
459      # Save this data to our partition config dir
460      if [ "${_pType}" = "gpt" ] ; then
461        _dFile="`echo $_pDisk | sed 's|/|-|g'`"
462        echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}p${CURPART}
463
464        # Clear out any headers
465        sleep 2
466        dd if=/dev/zero of=${_pDisk}p${CURPART} count=2048 2>/dev/null
467
468        # If we have a enc password, save it as well
469        if [ -n "${ENCPASS}" ] ; then
470          echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}p${CURPART}-encpass
471        fi
472      elif [ "${_pType}" = "apm" ] ; then
473        _dFile="`echo $_pDisk | sed 's|/|-|g'`"
474        echo "${FS}#${MNT}#${ENC}#${PLABEL}#GPT#${XTRAOPTS}" >${PARTDIR}/${_dFile}s${CURPART}
475
476        # Clear out any headers
477        sleep 2
478        dd if=/dev/zero of=${_pDisk}s${CURPART} count=2048 2>/dev/null
479
480        # If we have a enc password, save it as well
481        if [ -n "${ENCPASS}" ] ; then
482          echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}s${CURPART}-encpass
483        fi
484      else
485        # MBR Partition or GPT slice
486        _dFile="`echo $_wSlice | sed 's|/|-|g'`"
487        echo "${FS}#${MNT}#${ENC}#${PLABEL}#MBR#${XTRAOPTS}#${IMAGE}" >${PARTDIR}/${_dFile}${PARTLETTER}
488        # Clear out any headers
489        sleep 2
490        dd if=/dev/zero of=${_wSlice}${PARTLETTER} count=2048 2>/dev/null
491
492        # If we have a enc password, save it as well
493        if [ -n "${ENCPASS}" ] ; then
494          echo "${ENCPASS}" >${PARTDIR}-enc/${_dFile}${PARTLETTER}-encpass
495        fi
496      fi
497
498
499      # Increment our parts counter
500      if [ "$_pType" = "gpt" -o "$_pType" = "apm" ] ; then
501          CURPART=$((CURPART+1))
502        # If this is a gpt/apm partition,
503        # we can continue and skip the MBR part letter stuff
504        continue
505      else
506          CURPART=$((CURPART+1))
507        if [ "$CURPART" = "3" ] ; then CURPART="4" ; fi
508      fi
509
510
511      # This partition letter is used, get the next one
512      case ${PARTLETTER} in
513        a) PARTLETTER="b" ;;
514        b) PARTLETTER="d" ;;
515        d) PARTLETTER="e" ;;
516        e) PARTLETTER="f" ;;
517        f) PARTLETTER="g" ;;
518        g) PARTLETTER="h" ;;
519        h) PARTLETTER="ERR" ;;
520        *) exit_err "ERROR: bsdlabel only supports up to letter h for partitions." ;;
521      esac
522
523    fi # End of subsection locating a slice in config
524
525    echo $line | grep -q "^commitDiskLabel" 2>/dev/null
526    if [ $? -eq 0 -a "${FOUNDPARTS}" = "0" ]
527    then
528
529      # If this is the boot disk, stamp the right gptboot
530      if [ ! -z "${BOOTTYPE}" -a "$_pType" = "gpt" ] ; then
531        case ${BOOTTYPE} in
532          freebsd-ufs) rc_halt "gpart bootcode -p /boot/gptboot -i 1 ${_pDisk}" ;;
533          freebsd-zfs) rc_halt "gpart bootcode -p /boot/gptzfsboot -i 1 ${_pDisk}" ;;
534        esac
535      fi
536
537      # Make sure to stamp the MBR loader
538      if [ "$_pType" = "mbr" ] ; then
539        rc_halt "gpart bootcode -b /boot/boot ${_wSlice}"
540      fi
541
542      # Found our flag to commit this label setup, check that we found at least 1 partition
543      if [ "${CURPART}" = "1" ] ; then
544        exit_err "ERROR: commitDiskLabel was called without any partition entries for it!"
545      fi
546
547      break
548    fi
549  done <${CFGF}
550};
551
552# Reads through the config and sets up a BSDLabel for the given slice
553populate_disk_label()
554{
555  if [ -z "${1}" ]
556  then
557    exit_err "ERROR: populate_disk_label() called without argument!"
558  fi
559
560  # Set some vars from the given working slice
561  diskid="`echo $1 | cut -d ':' -f 1`" 
562  disk="`echo $1 | cut -d ':' -f 1 | sed 's|-|/|g'`" 
563  slicenum="`echo $1 | cut -d ':' -f 2`" 
564  type="`echo $1 | cut -d ':' -f 3`" 
565 
566  # Set WRKSLICE based upon format we are using
567  if [ "$type" = "mbr" ] ; then
568    wrkslice="${diskid}s${slicenum}"
569  fi
570  if [ "$type" = "apm" ] ; then
571    wrkslice="${diskid}s${slicenum}"
572  fi
573  if [ "$type" = "gpt" -o "$type" = "gptslice" ] ; then
574    wrkslice="${diskid}p${slicenum}"
575  fi
576
577  if [ ! -e "${SLICECFGDIR}/${wrkslice}" ] ; then
578    exit_err "ERROR: Missing SLICETAG data. This shouldn't happen - please let the developers know"
579  fi
580
581  disktag="`cat ${SLICECFGDIR}/${wrkslice}`"
582  slicedev="`echo $wrkslice | sed 's|-|/|g'`"
583 
584  # Setup the partitions with gpart
585  setup_gpart_partitions "${disktag}" "${disk}" "${slicedev}" "${slicenum}" "${type}"
586
587};
588
589# Function which reads in the disk slice config, and performs it
590setup_disk_label()
591{
592  # We are ready to start setting up the label, lets read the config and do the actions
593  # First confirm that we have a valid WORKINGSLICES
594  if [ -z "${WORKINGSLICES}" ]; then
595    exit_err "ERROR: No slices were setup! Please report this to the maintainers"
596  fi
597
598  # Check that the slices we have did indeed get setup and gpart worked
599  for i in $WORKINGSLICES
600  do
601    disk="`echo $i | cut -d '-' -f 1`" 
602    pnum="`echo $i | cut -d '-' -f 2`" 
603    type="`echo $i | cut -d '-' -f 3`" 
604    if [ "$type" = "mbr" -a ! -e "${disk}s${pnum}" ] ; then
605      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
606    fi
607    if [ "$type" = "gpt" -a ! -e "${disk}p${pnum}" ] ; then
608      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
609    fi
610    if [ "$type" = "apm" -a ! -e "${disk}s${pnum}" ] ; then
611      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
612    fi
613    if [ "$type" = "gptslice" -a ! -e "${disk}p${pnum}" ] ; then
614      exit_err "ERROR: The partition ${i} doesn't exist! gpart failure!"
615    fi
616  done
617
618  # Setup some files which we'll be referring to
619  export LABELLIST="${TMPDIR}/workingLabels"
620  rm $LABELLIST >/dev/null 2>/dev/null
621
622  # Set our flag to determine if we've got a valid root partition in this setup
623  export FOUNDROOT="-1"
624
625  # Check if we are using a /boot partition
626  export USINGBOOTPART="1"
627 
628  # Set encryption on root check
629  export USINGENCROOT="1"
630 
631  # Make the tmp directory where we'll store FS info & mount-points
632  rm -rf ${PARTDIR} >/dev/null 2>/dev/null
633  mkdir -p ${PARTDIR} >/dev/null 2>/dev/null
634  rm -rf ${PARTDIR}-enc >/dev/null 2>/dev/null
635  mkdir -p ${PARTDIR}-enc >/dev/null 2>/dev/null
636
637  for i in $WORKINGSLICES
638  do
639    populate_disk_label "${i}"
640  done
641
642  # Check if we made a root partition
643  if [ "$FOUNDROOT" = "-1" ]
644  then
645    exit_err "ERROR: No root (/) partition specified!!"
646  fi
647
648  # Check if we made a root partition
649  if [ "$FOUNDROOT" = "1" -a "${USINGBOOTPART}" != "0" ]
650  then
651    exit_err "ERROR: (/) partition isn't first partition on disk!"
652  fi
653
654  if [ "${USINGENCROOT}" = "0" -a "${USINGBOOTPART}" != "0" ]
655  then
656    exit_err "ERROR: Can't encrypt (/) with no (/boot) partition!"
657  fi
658};
659
660check_fstab_mbr()
661{
662  local SLICE
663  local FSTAB
664
665  if [ -z "$2" ]
666  then
667        return 1
668  fi
669
670  SLICE="$1"
671  FSTAB="$2/etc/fstab"
672
673  if [ -f "${FSTAB}" ]
674  then
675    PARTLETTER=`echo "$SLICE" | sed -E 's|^.+([a-h])$|\1|'`
676
677    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1
678    if [ $? -eq 0 ]
679    then
680      if [ "${PARTLETTER}" = "a" ]
681      then
682        FOUNDROOT="0"
683      else
684        FOUNDROOT="1"
685      fi
686
687      ROOTIMAGE="1"
688
689      export FOUNDROOT
690      export ROOTIMAGE
691    fi
692
693    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1
694    if [ $? -eq 0 ]
695    then
696      if [ "${PARTLETTER}" = "a" ]
697      then
698        USINGBOOTPART="0"
699      else
700        exit_err "/boot partition must be first partition"
701      fi
702      export USINGBOOTPART
703    fi
704
705    return 0
706  fi
707
708  return 1
709};
710
711check_fstab_gpt()
712{
713  local SLICE
714  local FSTAB
715
716  if [ -z "$2" ]
717  then
718        return 1
719  fi
720
721  SLICE="$1"
722  FSTAB="$2/etc/fstab"
723
724  if [ -f "${FSTAB}" ]
725  then
726    PARTNUMBER=`echo "${SLICE}" | sed -E 's|^.+p([0-9]*)$|\1|'`
727
728    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/$' 2>&1
729    if [ $? -eq 0 ]
730    then
731      if [ "${PARTNUMBER}" = "2" ]
732      then
733        FOUNDROOT="0"
734      else
735        FOUNDROOT="1"
736      fi
737
738      ROOTIMAGE="1"
739
740      export FOUNDROOT
741      export ROOTIMAGE
742    fi
743
744    cat "${FSTAB}" | awk '{ print $2 }' | grep -qE '^/boot$' 2>&1
745    if [ $? -eq 0 ]
746    then
747      if [ "${PARTNUMBER}" = "2" ]
748      then
749        USINGBOOTPART="0"
750      else
751        exit_err "/boot partition must be first partition"
752      fi
753      export USINGBOOTPART
754    fi
755
756    return 0
757  fi
758
759
760  return 1
761};
762
763check_disk_layout()
764{
765  local SLICES
766  local TYPE
767  local DISK
768  local RES
769  local F
770
771  DISK="$1"
772  TYPE="MBR"
773
774  if [ -z "${DISK}" ]
775  then
776        return 1
777  fi
778
779  SLICES_MBR=`ls /dev/${DISK}s[1-4]*[a-h]* 2>/dev/null`
780  SLICES_GPT=`ls /dev/${DISK}p[0-9]* 2>/dev/null`
781  SLICES_SLICE=`ls /dev/${DISK}[a-h]* 2>/dev/null`
782
783  if [ -n "${SLICES_MBR}" ]
784  then
785    SLICES="${SLICES_MBR}"
786    TYPE="MBR"
787    RES=0
788  fi
789  if [ -n "${SLICES_GPT}" ]
790  then
791    SLICES="${SLICES_GPT}"
792    TYPE="GPT"
793    RES=0
794  fi
795  if [ -n "${SLICES_SLICE}" ]
796  then
797    SLICES="${SLICES_SLICE}"
798    TYPE="MBR"
799    RES=0
800  fi
801 
802  for slice in ${SLICES}
803  do
804    F=1
805    mount ${slice} /mnt 2>/dev/null
806    if [ $? -ne 0 ]
807    then
808      continue
809    fi
810
811    if [ "${TYPE}" = "MBR" ]
812    then
813          check_fstab_mbr "${slice}" "/mnt"
814      F="$?"
815
816    elif [ "${TYPE}" = "GPT" ]
817    then
818          check_fstab_gpt "${slice}" "/mnt"
819      F="$?"
820    fi
821
822    if [ ${F} -eq 0 ]
823    then
824      umount /mnt
825      break
826    fi
827
828    umount /mnt
829  done
830
831  return ${RES}
832};
Note: See TracBrowser for help on using the repository browser.