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