1cd88b886SDevin Teske#!/bin/sh
2cd88b886SDevin Teske#-
3cd88b886SDevin Teske# Copyright (c) 2013 Allan Jude
4cd88b886SDevin Teske# Copyright (c) 2013 Devin Teske
5cd88b886SDevin Teske# All rights reserved.
6cd88b886SDevin Teske#
7cd88b886SDevin Teske# Redistribution and use in source and binary forms, with or without
8cd88b886SDevin Teske# modification, are permitted provided that the following conditions
9cd88b886SDevin Teske# are met:
10cd88b886SDevin Teske# 1. Redistributions of source code must retain the above copyright
11cd88b886SDevin Teske#    notice, this list of conditions and the following disclaimer.
12cd88b886SDevin Teske# 2. Redistributions in binary form must reproduce the above copyright
13cd88b886SDevin Teske#    notice, this list of conditions and the following disclaimer in the
14cd88b886SDevin Teske#    documentation and/or other materials provided with the distribution.
15cd88b886SDevin Teske#
16cd88b886SDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17cd88b886SDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18cd88b886SDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19cd88b886SDevin Teske# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20cd88b886SDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21cd88b886SDevin Teske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22cd88b886SDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23cd88b886SDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24cd88b886SDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25cd88b886SDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26cd88b886SDevin Teske# SUCH DAMAGE.
27cd88b886SDevin Teske#
28cd88b886SDevin Teske# $FreeBSD$
29cd88b886SDevin Teske#
30cd88b886SDevin Teske############################################################ INCLUDES
31cd88b886SDevin Teske
32cd88b886SDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig"
33cd88b886SDevin Teske. $BSDCFG_SHARE/common.subr || exit 1
34cd88b886SDevin Teskef_dprintf "%s: loading includes..." "$0"
35cd88b886SDevin Teskef_include $BSDCFG_SHARE/device.subr
36cd88b886SDevin Teskef_include $BSDCFG_SHARE/dialog.subr
37cd88b886SDevin Teskef_include $BSDCFG_SHARE/password/password.subr
38cd88b886SDevin Teskef_include $BSDCFG_SHARE/variable.subr
39cd88b886SDevin Teske
40cd88b886SDevin Teske############################################################ CONFIGURATION
41cd88b886SDevin Teske
42cd88b886SDevin Teske#
43cd88b886SDevin Teske# Default name of the boot-pool
44cd88b886SDevin Teske#
45cd88b886SDevin Teske: ${ZFSBOOT_POOL_NAME:=zroot}
46cd88b886SDevin Teske
47cd88b886SDevin Teske#
48cd88b886SDevin Teske# Default name for the boot environment parent dataset
49cd88b886SDevin Teske#
50*67635c19SDevin Teske: ${ZFSBOOT_BEROOT_NAME:=ROOT}
51cd88b886SDevin Teske
52cd88b886SDevin Teske#
53cd88b886SDevin Teske# Default name for the primany boot environment
54cd88b886SDevin Teske#
55cd88b886SDevin Teske: ${ZFSBOOT_BOOTFS_NAME:=default}
56cd88b886SDevin Teske
57cd88b886SDevin Teske#
58cd88b886SDevin Teske# Default Virtual Device (vdev) type to create
59cd88b886SDevin Teske#
60cd88b886SDevin Teske: ${ZFSBOOT_VDEV_TYPE:=stripe}
61cd88b886SDevin Teske
62cd88b886SDevin Teske#
63cd88b886SDevin Teske# Should we use gnop(8) to configure a transparent mapping to 4K sectors?
64cd88b886SDevin Teske#
65cd88b886SDevin Teske: ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:=1}
66cd88b886SDevin Teske
67cd88b886SDevin Teske#
68cd88b886SDevin Teske# Should we use geli(8) to encrypt the drives?
69cd88b886SDevin Teske#
70cd88b886SDevin Teske: ${ZFSBOOT_GELI_ENCRYPTION:=}
71cd88b886SDevin Teske
72cd88b886SDevin Teske#
73cd88b886SDevin Teske# Default name the unencrypted pool when using geli(8) to encrypt the drives
74cd88b886SDevin Teske#
75cd88b886SDevin Teske: ${ZFSBOOT_GELI_POOL_NAME:=bootpool}
76cd88b886SDevin Teske
77cd88b886SDevin Teske#
78cd88b886SDevin Teske# Default size for the unencrypted boot pool when using geli(8)
79cd88b886SDevin Teske#
80cd88b886SDevin Teske: ${ZFSBOOT_GELI_BOOT_SIZE:=2g}
81cd88b886SDevin Teske
82cd88b886SDevin Teske#
83cd88b886SDevin Teske# Default path to the geli(8) keyfile used in drive encryption
84cd88b886SDevin Teske#
85cd88b886SDevin Teske: ${ZFSBOOT_GELI_KEY_FILE:=/boot/encryption.key}
86cd88b886SDevin Teske
87cd88b886SDevin Teske#
88cd88b886SDevin Teske# Default disks to use (always empty unless being scripted)
89cd88b886SDevin Teske#
90cd88b886SDevin Teske: ${ZFSBOOT_DISKS:=}
91cd88b886SDevin Teske
92cd88b886SDevin Teske#
93cd88b886SDevin Teske# Default partitioning scheme to use on disks
94cd88b886SDevin Teske#
95cd88b886SDevin Teske: ${ZFSBOOT_PARTITION_SCHEME:=GPT}
96cd88b886SDevin Teske
97cd88b886SDevin Teske#
98cd88b886SDevin Teske# How much swap to put on each block device in the boot zpool
99cd88b886SDevin Teske# NOTE: Value passed to gpart(8); which supports SI unit suffixes.
100cd88b886SDevin Teske#
101cd88b886SDevin Teske: ${ZFSBOOT_SWAP_SIZE:=2g}
102cd88b886SDevin Teske
103cd88b886SDevin Teske#
104cd88b886SDevin Teske# Default ZFS layout for root zpool
105cd88b886SDevin Teske#
106cd88b886SDevin Teske# NOTE: Requires /tmp, /var/tmp, /$ZFSBOOT_BOOTFS_NAME/$ZFSBOOT_BOOTFS_NAME
107cd88b886SDevin Teske# NOTE: Anything after pound/hash character [#] is ignored as a comment.
108cd88b886SDevin Teske#
109cd88b886SDevin Teskef_isset ZFSBOOT_DATASETS || ZFSBOOT_DATASETS="
110cd88b886SDevin Teske	# DATASET	OPTIONS (comma or space separated; or both)
111cd88b886SDevin Teske
112cd88b886SDevin Teske	# Boot Environment [BE] root and default boot dataset
113cd88b886SDevin Teske	/$ZFSBOOT_BEROOT_NAME				mountpoint=none
114cd88b886SDevin Teske	/$ZFSBOOT_BEROOT_NAME/$ZFSBOOT_BOOTFS_NAME	mountpoint=/
115cd88b886SDevin Teske
116cd88b886SDevin Teske	# Compress /tmp, allow exec but not setuid
117cd88b886SDevin Teske	/tmp		mountpoint=/tmp,compression=lz4,exec=on,setuid=off
118cd88b886SDevin Teske
119cd88b886SDevin Teske	# Don't mount /usr so that 'base' files go to the BEROOT
120cd88b886SDevin Teske	/usr		mountpoint=/usr,canmount=off
121cd88b886SDevin Teske
122cd88b886SDevin Teske	# Home directories separated so they are common to all BEs
123cd88b886SDevin Teske	/usr/home	setuid=off
124cd88b886SDevin Teske
125cd88b886SDevin Teske	# Ports tree
126cd88b886SDevin Teske	/usr/ports		compression=lz4,setuid=off
127cd88b886SDevin Teske	/usr/ports/distfiles	compression=off,exec=off,setuid=off
128cd88b886SDevin Teske	/usr/ports/packages	compression=off,exec=off,setuid=off
129cd88b886SDevin Teske
130cd88b886SDevin Teske	# Source tree (compressed)
131cd88b886SDevin Teske	/usr/src	compression=lz4,exec=off,setuid=off
132cd88b886SDevin Teske	/usr/obj	# Object files
133cd88b886SDevin Teske
134cd88b886SDevin Teske	# Create /var and friends
135cd88b886SDevin Teske	/var		mountpoint=/var
136cd88b886SDevin Teske	/var/crash	compression=lz4,exec=off,setuid=off
137cd88b886SDevin Teske	/var/db		exec=off,setuid=off
138cd88b886SDevin Teske	/var/empty	exec=off,setuid=off
139cd88b886SDevin Teske	/var/log	compression=lz4,exec=off,setuid=off
140cd88b886SDevin Teske	/var/mail	compression=lz4,exec=off,setuid=off
141cd88b886SDevin Teske	/var/run	exec=off,setuid=off
142cd88b886SDevin Teske	/var/tmp	compression=lz4,exec=on,setuid=off
143cd88b886SDevin Teske" # END-QUOTE
144cd88b886SDevin Teske
145cd88b886SDevin Teske############################################################ GLOBALS
146cd88b886SDevin Teske
147cd88b886SDevin Teske#
148cd88b886SDevin Teske# Strings that should be moved to an i18n file and loaded with f_include_lang()
149cd88b886SDevin Teske#
150cd88b886SDevin Teskehline_alnum_arrows_punc_tab_enter="Use alnum, arrows, punctuation, TAB or ENTER"
151cd88b886SDevin Teskehline_arrows_space_tab_enter="Use arrows, SPACE, TAB or ENTER"
152cd88b886SDevin Teskehline_arrows_tab_enter="Press arrows, TAB or ENTER"
153cd88b886SDevin Teskemsg_back="Back"
154cd88b886SDevin Teskemsg_cancel="Cancel"
155cd88b886SDevin Teskemsg_change="Change Selection"
156cd88b886SDevin Teskemsg_configure_options="Configure Options:"
157cd88b886SDevin Teskemsg_create="Install"
158cd88b886SDevin Teskemsg_create_desc="Proceed with Installation"
159cd88b886SDevin Teskemsg_create_help="Create ZFS boot pool with displayed options"
160cd88b886SDevin Teskemsg_detailed_disk_info="gpart(8) show %s:\n%s\n\ncamcontrol(8) inquiry %s:\n%s\n\n\ncamcontrol(8) identify %s:\n%s\n"
161cd88b886SDevin Teskemsg_disk_info="Disk Info"
162cd88b886SDevin Teskemsg_disk_info_help="Get detailed information on disk device(s)"
163cd88b886SDevin Teskemsg_disks_to_use="Disks To Use"
164cd88b886SDevin Teskemsg_disks_to_use_help="Choose which disks to use for the Virtual Device (Required)"
165cd88b886SDevin Teskemsg_force_4k_sectors="Force 4K Sectors?"
166cd88b886SDevin Teskemsg_force_4k_sectors_help="Use gnop(8) to configure forced 4K sector alignment"
167cd88b886SDevin Teskemsg_freebsd_installer="FreeBSD Installer"
168cd88b886SDevin Teskemsg_geli_encryption="Encrypt Disks?"
169cd88b886SDevin Teskemsg_geli_encryption_help="Use geli(8) to encrypt all data partitions"
170cd88b886SDevin Teskemsg_geli_password="Enter a strong passphrase, used to protect your encryption keys. You will be required to enter this passphrase each time the system is booted"
171cd88b886SDevin Teskemsg_geli_setup="Initializing encryption on the selected disks, this will take several seconds per disk"
172cd88b886SDevin Teskemsg_invalid_virtual_device_type="Invalid Virtual Device type \`%s'"
173cd88b886SDevin Teskemsg_invalid_virtual_device_type_help="Select another Virtual Device type or Cancel to\nreturn to the ZFS menu. From there you can select\nmore disks or rescan for additional devices."
174cd88b886SDevin Teskemsg_last_chance_are_you_sure="Last Chance! Are you sure you want to destroy the current contents of the following disks:\n%s"
175cd88b886SDevin Teskemsg_last_chance_are_you_sure_color="\\\\ZrLast Chance!\\\\ZR Are you \\\\Z1sure\\\\Zn you want to \\\\Zr\\\\Z1destroy\\\\Zn the current contents of the following disks:\n%s"
176cd88b886SDevin Teskemsg_mirror_desc="Mirror - n-Way Mirroring"
177cd88b886SDevin Teskemsg_mirror_help="[2+ Disks] Mirroring provides the best performance, but the least storage"
178cd88b886SDevin Teskemsg_no="NO"
179cd88b886SDevin Teskemsg_no_disks_present_to_configure="No disk(s) present to configure"
180cd88b886SDevin Teskemsg_no_disks_selected="No disks selected."
181cd88b886SDevin Teskemsg_not_enough_disks_selected="Not enough disks selected. (%u < %u wanted)"
182cd88b886SDevin Teskemsg_ok="OK"
183cd88b886SDevin Teskemsg_partition_scheme="Partition Scheme"
184cd88b886SDevin Teskemsg_partition_scheme_help="Toggle between GPT and MBR partitioning schemes"
185cd88b886SDevin Teskemsg_please_enter_a_name_for_your_zpool="Please enter a name for your zpool:"
186cd88b886SDevin Teskemsg_please_enter_amount_of_swap_space="Please enter amount of swap space (SI-Unit suffixes\nrecommended; e.g., \`2g' for 2 Gigabytes):"
187cd88b886SDevin Teskemsg_please_select_one_or_more_disks="Please select one or more disks to create a zpool:"
188cd88b886SDevin Teskemsg_pool_name="Pool Name"
189cd88b886SDevin Teskemsg_pool_name_cannot_be_empty="Pool name cannot be empty."
190cd88b886SDevin Teskemsg_pool_name_help="Customize the name of the zpool to be created (Required)"
191cd88b886SDevin Teskemsg_processing_selection="Processing selection..."
192cd88b886SDevin Teskemsg_raidz1_desc="RAID-Z1 - Single Redundant RAID"
193cd88b886SDevin Teskemsg_raidz1_help="[3+ Disks] Withstand failure of 1 disk. Recommended for: 3, 5 or 9 disks"
194cd88b886SDevin Teskemsg_raidz2_desc="RAID-Z2 - Double Redundant RAID"
195cd88b886SDevin Teskemsg_raidz2_help="[4+ Disks] Withstand failure of 2 disks. Recommended for: 4, 6 or 10 disks"
196cd88b886SDevin Teskemsg_raidz3_desc="RAID-Z3 - Triple Redundant RAID"
197cd88b886SDevin Teskemsg_raidz3_help="[5+ Disks] Withstand failure of 3 disks. Recommended for: 5, 7 or 11 disks"
198cd88b886SDevin Teskemsg_rescan_devices="Rescan Devices"
199cd88b886SDevin Teskemsg_rescan_devices_help="Scan for device changes"
200cd88b886SDevin Teskemsg_select="Select"
201cd88b886SDevin Teskemsg_select_a_disk_device="Select a disk device"
202cd88b886SDevin Teskemsg_select_virtual_device_type="Select Virtual Device type:"
203cd88b886SDevin Teskemsg_stripe_desc="Stripe - No Redundancy"
204cd88b886SDevin Teskemsg_stripe_help="[1+ Disks] Striping provides maximum storage but no redundancy"
205cd88b886SDevin Teskemsg_swap_size="Swap Size"
206cd88b886SDevin Teskemsg_swap_size_help="Customize how much swap space is allocated to each selected disk"
207cd88b886SDevin Teskemsg_these_disks_are_too_small="These disks are too small given the amount of requested\nswap (%s) and/or GELI (%s) partitions, which would take\n50%% or more (not recommended) of each of the following\nselected disk devices:\n\n  %s\n\nRecommend changing partition size(s) and/or selecting a\ndifferent set of devices."
208cd88b886SDevin Teskemsg_yes="YES"
209cd88b886SDevin Teskemsg_zfs_configuration="ZFS Configuration"
210cd88b886SDevin Teskemsg_zfs_vdev_type="ZFS VDev Type"
211cd88b886SDevin Teskemsg_zfs_vdev_type_help="Select type of ZFS Virtual Device to create"
212cd88b886SDevin Teske
213cd88b886SDevin Teske############################################################ FUNCTIONS
214cd88b886SDevin Teske
215cd88b886SDevin Teske# dialog_menu_main
216cd88b886SDevin Teske#
217cd88b886SDevin Teske# Display the dialog(1)-based application main menu.
218cd88b886SDevin Teske#
219cd88b886SDevin Teskedialog_menu_main()
220cd88b886SDevin Teske{
221cd88b886SDevin Teske	local title="$DIALOG_TITLE"
222cd88b886SDevin Teske	local btitle="$DIALOG_BACKTITLE"
223cd88b886SDevin Teske	local prompt="$msg_configure_options"
224cd88b886SDevin Teske	local force4k="$msg_no"
225cd88b886SDevin Teske	local usegeli="$msg_no"
226cd88b886SDevin Teske	[ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && force4k="$msg_yes"
227cd88b886SDevin Teske	[ "$ZFSBOOT_GELI_ENCRYPTION" ] && usegeli="$msg_yes"
228cd88b886SDevin Teske	local menu_list="
229cd88b886SDevin Teske		'>>> $msg_create'         '$msg_create_desc'
230cd88b886SDevin Teske		                          '$msg_create_help'
231cd88b886SDevin Teske		'- $msg_rescan_devices'   '*'
232cd88b886SDevin Teske		                          '$msg_rescan_devices_help'
233cd88b886SDevin Teske		'- $msg_disk_info'        '*'
234cd88b886SDevin Teske		                          '$msg_disk_info_help'
235cd88b886SDevin Teske		'1 $msg_pool_name'        '$ZFSBOOT_POOL_NAME'
236cd88b886SDevin Teske		                          '$msg_pool_name_help'
237cd88b886SDevin Teske		'2 $msg_disks_to_use'     '$ZFSBOOT_DISKS'
238cd88b886SDevin Teske		                          '$msg_disks_to_use_help'
239cd88b886SDevin Teske		'3 $msg_zfs_vdev_type'    '$ZFSBOOT_VDEV_TYPE'
240cd88b886SDevin Teske		                          '$msg_zfs_vdev_type_help'
241cd88b886SDevin Teske		'4 $msg_force_4k_sectors' '$force4k'
242cd88b886SDevin Teske		                          '$msg_force_4k_sectors_help'
243cd88b886SDevin Teske		'5 $msg_geli_encryption'  '$usegeli'
244cd88b886SDevin Teske		                          '$msg_geli_encryption_help'
245cd88b886SDevin Teske		'6 $msg_partition_scheme' '$ZFSBOOT_PARTITION_SCHEME'
246cd88b886SDevin Teske		                          '$msg_partition_scheme_help'
247cd88b886SDevin Teske		'7 $msg_swap_size'        '$ZFSBOOT_SWAP_SIZE'
248cd88b886SDevin Teske		                          '$msg_swap_size_help'
249cd88b886SDevin Teske	" # END-QUOTE
250cd88b886SDevin Teske	local defaultitem= # Calculated below
251cd88b886SDevin Teske	local hline="$hline_alnum_arrows_punc_tab_enter"
252cd88b886SDevin Teske
253cd88b886SDevin Teske	local height width rows
254cd88b886SDevin Teske	eval f_dialog_menu_with_help_size height width rows \
255cd88b886SDevin Teske		\"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $menu_list
256cd88b886SDevin Teske
257cd88b886SDevin Teske	# Obtain default-item from previously stored selection
258cd88b886SDevin Teske	f_dialog_default_fetch defaultitem
259cd88b886SDevin Teske
260cd88b886SDevin Teske	local menu_choice
261cd88b886SDevin Teske	menu_choice=$( eval $DIALOG \
262cd88b886SDevin Teske		--title \"\$title\"              \
263cd88b886SDevin Teske		--backtitle \"\$btitle\"         \
264cd88b886SDevin Teske		--hline \"\$hline\"              \
265cd88b886SDevin Teske		--item-help                      \
266cd88b886SDevin Teske		--ok-label \"\$msg_select\"      \
267cd88b886SDevin Teske		--cancel-label \"\$msg_cancel\"  \
268cd88b886SDevin Teske		--default-item \"\$defaultitem\" \
269cd88b886SDevin Teske		--menu \"\$prompt\"              \
270cd88b886SDevin Teske		$height $width $rows             \
271cd88b886SDevin Teske		$menu_list                       \
272cd88b886SDevin Teske		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
273cd88b886SDevin Teske	)
274cd88b886SDevin Teske	local retval=$?
275cd88b886SDevin Teske	f_dialog_data_sanitize menu_choice
276cd88b886SDevin Teske	f_dialog_menutag_store "$menu_choice"
277cd88b886SDevin Teske
278cd88b886SDevin Teske	# Only update default-item on success
279cd88b886SDevin Teske	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
280cd88b886SDevin Teske
281cd88b886SDevin Teske	return $retval
282cd88b886SDevin Teske}
283cd88b886SDevin Teske
284cd88b886SDevin Teske# dialog_edit_disks
285cd88b886SDevin Teske#
286cd88b886SDevin Teske# Edit the list of disks to be used by the ZFS boot pool.
287cd88b886SDevin Teske#
288cd88b886SDevin Teskedialog_edit_disks()
289cd88b886SDevin Teske{
290cd88b886SDevin Teske	local title="$DIALOG_TITLE"
291cd88b886SDevin Teske	local btitle="$DIALOG_BACKTITLE"
292cd88b886SDevin Teske	local prompt="$msg_please_select_one_or_more_disks"
293cd88b886SDevin Teske	local check_list= # Calculated below
294cd88b886SDevin Teske	local hline="$hline_arrows_space_tab_enter"
295cd88b886SDevin Teske	local dev vardev disks=
296cd88b886SDevin Teske
297cd88b886SDevin Teske	#
298cd88b886SDevin Teske	# Get a [new] list of disk devices
299cd88b886SDevin Teske	#
300cd88b886SDevin Teske	f_device_find "" $DEVICE_TYPE_DISK disks
301cd88b886SDevin Teske	if [ ! "$disks" ]; then
302cd88b886SDevin Teske		f_show_msg "$msg_no_disks_present_to_configure"
303cd88b886SDevin Teske		return $FAILURE
304cd88b886SDevin Teske	fi
305cd88b886SDevin Teske
306cd88b886SDevin Teske	# Lets sort the disks array to be more user friendly
307cd88b886SDevin Teske	disks=$( echo "$disks" | tr ' ' '\n' | sort | tr '\n' ' ' )
308cd88b886SDevin Teske
309cd88b886SDevin Teske	#
310cd88b886SDevin Teske	# Loop through the list of selected disks and create temporary local
311cd88b886SDevin Teske	# variables mapping their status onto an up-to-date list of disks.
312cd88b886SDevin Teske	#
313cd88b886SDevin Teske	for dev in $ZFSBOOT_DISKS; do
314cd88b886SDevin Teske		f_str2varname "$dev" vardev
315cd88b886SDevin Teske		local _${vardev}_status=on
316cd88b886SDevin Teske	done
317cd88b886SDevin Teske
318cd88b886SDevin Teske	#
319cd88b886SDevin Teske	# Create the checklist menu of discovered disk devices
320cd88b886SDevin Teske	#
321cd88b886SDevin Teske	local on_off
322cd88b886SDevin Teske	for dev in $disks; do
323cd88b886SDevin Teske		local desc=
324cd88b886SDevin Teske		device_$dev get desc desc
325cd88b886SDevin Teske		f_shell_escape "$desc" desc
326cd88b886SDevin Teske		f_str2varname "$dev" vardev
327cd88b886SDevin Teske		f_getvar _${vardev}_status:-off on_off
328cd88b886SDevin Teske		check_list="$check_list '$dev' '$desc' $on_off"
329cd88b886SDevin Teske	done
330cd88b886SDevin Teske
331cd88b886SDevin Teske	#
332cd88b886SDevin Teske	# Prompt the user to check some disks
333cd88b886SDevin Teske	#
334cd88b886SDevin Teske	local height width rows
335cd88b886SDevin Teske	eval f_dialog_checklist_size height width rows \
336cd88b886SDevin Teske		\"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $check_list
337cd88b886SDevin Teske	disks=$( eval $DIALOG \
338cd88b886SDevin Teske		--title \"\$DIALOG_TITLE\"         \
339cd88b886SDevin Teske		--backtitle \"\$DIALOG_BACKTITLE\" \
340cd88b886SDevin Teske		--hline \"\$hline\"                \
341cd88b886SDevin Teske		--ok-label \"\$msg_ok\"            \
342cd88b886SDevin Teske		--cancel-label \"\$msg_cancel\"    \
343cd88b886SDevin Teske		--checklist \"\$prompt\"           \
344cd88b886SDevin Teske		$height $width $rows               \
345cd88b886SDevin Teske		$check_list                        \
346cd88b886SDevin Teske		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
347cd88b886SDevin Teske	) || return $?
348cd88b886SDevin Teske		# Exit if user either pressed ESC or chose Cancel/No
349cd88b886SDevin Teske	f_dialog_data_sanitize disks
350cd88b886SDevin Teske
351cd88b886SDevin Teske	ZFSBOOT_DISKS="$disks"
352cd88b886SDevin Teske
353cd88b886SDevin Teske	return $DIALOG_OK
354cd88b886SDevin Teske}
355cd88b886SDevin Teske
356cd88b886SDevin Teske# dialog_menu_vdev
357cd88b886SDevin Teske#
358cd88b886SDevin Teske# Prompt the user to select a a Virtual Device type.
359cd88b886SDevin Teske#
360cd88b886SDevin Teskedialog_menu_vdev()
361cd88b886SDevin Teske{
362cd88b886SDevin Teske	local title="$DIALOG_TITLE"
363cd88b886SDevin Teske	local btitle="$DIALOG_BACKTITLE"
364cd88b886SDevin Teske	local prompt="$msg_select_virtual_device_type"
365cd88b886SDevin Teske
366cd88b886SDevin Teske	# Make sure [potentially scripted] selections are real
367cd88b886SDevin Teske	real_disks=
368cd88b886SDevin Teske	for disk in $ZFSBOOT_DISKS; do
369cd88b886SDevin Teske		f_struct device_$disk && real_disks="$real_disks $disk"
370cd88b886SDevin Teske	done
371cd88b886SDevin Teske	# Make sure we have at least one real disk selected
372cd88b886SDevin Teske	ndisks=$( set -- $real_disks; echo $# )
373cd88b886SDevin Teske
374cd88b886SDevin Teske	local menu_list="
375cd88b886SDevin Teske		'stripe' '$msg_stripe_desc' '$msg_stripe_help'
376cd88b886SDevin Teske		'mirror' '$msg_mirror_desc' '$msg_mirror_help'
377cd88b886SDevin Teske		'raidz1' '$msg_raidz1_desc' '$msg_raidz1_help'
378cd88b886SDevin Teske		'raidz2' '$msg_raidz2_desc' '$msg_raidz2_help'
379cd88b886SDevin Teske		'raidz3' '$msg_raidz3_desc' '$msg_raidz3_help'
380cd88b886SDevin Teske	" # END-QUOTE
381cd88b886SDevin Teske
382cd88b886SDevin Teske	local defaultitem="$ZFSBOOT_VDEV_TYPE"
383cd88b886SDevin Teske	local hline="$hline_arrows_tab_enter"
384cd88b886SDevin Teske	local error_msg revalidate_choice
385cd88b886SDevin Teske
386cd88b886SDevin Teske	local mheight mwidth mrows
387cd88b886SDevin Teske	eval f_dialog_menu_size mheight mwidth mrows \
388cd88b886SDevin Teske		\"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $menu_list
389cd88b886SDevin Teske	local iheight iwidth
390cd88b886SDevin Teske	f_dialog_infobox_size iheight iwidth \
391cd88b886SDevin Teske		"$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_processing_selection"
392cd88b886SDevin Teske
393cd88b886SDevin Teske	local menu_choice
394cd88b886SDevin Teske	menu_choice=$( eval $DIALOG \
395cd88b886SDevin Teske		--title \"\$title\"              \
396cd88b886SDevin Teske		--backtitle \"\$btitle\"         \
397cd88b886SDevin Teske		--hline \"\$hline\"              \
398cd88b886SDevin Teske		--ok-label \"\$msg_ok\"          \
399cd88b886SDevin Teske		--cancel-label \"\$msg_cancel\"  \
400cd88b886SDevin Teske		--item-help                      \
401cd88b886SDevin Teske		--default-item \"\$defaultitem\" \
402cd88b886SDevin Teske		--menu \"\$prompt\"              \
403cd88b886SDevin Teske		$mheight $mwidth $mrows          \
404cd88b886SDevin Teske		$menu_list                       \
405cd88b886SDevin Teske		--and-widget                     \
406cd88b886SDevin Teske		${USE_XDIALOG:+--no-buttons}     \
407cd88b886SDevin Teske		--infobox \"\$msg_processing_selection\" \
408cd88b886SDevin Teske		$iheight $iwidth                 \
409cd88b886SDevin Teske		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
410cd88b886SDevin Teske	) || return $FAILURE
411cd88b886SDevin Teske	f_dialog_data_sanitize menu_choice
412cd88b886SDevin Teske	sleep 0.5 # Give time to read `--and-widget --info-box'
413cd88b886SDevin Teske
414cd88b886SDevin Teske	# Make sure we have enough disks for the desired vdev type
415cd88b886SDevin Teske	case "$menu_choice" in
416cd88b886SDevin Teske	stripe) want_disks=1 ;;
417cd88b886SDevin Teske	mirror) want_disks=2 ;;
418cd88b886SDevin Teske	raidz1) want_disks=3 ;;
419cd88b886SDevin Teske	raidz2) want_disks=4 ;;
420cd88b886SDevin Teske	raidz3) want_disks=5 ;;
421cd88b886SDevin Teske	*)
422cd88b886SDevin Teske		f_show_msg "$msg_invalid_virtual_device_type" \
423cd88b886SDevin Teske	                   "$menu_choice"
424cd88b886SDevin Teske		continue
425cd88b886SDevin Teske	esac
426cd88b886SDevin Teske	if [ $ndisks -lt $want_disks ]; then
427cd88b886SDevin Teske		msg_yes="$msg_change" msg_no="$msg_cancel" f_yesno \
428cd88b886SDevin Teske			"%s: $msg_not_enough_disks_selected\n%s" \
429cd88b886SDevin Teske			"$menu_choice" $ndisks $want_disks \
430cd88b886SDevin Teske			"$msg_invalid_virtual_device_type_help" ||
431cd88b886SDevin Teske			return $FAILURE
432cd88b886SDevin Teske		dialog_menu_vdev
433cd88b886SDevin Teske	else
434cd88b886SDevin Teske		ZFSBOOT_VDEV_TYPE="$menu_choice"
435cd88b886SDevin Teske	fi
436cd88b886SDevin Teske}
437cd88b886SDevin Teske
438cd88b886SDevin Teske# zfs_create_diskpart $disk $index
439cd88b886SDevin Teske#
440cd88b886SDevin Teske# For each block device to be used in the zpool, rather than just create the
441cd88b886SDevin Teske# zpool with the raw block devices (e.g., da0, da1, etc.) we create partitions
442cd88b886SDevin Teske# so we can have some real swap. This also provides wiggle room incase your
443cd88b886SDevin Teske# replacement drivers do not have the exact same sector counts.
444cd88b886SDevin Teske#
445cd88b886SDevin Teske# NOTE: The MBR layout is more complicated (GPT is preferred).
446cd88b886SDevin Teske#
447cd88b886SDevin Teskezfs_create_diskpart()
448cd88b886SDevin Teske{
449cd88b886SDevin Teske	local disk="$1" index="$2"
450cd88b886SDevin Teske	local funcname=zfs_create_diskpart
451cd88b886SDevin Teske	local disksize partsize
452cd88b886SDevin Teske
453cd88b886SDevin Teske	# Check arguments
454cd88b886SDevin Teske	[ "$disk" -a "$index" ] || return $FAILURE
455cd88b886SDevin Teske
456cd88b886SDevin Teske	#
457cd88b886SDevin Teske	# Destroy whatever partition layout is currently on disk.
458cd88b886SDevin Teske	# NOTE: `-F' required to destroy if partitions still exist.
459cd88b886SDevin Teske	# NOTE: Failure is ok here, blank disk will have nothing to destroy.
460cd88b886SDevin Teske	#
461cd88b886SDevin Teske	f_quietly gpart destroy -F $disk
462cd88b886SDevin Teske	f_quietly zpool labelclear -f /dev/$disk # Kill it with fire
463cd88b886SDevin Teske
464cd88b886SDevin Teske	# Make doubly-sure backup GPT is destroyed
465cd88b886SDevin Teske	f_quietly gpart create -s gpt $disk || return $FAILURE
466cd88b886SDevin Teske	f_quietly gpart destroy -F $disk || return $FAILURE
467cd88b886SDevin Teske
468cd88b886SDevin Teske	# Calculate partition size given desired amount of swap
469cd88b886SDevin Teske	device_$disk get capacity disksize || return $FAILURE
470cd88b886SDevin Teske	partsize=$(( $disksize - $swapsize ))
471cd88b886SDevin Teske
472cd88b886SDevin Teske	#
473cd88b886SDevin Teske	# Lay down the desired type of partition scheme
474cd88b886SDevin Teske	#
475cd88b886SDevin Teske	local setsize mbrindex
476cd88b886SDevin Teske	case "$ZFSBOOT_PARTITION_SCHEME" in
477cd88b886SDevin Teske	""|GPT)
478cd88b886SDevin Teske		#
479cd88b886SDevin Teske		# 1. Create GPT layout using labels
480cd88b886SDevin Teske		#
481cd88b886SDevin Teske		gpart create -s gpt $disk || return $FAILURE
482cd88b886SDevin Teske
483cd88b886SDevin Teske		#
484cd88b886SDevin Teske		# 2. Add small freebsd-boot partition labeled `boot#'
485cd88b886SDevin Teske		#
486cd88b886SDevin Teske		gpart add -l gptboot$index -t freebsd-boot -s 512k $disk ||
487cd88b886SDevin Teske			return $FAILURE
488cd88b886SDevin Teske		gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $disk ||
489cd88b886SDevin Teske			return $FAILURE
490cd88b886SDevin Teske
491cd88b886SDevin Teske		# zpool will use the `zfs#' GPT labels
492cd88b886SDevin Teske		bootpart=p2 targetpart=p2
493cd88b886SDevin Teske
494cd88b886SDevin Teske		# Change things around if we are using GELI
495cd88b886SDevin Teske		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
496cd88b886SDevin Teske			bootpart=p2 targetpart=p3
497cd88b886SDevin Teske			partsize=$(( $partsize - $gelisize ))
498cd88b886SDevin Teske			gpart add -l boot$index -t freebsd-zfs \
499cd88b886SDevin Teske				-s ${gelisize}b -a 1m $disk || return $FAILURE
500cd88b886SDevin Teske			# Pedantically nuke any old labels, stop geli
501cd88b886SDevin Teske			f_quietly zpool labelclear -f /dev/$disk$bootpart
502cd88b886SDevin Teske			f_quietly geli detach -f /dev/$disk$targetpart
503cd88b886SDevin Teske		fi
504cd88b886SDevin Teske
505cd88b886SDevin Teske		#
506cd88b886SDevin Teske		# 3. Add freebsd-zfs partition labeled `zfs#' for zpool
507cd88b886SDevin Teske		# NOTE: Using above calculated partsize to leave room for swap.
508cd88b886SDevin Teske		#
509cd88b886SDevin Teske		[ $swapsize -gt 0 ] && setsize="-s ${partsize}b"
510cd88b886SDevin Teske		gpart add -l zfs$index -t freebsd-zfs $setsize -a 1m $disk ||
511cd88b886SDevin Teske			return $FAILURE
512cd88b886SDevin Teske		f_quietly zpool labelclear -f /dev/$disk$targetpart # Pedantic
513cd88b886SDevin Teske
514cd88b886SDevin Teske		#
515cd88b886SDevin Teske		# 4. Add freebsd-swap partition labeled `swap#'
516cd88b886SDevin Teske		#
517cd88b886SDevin Teske		if [ $swapsize -gt 0 ]; then
518cd88b886SDevin Teske			gpart add -l swap$index -t freebsd-swap -a 1m $disk ||
519cd88b886SDevin Teske				return $FAILURE
520cd88b886SDevin Teske			# Update fstab(5)
521cd88b886SDevin Teske			printf "$fstab_fmt" \
522cd88b886SDevin Teske				/dev/gpt/swap$index none swap sw 0 0 \
523cd88b886SDevin Teske				>> $BSDINSTALL_TMPETC/fstab || return $FAILURE
524cd88b886SDevin Teske		fi
525cd88b886SDevin Teske		;;
526cd88b886SDevin Teske
527cd88b886SDevin Teske	MBR)
528cd88b886SDevin Teske		#
529cd88b886SDevin Teske		# 1. Create MBR layout (no labels)
530cd88b886SDevin Teske		#
531cd88b886SDevin Teske		gpart create -s mbr $disk || return $FAILURE
532cd88b886SDevin Teske		gpart bootcode -b /boot/boot0 $disk || return $FAILURE
533cd88b886SDevin Teske
534cd88b886SDevin Teske		#
535cd88b886SDevin Teske		# 2. Add freebsd slice with all available space
536cd88b886SDevin Teske		#
537cd88b886SDevin Teske		gpart add -t freebsd $disk || return $FAILURE
538cd88b886SDevin Teske		gpart set -a active -i 1 $disk || return $FAILURE
539cd88b886SDevin Teske		f_quietly zpool labelclear -f /dev/${disk}s1 # Pedantic
540cd88b886SDevin Teske		f_quietly gpart destroy -F ${disk}s1 # Pedantic
541cd88b886SDevin Teske
542cd88b886SDevin Teske		#
543cd88b886SDevin Teske		# 3. Write BSD sceme to the freebsd slice
544cd88b886SDevin Teske		#
545cd88b886SDevin Teske		gpart create -s BSD ${disk}s1 || return $FAILURE
546cd88b886SDevin Teske
547cd88b886SDevin Teske		# zpool will use s1a (no labels)
548cd88b886SDevin Teske		bootpart=s1a targetpart=s1a mbrindex=1
549cd88b886SDevin Teske
550cd88b886SDevin Teske		# Change things around if we are using GELI
551cd88b886SDevin Teske		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
552cd88b886SDevin Teske			bootpart=s1a targetpart=s1d
553cd88b886SDevin Teske			partsize=$(( $partsize - $gelisize ))
554cd88b886SDevin Teske			mbrindex=4 # If this is s1a then make the zpool s1d
555cd88b886SDevin Teske			gpart add -t freebsd-zfs -i 1 -s ${gelisize}b \
556cd88b886SDevin Teske				${disk}s1 || return $FAILURE
557cd88b886SDevin Teske			# Pedantically nuke any old labels, stop geli
558cd88b886SDevin Teske			f_quietly zpool labelclear -f /dev/$disk$bootpart
559cd88b886SDevin Teske			f_quietly geli detach -f /dev/$disk$targetpart
560cd88b886SDevin Teske		fi
561cd88b886SDevin Teske
562cd88b886SDevin Teske		#
563cd88b886SDevin Teske		# 4. Partition the BSD slice for ZFS
564cd88b886SDevin Teske		# NOTE: Using above calculated partsize to leave room for swap.
565cd88b886SDevin Teske		#
566cd88b886SDevin Teske		[ $swapsize -gt 0 ] && setsize="-s ${partsize}b"
567cd88b886SDevin Teske		gpart add -t freebsd-zfs -i $mbrindex $setsize ${disk}s1 ||
568cd88b886SDevin Teske			return $FAILURE
569cd88b886SDevin Teske		f_quietly zpool labelclear -f /dev/$disk$targetpart # Pedantic
570cd88b886SDevin Teske
571cd88b886SDevin Teske		#
572cd88b886SDevin Teske		# 5. Add freebsd-swap partition
573cd88b886SDevin Teske		#
574cd88b886SDevin Teske		if [ $swapsize -gt 0 ]; then
575cd88b886SDevin Teske			gpart add -t freebsd-swap -i 2 ${disk}s1 ||
576cd88b886SDevin Teske				return $FAILURE
577cd88b886SDevin Teske			# Update fstab(5)
578cd88b886SDevin Teske			printf "$fstab_fmt" /dev/${disk}s1b none swap sw 0 0 \
579cd88b886SDevin Teske				>> $BSDINSTALL_TMPETC/fstab || return $FAILURE
580cd88b886SDevin Teske		fi
581cd88b886SDevin Teske		;;
582cd88b886SDevin Teske
583cd88b886SDevin Teske	*)
584cd88b886SDevin Teske		printf "%s: %s is an unsupported partition scheme" \
585cd88b886SDevin Teske		       "$funcname" "$ZFSBOOT_PARTITION_SCHEME" >&2
586cd88b886SDevin Teske		return $FAILURE
587cd88b886SDevin Teske
588cd88b886SDevin Teske	esac # $ZFSBOOT_PARTITION_SCHEME
589cd88b886SDevin Teske
590cd88b886SDevin Teske	return $SUCCESS
591cd88b886SDevin Teske}
592cd88b886SDevin Teske
593cd88b886SDevin Teske# zfs_create_boot $poolname $vdev_type $real_disks ...
594cd88b886SDevin Teske#
595cd88b886SDevin Teske# Creates boot pool and dataset layout. Returns error if something goes wrong.
596cd88b886SDevin Teske# Errors are printed to stderr for collection and display.
597cd88b886SDevin Teske#
598cd88b886SDevin Teskezfs_create_boot()
599cd88b886SDevin Teske{
600cd88b886SDevin Teske	local poolname="$1" vdev_type="$2"
601cd88b886SDevin Teske	local fstab_fmt="%s\t\t%s\t%s\t%s\t\t%s\t%s\n"
602cd88b886SDevin Teske	local funcname=zfs_create_boot
603cd88b886SDevin Teske	local bootpart targetpart
604cd88b886SDevin Teske
605cd88b886SDevin Teske	shift 2 # name vdev_type
606cd88b886SDevin Teske
607cd88b886SDevin Teske	# We may need this later
608cd88b886SDevin Teske	local realdisks=$*
609cd88b886SDevin Teske
610cd88b886SDevin Teske	# Pedantic checks; should never be seen
611cd88b886SDevin Teske	if [ ! "$poolname" ]; then
612cd88b886SDevin Teske		echo "$funcname: NULL poolname" >&2
613cd88b886SDevin Teske		return $FAILURE
614cd88b886SDevin Teske	fi
615cd88b886SDevin Teske	if [ $# -lt 1 ]; then
616cd88b886SDevin Teske		echo "$funcname: missing disk arguments" >&2
617cd88b886SDevin Teske		return $FAILURE
618cd88b886SDevin Teske	fi
619cd88b886SDevin Teske
620cd88b886SDevin Teske	# Initialize fstab(5)
621cd88b886SDevin Teske	printf "$fstab_fmt" \
622cd88b886SDevin Teske		"# Device" Mountpoint FStype Options Dump "Pass#" \
623cd88b886SDevin Teske		>> $BSDINSTALL_TMPETC/fstab || return $FAILURE
624cd88b886SDevin Teske
625cd88b886SDevin Teske	# Expand SI units in desired sizes
626cd88b886SDevin Teske	local swapsize gelisize
627cd88b886SDevin Teske	f_expand_number "$ZFSBOOT_SWAP_SIZE" swapsize || return $FAILURE
628cd88b886SDevin Teske	f_expand_number "$ZFSBOOT_GELI_BOOT_SIZE" gelisize || return $FAILURE
629cd88b886SDevin Teske
630cd88b886SDevin Teske	# Prepare the disks
631cd88b886SDevin Teske	local n=0
632cd88b886SDevin Teske	for disk in $*; do
633cd88b886SDevin Teske		zfs_create_diskpart $disk $n || return $FAILURE
634cd88b886SDevin Teske		n=$(( $n + 1 ))
635cd88b886SDevin Teske	done
636cd88b886SDevin Teske
637cd88b886SDevin Teske	# MBR boot loader hack part 1
638cd88b886SDevin Teske	# We have to do this early because geli gets in the way later
639cd88b886SDevin Teske	if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
640cd88b886SDevin Teske		for disk in $realdisks; do
641cd88b886SDevin Teske			dd if=/boot/zfsboot of=/dev/${disk}s1 count=1 ||
642cd88b886SDevin Teske				return $FAILURE
643cd88b886SDevin Teske		done
644cd88b886SDevin Teske	fi
645cd88b886SDevin Teske
646cd88b886SDevin Teske	# Forced 4k alignment support provided by Geom NOP (see gnop(8))
647cd88b886SDevin Teske	local unenc_list=
648cd88b886SDevin Teske	if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then
649cd88b886SDevin Teske		local new_list=
650cd88b886SDevin Teske		for disk in $*; do
651cd88b886SDevin Teske			if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
652cd88b886SDevin Teske				# We don't gnop the encrypted partition
653cd88b886SDevin Teske				# because geli will do this for us
654cd88b886SDevin Teske				# gnop the unencrypted disk
655cd88b886SDevin Teske				gnop create -S 4096 $disk$bootpart ||
656cd88b886SDevin Teske					return $FAILURE
657cd88b886SDevin Teske				unenc_list="$unenc_list $disk$bootpart.nop"
658cd88b886SDevin Teske			else
659cd88b886SDevin Teske				gnop create -S 4096 $disk$targetpart ||
660cd88b886SDevin Teske					return $FAILURE
661cd88b886SDevin Teske				new_list="$new_list $disk$targetpart.nop"
662cd88b886SDevin Teske			fi
663cd88b886SDevin Teske		done
664cd88b886SDevin Teske		set -- $new_list
665cd88b886SDevin Teske	else
666cd88b886SDevin Teske		local new_list=
667cd88b886SDevin Teske		for disk in $*; do
668cd88b886SDevin Teske			new_list="$new_list $disk$targetpart"
669cd88b886SDevin Teske			[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
670cd88b886SDevin Teske				unenc_list="$unenc_list $disk$bootpart"
671cd88b886SDevin Teske		done
672cd88b886SDevin Teske		set -- $new_list
673cd88b886SDevin Teske	fi
674cd88b886SDevin Teske
675cd88b886SDevin Teske	#
676cd88b886SDevin Teske	# If encryption is enabled, we need to create the GEOMs
677cd88b886SDevin Teske	#
678cd88b886SDevin Teske	if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
679cd88b886SDevin Teske		local bootvdev=
680cd88b886SDevin Teske		local geli_pool="$BSDINSTALL_CHROOT/$ZFSBOOT_GELI_POOL_NAME"
681cd88b886SDevin Teske		local key="$ZFSBOOT_GELI_KEY_FILE"
682cd88b886SDevin Teske
683cd88b886SDevin Teske		# Create the parent directories for our unencrypted pool
684cd88b886SDevin Teske		f_quietly umount /mnt
685cd88b886SDevin Teske		mount -t tmpfs none $BSDINSTALL_CHROOT || return $FAILURE
686cd88b886SDevin Teske
687cd88b886SDevin Teske		# Create mirror across the unencrypted partition on all disks
688cd88b886SDevin Teske		[ $( set -- $unenc_list; echo $# ) -gt 1 ] && bootvdev=mirror
689cd88b886SDevin Teske
690cd88b886SDevin Teske		zpool create -o altroot=$BSDINSTALL_CHROOT \
691cd88b886SDevin Teske			-m "/$ZFSBOOT_GELI_POOL_NAME" -f \
692cd88b886SDevin Teske			"$ZFSBOOT_GELI_POOL_NAME" $bootvdev $unenc_list ||
693cd88b886SDevin Teske			return $FAILURE
694cd88b886SDevin Teske		mkdir -p $geli_pool/boot || return $FAILURE
695cd88b886SDevin Teske
696cd88b886SDevin Teske		# Generate an encryption key using random(4)
697cd88b886SDevin Teske		dd if=/dev/random of="$geli_pool/$key" bs=4096 count=1 ||
698cd88b886SDevin Teske			return $FAILURE
699cd88b886SDevin Teske
700cd88b886SDevin Teske		# Create the geli(8) GEOMS
701cd88b886SDevin Teske		local geli_list
702cd88b886SDevin Teske		msg_enter_new_password="$msg_geli_password" \
703cd88b886SDevin Teske			f_dialog_input_password || return $FAILURE
704cd88b886SDevin Teske		f_dialog_info "$msg_geli_setup" \
705cd88b886SDevin Teske			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
706cd88b886SDevin Teske		for disk in $realdisks; do
707cd88b886SDevin Teske			echo "$pw_password" | geli init -b -B \
708cd88b886SDevin Teske				"$geli_pool/boot/$disk$targetpart.eli" \
709cd88b886SDevin Teske				-e AES-XTS -J - -K "$geli_pool/$key" -l 256 \
710cd88b886SDevin Teske				-s 4096 $disk$targetpart || return $FAILURE
711cd88b886SDevin Teske			echo "$pw_password" | geli attach -j - \
712cd88b886SDevin Teske				-k "$geli_pool/$key" $disk$targetpart ||
713cd88b886SDevin Teske				return $FAILURE
714cd88b886SDevin Teske			geli_list="$geli_list $disk$targetpart.eli"
715cd88b886SDevin Teske		done
716cd88b886SDevin Teske		set -- $geli_list
717cd88b886SDevin Teske		zfs unmount "$ZFSBOOT_GELI_POOL_NAME" || return $FAILURE
718cd88b886SDevin Teske		f_quietly umount /mnt # done with tmpfs
719cd88b886SDevin Teske	fi
720cd88b886SDevin Teske
721cd88b886SDevin Teske	#
722cd88b886SDevin Teske	# Create the ZFS pool with desired type and disk devices
723cd88b886SDevin Teske	#
724cd88b886SDevin Teske	zpool create -o altroot=$BSDINSTALL_CHROOT -m none -f \
725cd88b886SDevin Teske		"$poolname" $vdev_type $* || return $FAILURE
726cd88b886SDevin Teske
727cd88b886SDevin Teske	# Customize the zpool a bit...
728cd88b886SDevin Teske	zfs set checksum=fletcher4	"$poolname" || return $FAILURE
729cd88b886SDevin Teske	zfs set atime=off		"$poolname" || return $FAILURE
730cd88b886SDevin Teske
731cd88b886SDevin Teske	#
732cd88b886SDevin Teske	# Create ZFS dataset layout within the new boot pool
733cd88b886SDevin Teske	#
734cd88b886SDevin Teske	echo "$ZFSBOOT_DATASETS" | while read dataset options; do
735cd88b886SDevin Teske		# Skip blank lines and comments
736cd88b886SDevin Teske		case "$dataset" in "#"*|"") continue; esac
737cd88b886SDevin Teske		# Remove potential inline comments in options
738cd88b886SDevin Teske		options="${options%%#*}"
739cd88b886SDevin Teske		# Replace tabs with spaces
740cd88b886SDevin Teske		f_replaceall "$options" "	" " " options
741cd88b886SDevin Teske		# Reduce contiguous runs of space to one single space
742cd88b886SDevin Teske		oldoptions=
743cd88b886SDevin Teske		while [ "$oldoptions" != "$options" ]; do
744cd88b886SDevin Teske			oldoptions="$options"
745cd88b886SDevin Teske			f_replaceall "$options" "  " " " options
746cd88b886SDevin Teske		done
747cd88b886SDevin Teske		# Replace both commas and spaces with ` -o '
748cd88b886SDevin Teske		f_replaceall "$options" "[ ,]" " -o " options
749cd88b886SDevin Teske		# Create the dataset with desired options
750cd88b886SDevin Teske		zfs create ${options:+-o $options} "$poolname$dataset" ||
751cd88b886SDevin Teske			return $FAILURE
752cd88b886SDevin Teske	done
753cd88b886SDevin Teske
754cd88b886SDevin Teske	# Touch up permissions on the tmp directories
755cd88b886SDevin Teske	chmod 1777 $BSDINSTALL_CHROOT/tmp || return $FAILURE
756cd88b886SDevin Teske	chmod 1777 $BSDINSTALL_CHROOT/var/tmp || return $FAILURE
757cd88b886SDevin Teske
758cd88b886SDevin Teske	# Create symlink(s)
759cd88b886SDevin Teske	[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
760cd88b886SDevin Teske		{ ln -s $ZFSBOOT_GELI_POOL_NAME/boot $BSDINSTALL_CHROOT/boot ||
761cd88b886SDevin Teske			return $FAILURE; }
762cd88b886SDevin Teske
763cd88b886SDevin Teske	# Set bootfs property
764cd88b886SDevin Teske	zpool set bootfs="$poolname/$ZFSBOOT_BEROOT_NAME/$ZFSBOOT_BOOTFS_NAME" \
765cd88b886SDevin Teske		"$poolname" || return $FAILURE
766cd88b886SDevin Teske
767cd88b886SDevin Teske	# Export the pool(s)
768cd88b886SDevin Teske	zpool export "$poolname" || return $FAILURE
769cd88b886SDevin Teske	[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
770cd88b886SDevin Teske		{ zpool export "$ZFSBOOT_GELI_POOL_NAME" || return $FAILURE; }
771cd88b886SDevin Teske
772cd88b886SDevin Teske	# Destroy the gnop devices (if enabled)
773cd88b886SDevin Teske	for disk in ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:+$realdisks}; do
774cd88b886SDevin Teske		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
775cd88b886SDevin Teske			f_quietly gnop destroy $disk$bootpart.nop
776cd88b886SDevin Teske		else
777cd88b886SDevin Teske			f_quietly gnop destroy $disk$targetpart.nop
778cd88b886SDevin Teske		fi
779cd88b886SDevin Teske	done
780cd88b886SDevin Teske
781cd88b886SDevin Teske	# MBR boot loader hack part 2
782cd88b886SDevin Teske	if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
783cd88b886SDevin Teske		# Stick the ZFS boot loader in the "convienient hole" after
784cd88b886SDevin Teske		# the ZFS internal metadata
785cd88b886SDevin Teske		for disk in $realdisks; do
786cd88b886SDevin Teske			dd if=/boot/zfsboot of=/dev/$disk$bootpart \
787cd88b886SDevin Teske				skip=1 seek=1024 || return $FAILURE
788cd88b886SDevin Teske		done
789cd88b886SDevin Teske	fi
790cd88b886SDevin Teske
791cd88b886SDevin Teske	# Re-import the ZFS pool(s)
792cd88b886SDevin Teske	zpool import -o altroot=$BSDINSTALL_CHROOT $poolname ||	return $FAILURE
793cd88b886SDevin Teske	[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
794cd88b886SDevin Teske		{ zpool import -o altroot=$BSDINSTALL_CHROOT \
795cd88b886SDevin Teske			"$ZFSBOOT_GELI_POOL_NAME" || return $FAILURE; }
796cd88b886SDevin Teske
797cd88b886SDevin Teske	# While this is apparently not needed, it seems to help MBR
798cd88b886SDevin Teske	mkdir -p $BSDINSTALL_CHROOT/boot/zfs || return $FAILURE
799cd88b886SDevin Teske	zpool set cachefile=$BSDINSTALL_CHROOT/boot/zfs/zpool.cache \
800cd88b886SDevin Teske		"$poolname" || return $FAILURE
801cd88b886SDevin Teske
80213d8e1ceSDevin Teske	# Last, but not least... required lines for rc.conf(5)/loader.conf(5)
803cd88b886SDevin Teske	# NOTE: We later concatenate these into their destination
804cd88b886SDevin Teske	echo 'zfs_enable="YES"' > $BSDINSTALL_TMPETC/rc.conf.zfs ||
805cd88b886SDevin Teske		return $FAILURE
806cd88b886SDevin Teske	echo 'zfs_load="YES"' > $BSDINSTALL_TMPBOOT/loader.conf.zfs ||
807cd88b886SDevin Teske		return $FAILURE
808cd88b886SDevin Teske
809cd88b886SDevin Teske	# We're all done unless we should go on to do encryption
810cd88b886SDevin Teske	[ "$ZFSBOOT_GELI_ENCRYPTION" ] || return $SUCCESS
811cd88b886SDevin Teske
81213d8e1ceSDevin Teske	# Some additional GELI requirements for loader.conf(5)
81313d8e1ceSDevin Teske	echo 'zpool_cache_load="YES"' \
814abd99bbcSDevin Teske		>> $BSDINSTALL_TMPBOOT/loader.conf.zfs || return $FAILURE
81513d8e1ceSDevin Teske	echo 'zpool_cache_type="/boot/zfs/zpool.cache"' \
816abd99bbcSDevin Teske		>> $BSDINSTALL_TMPBOOT/loader.conf.zfs || return $FAILURE
81713d8e1ceSDevin Teske	echo 'zpool_cache_name="/boot/zfs/zpool.cache"' \
818abd99bbcSDevin Teske		>> $BSDINSTALL_TMPBOOT/loader.conf.zfs || return $FAILURE
81913d8e1ceSDevin Teske
820cd88b886SDevin Teske	#
821cd88b886SDevin Teske	# Configure geli(8)-based encryption
822cd88b886SDevin Teske	#
823cd88b886SDevin Teske	echo 'aesni_load="YES"' \
824cd88b886SDevin Teske		> $BSDINSTALL_TMPBOOT/loader.conf.aesni || return $FAILURE
825cd88b886SDevin Teske	echo 'geom_eli_load="YES"' \
826cd88b886SDevin Teske		> $BSDINSTALL_TMPBOOT/loader.conf.geli || return $FAILURE
827cd88b886SDevin Teske	printf 'vfs.root.mountfrom="zfs:%s/%s/%s"\n' "$poolname" \
828cd88b886SDevin Teske		"$ZFSBOOT_BEROOT_NAME" "$ZFSBOOT_BOOTFS_NAME" \
829cd88b886SDevin Teske		> $BSDINSTALL_TMPBOOT/loader.conf.root || return $FAILURE
830cd88b886SDevin Teske	for disk in $realdisks; do
831cd88b886SDevin Teske		printf 'geli_%s_keyfile0_load="YES"\n' \
832cd88b886SDevin Teske			"$disk$targetpart" \
833cd88b886SDevin Teske			> $BSDINSTALL_TMPBOOT/loader.conf.$disk$targetpart ||
834cd88b886SDevin Teske			return $FAILURE
835cd88b886SDevin Teske		printf 'geli_%s_keyfile0_type="%s:geli_keyfile0"\n' \
836cd88b886SDevin Teske			"$disk$targetpart" "$disk$targetpart" \
837cd88b886SDevin Teske			>> $BSDINSTALL_TMPBOOT/loader.conf.$disk$targetpart ||
838cd88b886SDevin Teske			return $FAILURE
839cd88b886SDevin Teske		printf 'geli_%s_keyfile0_name="%s"\n' \
840cd88b886SDevin Teske			"$disk$targetpart" "$ZFSBOOT_GELI_KEY_FILE" \
841cd88b886SDevin Teske			>> $BSDINSTALL_TMPBOOT/loader.conf.$disk$targetpart ||
842cd88b886SDevin Teske			return $FAILURE
843cd88b886SDevin Teske	done
844cd88b886SDevin Teske
845cd88b886SDevin Teske	return $SUCCESS
846cd88b886SDevin Teske}
847cd88b886SDevin Teske
848cd88b886SDevin Teske# dialog_menu_diskinfo
849cd88b886SDevin Teske#
850cd88b886SDevin Teske# Prompt the user to select a disk and then provide detailed info on it.
851cd88b886SDevin Teske#
852cd88b886SDevin Teskedialog_menu_diskinfo()
853cd88b886SDevin Teske{
854cd88b886SDevin Teske	local disk
855cd88b886SDevin Teske
856cd88b886SDevin Teske	#
857cd88b886SDevin Teske	# Break from loop when user cancels disk selection
858cd88b886SDevin Teske	#
859cd88b886SDevin Teske	while :; do
860cd88b886SDevin Teske		disk=$( msg_cancel="$msg_back" f_device_menu \
861cd88b886SDevin Teske			"$DIALOG_TITLE" "$msg_select_a_disk_device" "" \
862cd88b886SDevin Teske			$DEVICE_TYPE_DISK 2>&1 ) || break
863cd88b886SDevin Teske
864cd88b886SDevin Teske		# Show gpart(8) `show' and camcontrol(8) `inquiry' data
865cd88b886SDevin Teske		f_show_msg "$msg_detailed_disk_info" \
866cd88b886SDevin Teske			"$disk" "$( gpart show $disk 2> /dev/null )" \
867cd88b886SDevin Teske			"$disk" "$( camcontrol inquiry $disk 2> /dev/null )" \
868cd88b886SDevin Teske			"$disk" "$( camcontrol identify $disk 2> /dev/null )"
869cd88b886SDevin Teske	done
870cd88b886SDevin Teske
871cd88b886SDevin Teske	return $SUCCESS
872cd88b886SDevin Teske}
873cd88b886SDevin Teske
874cd88b886SDevin Teske############################################################ MAIN
875cd88b886SDevin Teske
876cd88b886SDevin Teske#
877cd88b886SDevin Teske# Initialize
878cd88b886SDevin Teske#
879cd88b886SDevin Teskef_dialog_title "$msg_zfs_configuration"
880cd88b886SDevin Teskef_dialog_backtitle "$msg_freebsd_installer"
881cd88b886SDevin Teske
882cd88b886SDevin Teske# User may have specifically requested ZFS-related operations be interactive
883cd88b886SDevin Teske! f_interactive && f_zfsinteractive && unset $VAR_NONINTERACTIVE
884cd88b886SDevin Teske
885cd88b886SDevin Teske#
886cd88b886SDevin Teske# Loop over the main menu until we've accomplished what we came here to do
887cd88b886SDevin Teske#
888cd88b886SDevin Teskewhile :; do
889cd88b886SDevin Teske	if ! f_interactive; then
890cd88b886SDevin Teske		retval=$DIALOG_OK
891cd88b886SDevin Teske		mtag=">>> $msg_create"
892cd88b886SDevin Teske	else
893cd88b886SDevin Teske		dialog_menu_main
894cd88b886SDevin Teske		retval=$?
895cd88b886SDevin Teske		f_dialog_menutag_fetch mtag
896cd88b886SDevin Teske	fi
897cd88b886SDevin Teske
898cd88b886SDevin Teske	f_dprintf "retval=%u mtag=[%s]" $reval "$mtag"
899cd88b886SDevin Teske	[ $retval -eq $DIALOG_OK ] || f_die
900cd88b886SDevin Teske
901cd88b886SDevin Teske	case "$mtag" in
902cd88b886SDevin Teske	">>> $msg_create")
903cd88b886SDevin Teske		#
904cd88b886SDevin Teske		# First, validate the user's selections
905cd88b886SDevin Teske		#
906cd88b886SDevin Teske
907cd88b886SDevin Teske		# Make sure they gave us a name for the pool
908cd88b886SDevin Teske		if [ ! "$ZFSBOOT_POOL_NAME" ]; then
909cd88b886SDevin Teske			f_show_msg "$msg_pool_name_cannot_be_empty"
910cd88b886SDevin Teske			f_interactive || f_die
911cd88b886SDevin Teske			continue
912cd88b886SDevin Teske		fi
913cd88b886SDevin Teske		# Make sure [potentially scripted] selections are real
914cd88b886SDevin Teske		real_disks=
915cd88b886SDevin Teske		for disk in $ZFSBOOT_DISKS; do
916cd88b886SDevin Teske			f_struct device_$disk && real_disks="$real_disks $disk"
917cd88b886SDevin Teske		done
918cd88b886SDevin Teske		# Make sure we have at least one real disk selected
919cd88b886SDevin Teske		ndisks=$( set -- $real_disks; echo $# )
920cd88b886SDevin Teske		if [ $ndisks -lt 1 ]; then
921cd88b886SDevin Teske			f_show_msg "$msg_no_disks_selected"
922cd88b886SDevin Teske			f_interactive || f_die
923cd88b886SDevin Teske			continue
924cd88b886SDevin Teske		fi
925cd88b886SDevin Teske		# Make sure we have enough disks for the desired vdev type
926cd88b886SDevin Teske		case "$ZFSBOOT_VDEV_TYPE" in
927cd88b886SDevin Teske		stripe) want_disks=1 ;;
928cd88b886SDevin Teske		mirror) want_disks=2 ;;
929cd88b886SDevin Teske		raidz1) want_disks=3 ;;
930cd88b886SDevin Teske		raidz2) want_disks=4 ;;
931cd88b886SDevin Teske		raidz3) want_disks=5 ;;
932cd88b886SDevin Teske		*)
933cd88b886SDevin Teske			f_show_msg "$msg_invalid_virtual_device_type" \
934cd88b886SDevin Teske		                   "$ZFSBOOT_VDEV_TYPE"
935cd88b886SDevin Teske			f_interactive || f_die
936cd88b886SDevin Teske			continue
937cd88b886SDevin Teske		esac
938cd88b886SDevin Teske		if [ $ndisks -lt $want_disks ]; then
939cd88b886SDevin Teske			f_show_msg "%s: $msg_not_enough_disks_selected" \
940cd88b886SDevin Teske			           "$ZFSBOOT_VDEV_TYPE" "$want_disks"
941cd88b886SDevin Teske			f_interactive || f_die
942cd88b886SDevin Teske			continue
943cd88b886SDevin Teske		fi
944cd88b886SDevin Teske		# Make sure each disk will be at least 50% ZFS
945cd88b886SDevin Teske		if f_expand_number "$ZFSBOOT_SWAP_SIZE" swapsize &&
946cd88b886SDevin Teske		   f_expand_number "$ZFSBOOT_GELI_BOOT_SIZE" gelisize
947cd88b886SDevin Teske		then
948cd88b886SDevin Teske			minsize=$swapsize teeny_disks=
949cd88b886SDevin Teske			[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
950cd88b886SDevin Teske				minsize=$(( $minsize + $gelisize ))
951cd88b886SDevin Teske			for disk in $real_disks; do
952cd88b886SDevin Teske				device_$disk get capacity disksize || continue
953cd88b886SDevin Teske				disksize=$(( $disksize - $minsize ))
954cd88b886SDevin Teske				[ $disksize -lt $minsize ] &&
955cd88b886SDevin Teske					teeny_disks="$teeny_disks $disk"
956cd88b886SDevin Teske			done
957cd88b886SDevin Teske			if [ "$teeny_disks" ]; then
958cd88b886SDevin Teske				f_show_msg "$msg_these_disks_are_too_small" \
959cd88b886SDevin Teske				           "$ZFSBOOT_SWAP_SIZE" \
960cd88b886SDevin Teske				           "$ZFSBOOT_GELI_BOOT_SIZE" \
961cd88b886SDevin Teske				           "$teeny_disks"
962cd88b886SDevin Teske				f_interactive || f_die
963cd88b886SDevin Teske				continue
964cd88b886SDevin Teske			fi
965cd88b886SDevin Teske		fi
966cd88b886SDevin Teske
967cd88b886SDevin Teske		#
968cd88b886SDevin Teske		# Last Chance!
969cd88b886SDevin Teske		#
970cd88b886SDevin Teske		if [ ! "$USE_XDIALOG" ]; then
971cd88b886SDevin Teske			f_interactive && DIALOG="$DIALOG --colors" f_noyes \
972cd88b886SDevin Teske				"$msg_last_chance_are_you_sure_color" \
973cd88b886SDevin Teske				"$ZFSBOOT_DISKS" || continue
974cd88b886SDevin Teske		else
975cd88b886SDevin Teske			f_interactive && f_noyes \
976cd88b886SDevin Teske				"$msg_last_chance_are_you_sure" \
977cd88b886SDevin Teske				"$ZFSBOOT_DISKS" || continue
978cd88b886SDevin Teske		fi
979cd88b886SDevin Teske
980cd88b886SDevin Teske		#
981cd88b886SDevin Teske		# Let's do this
982cd88b886SDevin Teske		#
983cd88b886SDevin Teske
984cd88b886SDevin Teske		vdev_type="$ZFSBOOT_VDEV_TYPE"
985cd88b886SDevin Teske
986cd88b886SDevin Teske		# Blank the vdev type for the default layout
987cd88b886SDevin Teske		[ "$vdev_type" = "stripe" ] && vdev_type=
988cd88b886SDevin Teske
989cd88b886SDevin Teske		if ! error=$( zfs_create_boot "$ZFSBOOT_POOL_NAME" \
990cd88b886SDevin Teske			"$vdev_type" $real_disks 2>&1 )
991cd88b886SDevin Teske		then
992cd88b886SDevin Teske			f_dialog_msgbox "$error"
993cd88b886SDevin Teske			f_interactive || f_die
994cd88b886SDevin Teske			continue
995cd88b886SDevin Teske		fi
996cd88b886SDevin Teske
997cd88b886SDevin Teske		break # to success
998cd88b886SDevin Teske		;;
999cd88b886SDevin Teske	"- $msg_rescan_devices") f_device_rescan ;;
1000cd88b886SDevin Teske	"- $msg_disk_info") dialog_menu_diskinfo ;;
1001cd88b886SDevin Teske	?" $msg_pool_name")
1002cd88b886SDevin Teske		# Prompt the user to input/change the name for the new pool
1003cd88b886SDevin Teske		f_dialog_input input \
1004cd88b886SDevin Teske			"$msg_please_enter_a_name_for_your_zpool" \
1005cd88b886SDevin Teske			"$ZFSBOOT_POOL_NAME" &&
1006cd88b886SDevin Teske			ZFSBOOT_POOL_NAME="$input"
1007cd88b886SDevin Teske		;;
1008cd88b886SDevin Teske	?" $msg_disks_to_use") dialog_edit_disks ;;
1009cd88b886SDevin Teske	?" $msg_zfs_vdev_type") dialog_menu_vdev ;;
1010cd88b886SDevin Teske	?" $msg_force_4k_sectors")
1011cd88b886SDevin Teske		# Toggle the variable referenced both by the menu and later
1012cd88b886SDevin Teske		if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then
1013cd88b886SDevin Teske			ZFSBOOT_GNOP_4K_FORCE_ALIGN=
1014cd88b886SDevin Teske		else
1015cd88b886SDevin Teske			ZFSBOOT_GNOP_4K_FORCE_ALIGN=1
1016cd88b886SDevin Teske		fi
1017cd88b886SDevin Teske		;;
1018cd88b886SDevin Teske	?" $msg_geli_encryption")
1019cd88b886SDevin Teske		# Toggle the variable referenced both by the menu and later
1020cd88b886SDevin Teske		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
1021cd88b886SDevin Teske			ZFSBOOT_GELI_ENCRYPTION=
1022cd88b886SDevin Teske		else
1023cd88b886SDevin Teske			ZFSBOOT_GELI_ENCRYPTION=1
1024cd88b886SDevin Teske		fi
1025cd88b886SDevin Teske		;;
1026cd88b886SDevin Teske	?" $msg_partition_scheme")
1027cd88b886SDevin Teske		# Toggle between GPT and MBR
1028cd88b886SDevin Teske		if [ "$ZFSBOOT_PARTITION_SCHEME" = GPT ]; then
1029cd88b886SDevin Teske			ZFSBOOT_PARTITION_SCHEME=MBR
1030cd88b886SDevin Teske		else
1031cd88b886SDevin Teske			ZFSBOOT_PARTITION_SCHEME=GPT
1032cd88b886SDevin Teske		fi
1033cd88b886SDevin Teske		;;
1034cd88b886SDevin Teske	?" $msg_swap_size")
1035cd88b886SDevin Teske		# Prompt the user to input/change the swap size for each disk
1036cd88b886SDevin Teske		f_dialog_input input \
1037cd88b886SDevin Teske			"$msg_please_enter_amount_of_swap_space" \
1038cd88b886SDevin Teske			"$ZFSBOOT_SWAP_SIZE" &&
1039cd88b886SDevin Teske			ZFSBOOT_SWAP_SIZE="$input"
1040cd88b886SDevin Teske		;;
1041cd88b886SDevin Teske	esac
1042cd88b886SDevin Teskedone
1043cd88b886SDevin Teske
1044cd88b886SDevin Teskereturn $SUCCESS
1045cd88b886SDevin Teske
1046cd88b886SDevin Teske################################################################################
1047cd88b886SDevin Teske# END
1048cd88b886SDevin Teske################################################################################
1049