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