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