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