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