3 # Copyright (c) 2010 iXsystems, Inc. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
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.
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
28 # Functions which perform the final cleanup after an install
30 # Finishes up with ZFS setup before unmounting
33 # Loop through our FS and see if we have any ZFS partitions to cleanup
34 for PART in `ls ${PARTDIR}`
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}")
41 if [ "$PARTFS" = "ZFS" ]
43 # Check if we have multiple zfs mounts specified
44 for ZMNT in `echo ${PARTMNT} | sed 's|,| |g'`
46 if [ "${ZMNT}" = "/" ]
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
54 export FOUNDZFSROOT="${ZPOOLNAME}"
61 if [ -n "${FOUNDZFS}" ]
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
67 echo 'zfs_load="YES"' >>${FSMNT}/boot/loader.conf
69 cat ${FSMNT}/etc/rc.conf 2>/dev/null | grep -q 'zfs_enable="YES"' 2>/dev/null
72 echo 'zfs_enable="YES"' >>${FSMNT}/etc/rc.conf
76 # Copy over any ZFS cache data
77 cp /boot/zfs/* ${FSMNT}/boot/zfs/
79 # Copy the hostid so that our zfs cache works
80 cp /etc/hostid ${FSMNT}/etc/hostid
83 # Loop through our FS and see if we have any ZFS partitions to cleanup
84 for PART in `ls ${PARTDIR}`
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}")
92 if [ "$PARTFS" = "ZFS" ]
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"
101 # Check if we have multiple zfs mounts specified
102 for ZMNT in `echo ${PARTMNT} | sed 's|,| |g'`
104 PARTMNTREV="${ZMNT} ${PARTMNTREV}"
107 for ZMNT in ${PARTMNTREV}
109 if [ "${ZMNT}" != "/" ]
111 rc_halt "zfs set mountpoint=${ZMNT} ${ZPOOLNAME}${ZMNT}"
112 rc_halt "zfs unmount ${ZPOOLNAME}${ZMNT}"
121 # Function which performs the specific setup for using a /boot partition
122 setup_dedicated_boot_part()
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"
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"
144 # Function which creates the /etc/fstab for the installed system
147 FSTAB="${FSMNT}/etc/fstab"
148 rm ${FSTAB} >/dev/null 2>/dev/null
151 echo "# Device Mountpoint FStype Options Dump Pass" >> ${FSTAB}
153 # Loop through the partitions, and start creating /etc/fstab
154 for PART in `ls ${PARTDIR}`
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`"
165 # Set mount options for file-systems
167 UFS+J) MNTOPTS="rw,noatime,async" ;;
168 SWAP) MNTOPTS="sw" ;;
169 *) MNTOPTS="rw,noatime" ;;
173 # Figure out if we are using a glabel, or the raw name for this entry
174 if [ -n "${PARTLABEL}" ]
176 DEVICE="label/${PARTLABEL}"
178 # Check if using encryption
179 if [ "${PARTENC}" = "ON" ] ; then
183 if [ "${PARTFS}" = "UFS+J" ] ; then
186 DEVICE="${PARTDEV}${EXT}"
190 # Set our ROOTFSTYPE for loader.conf if necessary
191 check_for_mount "${PARTMNT}" "/"
192 if [ $? -eq 0 ] ; then
193 if [ "${PARTFS}" = "ZFS" ] ; then
195 XPOOLNAME=$(get_zpool_name "${PARTDEV}")
196 ROOTFS="${ZPOOLNAME}"
203 # Only create non-zfs partitions
204 if [ "${PARTFS}" != "ZFS" ]
207 # Make sure geom_journal is loaded
208 if [ "${PARTFS}" = "UFS+J" ] ; then
212 # Save the BOOTFS for call at the end
213 if [ "${PARTMNT}" = "/boot" ] ; then
214 BOOTFS="${PARTDEV}${EXT}"
215 BOOTMNT="${BOOT_PART_MOUNT}"
219 # Echo out the fstab entry now
220 if [ "${PARTFS}" = "SWAP" ]
222 echo "/dev/${DEVICE} none swap ${MNTOPTS} 0 0" >> ${FSTAB}
224 echo "/dev/${DEVICE} ${PARTMNT} ufs ${MNTOPTS} 1 1" >> ${FSTAB}
227 fi # End of ZFS Check
230 # Setup some specific PC-BSD fstab options
231 if [ "$INSTALLTYPE" != "FreeBSD" ]
233 echo "procfs /proc procfs rw 0 0" >> ${FSTAB}
234 echo "linprocfs /compat/linux/proc linprocfs rw 0 0" >> ${FSTAB}
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}"
244 # Setup our disk mirroring with gmirror
247 cat ${FSMNT}/boot/loader.conf 2>/dev/null | grep -q 'geom_mirror_load="YES"' 2>/dev/null
250 echo 'geom_mirror_load="YES"' >>${FSMNT}/boot/loader.conf
255 # Function which saves geli keys and sets up loading of them at boot
260 mkdir -p ${FSMNT}/boot/keys >/dev/null 2>/dev/null
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'`"
270 rc_halt "geli configure -b ${PARTDEV}"
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
278 # Copy the key to the disk
279 rc_halt "cp ${GELIKEYDIR}/${KEYFILE} ${FSMNT}/boot/keys/${PARTNAME}.key"
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
288 echo 'geom_eli_load="YES"' >>${FSMNT}/boot/loader.conf
294 # Function to generate a random hostname if none was specified
297 RAND="`jot -r 1 1 9000`"
299 if [ "$INSTALLTYPE" = "FreeBSD" ]
301 VAL="freebsd-${RAND}"
310 # Function which sets up the hostname for the system
314 get_value_from_cfg hostname
317 # If we don't have a hostname, make one up
318 if [ -z "${HOSTNAME}" ]
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
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
336 # Check and make sure geom_journal is enabled on the system
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
344 echo 'geom_journal_load="YES"' >>${FSMNT}/boot/loader.conf
349 # Function which sets the root password from the install config
352 # Get the plaintext string
353 get_value_from_cfg_with_spaces rootPass
356 # Get the encrypted string
357 get_value_from_cfg_with_spaces rootEncPass
360 # If we don't have a root pass, return
361 if [ -z "${PW}" -a -z "${ENCPW}" ] ; then return 0 ; fi
363 echo_log "Setting root password"
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"
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"
384 # Check if we need to run any gmirror setup
385 ls ${MIRRORCFGDIR}/* >/dev/null 2>/dev/null
388 # Lets setup gmirror now
392 # Check if we need to save any geli keys
393 ls ${GELIKEYDIR}/* >/dev/null 2>/dev/null
396 # Lets setup geli loading
400 # Set a hostname on the install system
403 # Set the root_pw if it is specified
406 # Generate the fstab for the installed system