]> CyberLeo.Net >> Repos - FreeBSD/releng/9.1.git/blob - usr.sbin/pc-sysinstall/backend/functions-cleanup.sh
MFC r240315:
[FreeBSD/releng/9.1.git] / usr.sbin / pc-sysinstall / backend / functions-cleanup.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 which perform the final cleanup after an install
29
30 # Finishes up with ZFS setup before unmounting
31 zfs_cleanup_unmount()
32 {
33   # Loop through our FS and see if we have any ZFS partitions to cleanup
34   for PART in `ls ${PARTDIR}`
35   do
36     PARTDEV=`echo $PART | sed 's|-|/|g'`
37     PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
38     PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`"
39     ZPOOLNAME=$(get_zpool_name "${PARTDEV}")
40
41     if [ "$PARTFS" = "ZFS" ]
42     then
43       # Check if we have multiple zfs mounts specified
44       for ZMNT in `echo ${PARTMNT} | sed 's|,| |g'`
45       do
46         if [ "${ZMNT}" = "/" ]
47         then
48           # Make sure we haven't already added the zfs boot line when
49           # Creating a dedicated "/boot" partition
50           cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q "vfs.root.mountfrom=" 2>/dev/null
51           if [ $? -ne 0 ] ; then
52             echo "vfs.root.mountfrom=\"zfs:${ZPOOLNAME}/ROOT/default\"" >> ${FSMNT}/boot/loader.conf
53           fi
54           export FOUNDZFSROOT="${ZPOOLNAME}"
55         fi
56       done
57       FOUNDZFS="1"
58     fi
59   done
60
61   if [ -n "${FOUNDZFS}" ]
62   then
63     # Check if we need to add our ZFS flags to rc.conf, src.conf and loader.conf
64     cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'zfs_load="YES"' 2>/dev/null
65     if [ $? -ne 0 ]
66     then
67       echo 'zfs_load="YES"' >>${FSMNT}/boot/loader.conf
68     fi
69     cat ${FSMNT}/etc/rc.conf 2>/dev/null | grep -q 'zfs_enable="YES"' 2>/dev/null
70     if [ $? -ne 0 ]
71     then
72       echo 'zfs_enable="YES"' >>${FSMNT}/etc/rc.conf
73     fi
74
75     sleep 2
76     # Copy over any ZFS cache data
77     cp /boot/zfs/* ${FSMNT}/boot/zfs/
78
79     # Copy the hostid so that our zfs cache works
80     cp /etc/hostid ${FSMNT}/etc/hostid
81   fi
82
83   # Loop through our FS and see if we have any ZFS partitions to cleanup
84   for PART in `ls ${PARTDIR}`
85   do
86     PARTDEV=`echo $PART | sed 's|-|/|g'`
87     PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
88     PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`"
89     PARTENC="`cat ${PARTDIR}/${PART} | cut -d '#' -f 3`"
90     ZPOOLNAME=$(get_zpool_name "${PARTDEV}")
91
92     if [ "$PARTFS" = "ZFS" ]
93     then
94
95       # Create a list of zpool names we can export
96       echo $ZPOOLEXPORTS | grep -q "$ZPOOLNAME "
97       if [ $? -ne 0 ] ; then
98         export ZPOOLEXPORTS="$ZPOOLNAME $ZPOOLEXPORTS"
99       fi
100
101       # Check if we have multiple zfs mounts specified
102       for ZMNT in `echo ${PARTMNT} | sed 's|,| |g'`
103       do
104         ZMNT="`echo $ZMNT | cut -d '(' -f 1`"
105         PARTMNTREV="${ZMNT} ${PARTMNTREV}"
106       done
107
108       for ZMNT in ${PARTMNTREV}
109       do
110         if [ "${ZMNT}" = "/" ] ; then continue ; fi
111         # Some ZFS like /swap aren't mounted, and dont need unmounting
112         mount | grep -q "${FSMNT}${ZMNT}"
113         if [ $? -eq 0 ] ; then
114           rc_halt "zfs unmount ${ZPOOLNAME}${ZMNT}"
115           rc_halt "zfs set mountpoint=${ZMNT} ${ZPOOLNAME}${ZMNT}"
116         fi
117         sleep 2
118       done
119     fi
120   done
121
122 };
123
124 # Function which performs the specific setup for using a /boot partition
125 setup_dedicated_boot_part()
126 {
127   ROOTFS="${1}"
128   ROOTFSTYPE="${2}"
129   BOOTFS="${3}"
130   BOOTMNT="${4}"
131
132   # Set the root mount in loader.conf
133   echo "vfs.root.mountfrom=\"${ROOTFSTYPE}:${ROOTFS}\"" >> ${FSMNT}/boot/loader.conf
134   rc_halt "mkdir -p ${FSMNT}/${BOOTMNT}/boot"
135   rc_halt "mv ${FSMNT}/boot/* ${FSMNT}${BOOTMNT}/boot/"
136   rc_halt "mv ${FSMNT}${BOOTMNT}/boot ${FSMNT}/boot/"
137   rc_halt "umount ${BOOTFS}"
138   rc_halt "mount ${BOOTFS} ${FSMNT}${BOOTMNT}"
139   rc_halt "rmdir ${FSMNT}/boot"
140
141   # Strip the '/' from BOOTMNT before making symlink
142   BOOTMNTNS="`echo ${BOOTMNT} | sed 's|/||g'`"
143   rc_halt "chroot ${FSMNT} ln -s ${BOOTMNTNS}/boot /boot"
144   
145 };
146
147 # Function which creates the /etc/fstab for the installed system
148 setup_fstab()
149 {
150   FSTAB="${FSMNT}/etc/fstab"
151   rm ${FSTAB} >/dev/null 2>/dev/null
152
153   # Create the header
154   echo "# Device                Mountpoint              FStype          Options Dump Pass" >> ${FSTAB}
155
156   # Loop through the partitions, and start creating /etc/fstab
157   for PART in `ls ${PARTDIR}`
158   do
159     PARTDEV=`echo $PART | sed 's|-|/|g'`
160     PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
161     PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`"
162     PARTENC="`cat ${PARTDIR}/${PART} | cut -d '#' -f 3`"
163     PARTLABEL="`cat ${PARTDIR}/${PART} | cut -d '#' -f 4`"
164
165     # Unset EXT
166     EXT=""
167
168     # Set mount options for file-systems
169     case $PARTFS in
170       UFS+J) MNTOPTS="rw,noatime,async" ;;
171       SWAP) MNTOPTS="sw" ;;
172       *) MNTOPTS="rw,noatime" ;;
173     esac
174
175
176     # Figure out if we are using a glabel, or the raw name for this entry
177     if [ -n "${PARTLABEL}" ]
178     then
179       DEVICE="label/${PARTLABEL}"
180     else
181       # Check if using encryption 
182       if [ "${PARTENC}" = "ON" ] ; then
183         EXT=".eli"
184       fi
185
186       if [ "${PARTFS}" = "UFS+J" ] ; then
187         EXT="${EXT}.journal"
188       fi
189       DEVICE="${PARTDEV}${EXT}"
190     fi
191
192
193     # Set our ROOTFSTYPE for loader.conf if necessary
194     check_for_mount "${PARTMNT}" "/"
195     if [ $? -eq 0 ] ; then
196       if [ "${PARTFS}" = "ZFS" ] ; then
197         ROOTFSTYPE="zfs"
198         ZPOOLNAME=$(get_zpool_name "${PARTDEV}")
199         ROOTFS="${ZPOOLNAME}/ROOT/default"
200       else
201         ROOTFS="${DEVICE}"
202         ROOTFSTYPE="ufs"
203       fi
204     fi
205
206     # Only create non-zfs partitions
207     if [ "${PARTFS}" != "ZFS" ]
208     then
209
210       # Make sure geom_journal is loaded
211       if [ "${PARTFS}" = "UFS+J" ] ; then
212         setup_gjournal
213       fi
214
215       # Save the BOOTFS for call at the end
216       if [ "${PARTMNT}" = "/boot" ] ; then
217         BOOTFS="${PARTDEV}${EXT}"
218         BOOTMNT="${BOOT_PART_MOUNT}"
219         PARTMNT="${BOOTMNT}"
220       fi
221
222       # Echo out the fstab entry now
223       if [ "${PARTFS}" = "SWAP" ]
224       then
225         echo "/dev/${DEVICE}    none            swap    ${MNTOPTS}      0       0" >> ${FSTAB}
226       else
227         echo "/dev/${DEVICE}    ${PARTMNT}              ufs     ${MNTOPTS}      1       1" >> ${FSTAB}
228       fi
229
230     fi # End of ZFS Check
231   done
232
233   # Setup some specific PC-BSD fstab options
234   if [ "$INSTALLTYPE" != "FreeBSD" ]
235   then
236     echo "procfs                        /proc                   procfs          rw              0       0" >> ${FSTAB}
237     echo "linprocfs             /compat/linux/proc      linprocfs       rw              0       0" >> ${FSTAB}
238   fi
239
240   # If we have a dedicated /boot, run the post-install setup of it now
241   if [ ! -z "${BOOTMNT}" ] ; then 
242     setup_dedicated_boot_part "${ROOTFS}" "${ROOTFSTYPE}" "${BOOTFS}" "${BOOTMNT}"
243   fi
244
245 };
246
247 # Setup our disk mirroring with gmirror
248 setup_gmirror()
249 {
250   cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_mirror_load="YES"' 2>/dev/null
251   if [ $? -ne 0 ]
252   then
253     echo 'geom_mirror_load="YES"' >>${FSMNT}/boot/loader.conf
254   fi
255
256 };
257
258 # Function which saves geli keys and sets up loading of them at boot
259 setup_geli_loading()
260 {
261
262   # Make our keys dir
263   mkdir -p ${FSMNT}/boot/keys >/dev/null 2>/dev/null
264
265   cd ${GELIKEYDIR}
266   for KEYFILE in `ls`
267   do
268      # Figure out the partition name based on keyfile name removing .key
269      PART="`echo ${KEYFILE} | cut -d '.' -f 1`"
270      PARTDEV="`echo ${PART} | sed 's|-|/|g'`"
271      PARTNAME="`echo ${PART} | sed 's|-dev-||g'`"
272
273      rc_halt "geli configure -b ${PARTDEV}"
274
275      # If no passphrase, setup key files
276      if [ ! -e "${PARTDIR}-enc/${PART}-encpass" ] ; then
277        echo "geli_${PARTNAME}_keyfile0_load=\"YES\"" >> ${FSMNT}/boot/loader.conf 
278        echo "geli_${PARTNAME}_keyfile0_type=\"${PARTNAME}:geli_keyfile0\"" >> ${FSMNT}/boot/loader.conf 
279        echo "geli_${PARTNAME}_keyfile0_name=\"/boot/keys/${PARTNAME}.key\"" >> ${FSMNT}/boot/loader.conf 
280
281        # Copy the key to the disk
282        rc_halt "cp ${GELIKEYDIR}/${KEYFILE} ${FSMNT}/boot/keys/${PARTNAME}.key"
283      fi
284
285   done
286
287   # Make sure we have geom_eli set to load at boot
288   cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_eli_load="YES"' 2>/dev/null
289   if [ $? -ne 0 ]
290   then
291     echo 'geom_eli_load="YES"' >>${FSMNT}/boot/loader.conf
292   fi
293
294 };
295
296
297 # Function to generate a random hostname if none was specified
298 gen_hostname()
299 {
300   RAND="`jot -r 1 1 9000`"
301
302   if [ "$INSTALLTYPE" = "FreeBSD" ]
303   then
304     VAL="freebsd-${RAND}" 
305   else
306     VAL="pcbsd-${RAND}" 
307   fi
308
309   export VAL
310
311 };
312
313 # Function which sets up the hostname for the system
314 setup_hostname()
315 {
316
317   get_value_from_cfg hostname
318   HOSTNAME="${VAL}"
319
320   # If we don't have a hostname, make one up
321   if [ -z "${HOSTNAME}" ]
322   then
323     gen_hostname
324     HOSTNAME="${VAL}"
325   fi
326
327   # Clean up any saved hostname
328   cat ${FSMNT}/etc/rc.conf | grep -v "hostname=" >${FSMNT}/etc/rc.conf.new
329   mv ${FSMNT}/etc/rc.conf.new ${FSMNT}/etc/rc.conf
330
331   # Set the hostname now
332   echo_log "Setting hostname: ${HOSTNAME}"
333   echo "hostname=\"${HOSTNAME}\"" >> ${FSMNT}/etc/rc.conf
334   sed -i -e "s|my.domain|${HOSTNAME} ${HOSTNAME}|g" ${FSMNT}/etc/hosts
335
336 };
337
338
339 # Check and make sure geom_journal is enabled on the system
340 setup_gjournal()
341 {
342
343   # Make sure we have geom_journal set to load at boot
344   cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_journal_load="YES"' 2>/dev/null
345   if [ $? -ne 0 ]
346   then
347     echo 'geom_journal_load="YES"' >>${FSMNT}/boot/loader.conf
348   fi
349
350 };
351
352 # Function which sets the root password from the install config
353 set_root_pw()
354 {
355   # Get the plaintext string
356   get_value_from_cfg_with_spaces rootPass
357   local PW="${VAL}"
358
359   # Get the encrypted string
360   get_value_from_cfg_with_spaces rootEncPass
361   local ENCPW="${VAL}"
362
363   # If we don't have a root pass, return
364   if [ -z "${PW}" -a -z "${ENCPW}" ] ; then return 0 ; fi
365
366   echo_log "Setting root password"
367
368   # Check if setting plaintext password
369   if [ -n "${PW}" ] ; then
370     echo "${PW}" > ${FSMNT}/.rootpw
371     run_chroot_cmd "cat /.rootpw | pw usermod root -h 0"
372     rc_halt "rm ${FSMNT}/.rootpw"
373   fi
374
375   # Check if setting encrypted password
376   if [ -n "${ENCPW}" ] ; then
377     echo "${ENCPW}" > ${FSMNT}/.rootpw
378     run_chroot_cmd "cat /.rootpw | pw usermod root -H 0"
379     rc_halt "rm ${FSMNT}/.rootpw"
380   fi
381
382 };
383
384
385 run_final_cleanup()
386 {
387   # Check if we need to run any gmirror setup
388   ls ${MIRRORCFGDIR}/* >/dev/null 2>/dev/null
389   if [ $? -eq 0 ]
390   then
391     # Lets setup gmirror now
392     setup_gmirror
393   fi
394
395   # Check if we need to save any geli keys
396   ls ${GELIKEYDIR}/* >/dev/null 2>/dev/null
397   if [ $? -eq 0 ]
398   then
399     # Lets setup geli loading
400     setup_geli_loading
401   fi
402
403   # Set a hostname on the install system
404   setup_hostname
405
406   # Set the root_pw if it is specified
407   set_root_pw
408
409   # Generate the fstab for the installed system
410   setup_fstab
411 };