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