Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 08 Oct 2013 23:49:05 -0400
From:      Allan Jude <freebsd@allanjude.com>
To:        freebsd-current@freebsd.org
Subject:   Re: [CFT] Patch to bsdinstall to support root-on-ZFS and GELI
Message-ID:  <5254D231.5070803@allanjude.com>
In-Reply-To: <52531295.7090700@allanjude.com>
References:  <52531295.7090700@allanjude.com>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------040306070903020902050706
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

On 2013-10-07 15:59, Allan Jude wrote:
> Devin Teske and I have been working on a big patch to bsdinstall to
> implement installing on a ZFS pool. It supports both GPT and MBR, the 4k
> sector gnop trick, and optional GELI encryption. We would like to commit
> this in time for 10.0-BETA1 so it needs some testing to work out any
> obvious bugs before we send it off to re@ to get it committed.
>
> It includes a single configuration menu that allows you to select all of
> the required details, including which drives to use (gets details from
> camcontrol, also includes an inspection utility that presents the
> detailed output of camcontrol inquiry/identify, and gpart show), what
> ZFS RAID level to use (taking in to consideration the selected number of
> drives), GPT/mbr, 4k YES/no, GELI yes/NO, pool name, etc.
>
>
> Additional, it includes some other changes to bsdinstall:
> 1. Change the default to the 'non-standard keyboard mapping' prompt to no
> 2. Replace the 3 separate dialogs to configure an ipv4 address with just 1
> 3. Remove the dialog asking if you wish to enable crash dumps, this
> feature has been combined into the regular 'services to enable' dialog
> and enabled by default
>
>
> You can browse the patches here:
> http://druidbsd.cvs.sf.net/viewvc/druidbsd/bsdinstall_zfs/
>
> I've built a bootonly.iso (10.0-ALPHA4) to make testing easier,
> available compressed (48 MB) or uncompressed (211 MB):
>
> http://www.allanjude.com/bsd/zfsbootonly_2013-10-06.iso.xz
>
> http://www.allanjude.com/bsd/zfsbootonly_2013-10-06.iso
>
>
> We look forward to your feedback
>

We've made more improvements, including corporating most all of the
feedback we've gotten so far


Outstanding items:
1. Apply the changes to ipv6 config the way we did ipv4
2. improve disk identification (model info and serial # instead of one
or the other)
3. Include a helpful message before the GELI step where you have to
enter your password many times, the user will be less confused if it is
explained why they have to enter their password 3 * number of disks times
4. Validate vdev type choice inside the vdev type menu, and warn the
user if they have made an invalid selection, so they can add more disks
or chance their selection, without having to try to start the
installation first
5. Whatever else you guys find wrong tonight

I generated new test images, and attached the patch (which got REALLY
big when Devin Teske decided to fix "all of the things":

http://www.allanjude.com/bsd/zfsbootonly.2013-10-08.iso.xz

http://www.allanjude.com/bsd/zfsbootonly.2013-10-08.iso


-- 
Allan Jude


--------------040306070903020902050706
Content-Type: text/plain; charset=windows-1252;
 name="zfsboot.2013-10-08.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="zfsboot.2013-10-08.patch"

Index: usr.sbin/bsdconfig/bsdconfig
===================================================================
--- usr.sbin/bsdconfig/bsdconfig	(revision 256169)
+++ usr.sbin/bsdconfig/bsdconfig	(working copy)
@@ -300,7 +300,7 @@ dialog_menu_main()
 	f_dialog_menutag_store "$menu_choice"
 
 	# Only update default-item on success
-	[ $retval -eq 0 ] && f_dialog_default_store "$menu_choice"
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
 
 	return $retval
 }
@@ -396,11 +396,10 @@ while :; do
 	f_dialog_menutag_fetch mtag
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 
-	if [ $retval -eq 2 ]; then
-		# The Help button was pressed
+	if [ $retval -eq $DIALOG_HELP ]; then
 		f_show_help "$BSDCONFIG_HELPFILE"
 		continue
-	elif [ $retval -ne 0 ]; then
+	elif [ $retval -ne $DIALOG_OK ]; then
 		f_die
 	fi
 
Index: usr.sbin/bsdconfig/console/ttys
===================================================================
--- usr.sbin/bsdconfig/console/ttys	(revision 256169)
+++ usr.sbin/bsdconfig/console/ttys	(working copy)
@@ -92,7 +92,7 @@ dialog_menu_main()
 	local retval=$?
 	f_dialog_menutag_store -s "$menu_choice"
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		local item
 		item=$( eval f_dialog_menutag2item \
 		        	\"\$menu_choice\" $menu_list )
Index: usr.sbin/bsdconfig/mouse/enable
===================================================================
--- usr.sbin/bsdconfig/mouse/enable	(revision 256169)
+++ usr.sbin/bsdconfig/mouse/enable	(working copy)
@@ -102,7 +102,7 @@ f_dialog_title_restore
 # Stop the mouse daemon
 #
 f_quietly vidcontrol -m off
-if [ $retval -eq $SUCCESS ]; then
+if [ $retval -eq $DIALOG_OK ]; then
 	f_sysrc_set moused_enable "YES" || f_die
 	ln -fs /dev/sysmouse /dev/mouse || f_die # backwards compat
 else
Index: usr.sbin/bsdconfig/networking/devices
===================================================================
--- usr.sbin/bsdconfig/networking/devices	(revision 256169)
+++ usr.sbin/bsdconfig/networking/devices	(working copy)
@@ -148,7 +148,7 @@ while :; do
 		"$interface" "$_ipaddr" "$_netmask" "$_options" $dhcp
 
 	# Return to root menu if above returns success
-	[ $? -eq $SUCCESS ] && break
+	[ $? -eq $DIALOG_OK ] && break
 done
 
 exit $SUCCESS
Index: usr.sbin/bsdconfig/networking/share/device.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/device.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/device.subr	(working copy)
@@ -125,7 +125,7 @@ f_dialog_menu_netdev()
 	)
 	if [ ! "$interfaces" ]; then
 		f_show_msg "$msg_no_network_interfaces"
-		return $FAILURE
+		return $DIALOG_CANCEL
 	fi
 
 	#
@@ -242,12 +242,10 @@ f_dialog_menu_netdev_edit()
 		local retval=$?
 		f_dialog_data_sanitize tag
 
-		if [ $retval -eq 2 ]; then
-			# The Help button was pressed
+		if [ $retval -eq $DIALOG_HELP ]; then
 			f_show_help "$TCP_HELPFILE"
 			continue
-		elif [ $retval -ne $SUCCESS ]; then
-			# "Cancel" was chosen (-1) or ESC was pressed (255)
+		elif [ $retval -ne $DIALOG_OK ]; then
 			return $retval
 		else
 			# Only update default-item on success
@@ -298,7 +296,7 @@ f_dialog_menu_netdev_edit()
 		      	)
 		      	retval=$?
 		      	trap 'interrupt' SIGINT
-		      	if [ $retval -eq $SUCCESS ]; then
+		      	if [ $retval -eq $DIALOG_OK ]; then
 		      		dhcp=1
 		      		ipaddr=$( f_ifconfig_inet $interface )
 		      		netmask=$( f_ifconfig_netmask $interface )
@@ -312,11 +310,11 @@ f_dialog_menu_netdev_edit()
 		      fi
 		      ;;
 		3\ *) f_dialog_input_ipaddr "$interface" "$ipaddr"
-		      [ $? -eq $SUCCESS ] && dhcp= ;;
+		      [ $? -eq $DIALOG_OK ] && dhcp= ;;
 		4\ *) f_dialog_input_netmask "$interface" "$netmask"
-		      [ $? -eq $SUCCESS -a "$_netmask" ] && dhcp= ;;
+		      [ $? -eq $DIALOG_OK -a "$_netmask" ] && dhcp= ;;
 		5\ *) f_dialog_menu_media_options "$interface" "$options"
-		      [ $? -eq $SUCCESS ] && dhcp= ;;
+		      [ $? -eq $DIALOG_OK ] && dhcp= ;;
 		esac
 	done
 
@@ -383,7 +381,7 @@ f_dialog_menu_netdev_edit()
 		fi
 	fi
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/networking/share/hostname.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/hostname.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/hostname.subr	(working copy)
@@ -110,7 +110,7 @@ f_dialog_input_hostname()
 	#
 	while :; do
 		f_dialog_input hostname "$msg" "$hostname" \
-		               "$hline_alnum_punc_tab_enter" || return
+		               "$hline_alnum_punc_tab_enter" || return $?
 		# Taint-check the user's input
 		f_dialog_validate_hostname "$hostname" && break
 	done
@@ -150,7 +150,7 @@ f_dialog_input_hostname()
 		fi
 	fi
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/networking/share/ipaddr.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/ipaddr.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/ipaddr.subr	(working copy)
@@ -147,7 +147,7 @@ f_dialog_input_ipaddr()
 		local setting="$( printf "$msg_current_ipaddr" \
 		                         "$interface" "$_ipaddr" )"
 		f_noyes "$msg_nfs_mounts_may_cause_hang" "$setting" ||
-			return $FAILURE
+			return $DIALOG_CANCEL
 	fi
 
 	local msg="$( printf "$msg_please_enter_new_ip_addr" "$interface" )"
@@ -163,11 +163,11 @@ f_dialog_input_ipaddr()
 		# - User has not made any changes to the given value
 		#
 		f_dialog_input _input "$msg" "$_ipaddr" \
-		               "$hline_num_punc_tab_enter" || return
-		[ "$_ipaddr" = "$_input" ] && return $FAILURE
+		               "$hline_num_punc_tab_enter" || return $?
+		[ "$_ipaddr" = "$_input" ] && return $DIALOG_CANCEL
 
 		# Return success if NULL value was entered
-		[ "$_input" ] || return $SUCCESS
+		[ "$_input" ] || return $DIALOG_OK
 
 		# Take only the first "word" of the user's input
 		_ipaddr="$_input"
@@ -208,7 +208,7 @@ f_dialog_input_ipaddr()
 	ipaddr="$_ipaddr"
 	[ "$_netmask" ] && netmask="$_netmask"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/networking/share/media.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/media.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/media.subr	(working copy)
@@ -118,7 +118,7 @@ f_dialog_input_options()
 		local setting="$( printf "$msg_current_options" \
 		                         "$interface" "$options" )"
 		f_noyes "$msg_nfs_mounts_may_cause_hang" "$setting" ||
-			return $FAILURE
+			return $DIALOG_CANCEL
 	fi
 
 	local msg="$( printf "$msg_please_enter_mediaopts" "$interface" )"
@@ -138,7 +138,7 @@ f_dialog_input_options()
 	local retval=$?
 	f_dialog_line_sanitize _options
 
-	[ $retval -eq $SUCCESS ] && options="$_options"
+	[ $retval -eq $DIALOG_OK ] && options="$_options"
 
 	return $retval
 }
@@ -165,7 +165,7 @@ f_dialog_menu_media_options()
 		local setting="$( printf "$msg_current_options" \
 		                         "$interface" "$_options" )"
 		f_noyes "$msg_nfs_mounts_may_cause_hang" "$setting" ||
-			return $FAILURE
+			return $DIALOG_CANCEL
 	fi
 
 	#
@@ -219,7 +219,7 @@ f_dialog_menu_media_options()
 	local retval=$?
 	f_dialog_data_sanitize tag
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		options=$( eval f_dialog_menutag2item \"\$tag\" \
 		                                      $supported_media )
 		case "$options" in
Index: usr.sbin/bsdconfig/networking/share/netmask.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/netmask.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/netmask.subr	(working copy)
@@ -97,7 +97,7 @@ f_dialog_input_netmask()
 		local setting="$( printf "$msg_current_subnet" \
 		                         "$interface" "$_netmask" )"
 		f_noyes "$msg_nfs_mounts_may_cause_hang" "$setting" ||
-			return $FAILURE
+			return $DIALOG_CANCEL
 	fi
 
 	#
@@ -111,11 +111,11 @@ f_dialog_input_netmask()
 		# - User has not made any changes to the given value
 		#
 		f_dialog_input _input "$msg" "$_netmask" \
-		               "$hline_num_punc_tab_enter" || return
-		[ "$_netmask" = "$_input" ] && return $FAILURE
+		               "$hline_num_punc_tab_enter" || return $?
+		[ "$_netmask" = "$_input" ] && return $DIALOG_CANCEL
 
 		# Return success if NULL value was entered
-		[ "$_input" ] || return $SUCCESS
+		[ "$_input" ] || return $DIALOG_OK
 
 		# Take only the first "word" of the user's input
 		_netmask="$_input"
Index: usr.sbin/bsdconfig/networking/share/resolv.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/resolv.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/resolv.subr	(working copy)
@@ -195,7 +195,7 @@ f_dialog_resolv_conf_update()
 		# update with our new `domain' and `search' directives.
 		#
 		local tmpfile="$( mktemp -t "$pgm" )"
-		[ "$tmpfile" ] || return $FAILURE
+		[ "$tmpfile" ] || return $DIALOG_CANCEL
 
 		#
 		# Fixup permissions and ownership (mktemp(1) creates the
@@ -235,7 +235,8 @@ f_dialog_resolv_conf_update()
 		# Write the temporary file contents and move the temporary
 		# file into place.
 		#
-		echo "$new_contents" | tail -r > "$tmpfile" || return $FAILURE
+		echo "$new_contents" | tail -r > "$tmpfile" ||
+			return $DIALOG_CANCEL
 		f_quietly mv "$tmpfile" "$RESOLV_CONF"
 
 	fi
@@ -293,8 +294,8 @@ f_dialog_input_nameserver()
 	#
 	# Perform sanity checks
 	#
-	f_isinteger "$index" || return $FAILURE
-	[ $index -ge 0 ] || return $FAILURE
+	f_isinteger "$index" || return $DIALOG_CANCEL
+	[ $index -ge 0 ] || return $DIALOG_CANCEL
 
 	local msg
 	if [ $index -gt 0 ]; then
@@ -312,7 +313,7 @@ f_dialog_input_nameserver()
 	#
 	while :; do
 		f_dialog_input new_ns "$msg" "$ns" \
-		               "$hline_num_punc_tab_enter" || return
+		               "$hline_num_punc_tab_enter" || return $?
 
 		# Take only the first "word" of the user's input
 		new_ns="${new_ns%%[$IFS]*}"
@@ -331,7 +332,7 @@ f_dialog_input_nameserver()
 	if [ $index -eq "0" -a "$new_ns" ]; then
 		f_dialog_info "$msg_saving_nameserver"
 		printf "nameserver\t%s\n" "$new_ns" >> "$RESOLV_CONF"
-		return $SUCCESS
+		return $DIALOG_OK
 	elif [ $index -gt 0 -a "$old_ns" != "$new_ns" ]; then
 		if [ "$new_ns" ]; then
 			msg="$msg_saving_nameserver_existing"
@@ -344,7 +345,7 @@ f_dialog_input_nameserver()
 		# Create a new temporary file to write our new resolv.conf(5)
 		#
 		local tmpfile="$( mktemp -t "$pgm" )"
-		[ "$tmpfile" ] || return $FAILURE
+		[ "$tmpfile" ] || return $DIALOG_CANCEL
 
 		#
 		# Quietly fixup permissions and ownership
@@ -381,7 +382,7 @@ f_dialog_input_nameserver()
 		# Write the temporary file contents and move the temporary
 		# file into place.
 		#
-		echo "$new_contents" > "$tmpfile" || return $FAILURE
+		echo "$new_contents" > "$tmpfile" || return $DIALOG_CANCEL
 		f_quietly mv "$tmpfile" "$RESOLV_CONF"
 	fi
 }
@@ -452,7 +453,7 @@ f_dialog_menu_nameservers()
 		f_dialog_data_sanitize tag
 
 		# Return if "Cancel" was chosen (-1) or ESC was pressed (255)
-		if [ $retval -ne $SUCCESS ]; then
+		if [ $retval -ne $DIALOG_OK ]; then
 			return $retval
 		else
 			# Only update default-item on success
Index: usr.sbin/bsdconfig/networking/share/routing.subr
===================================================================
--- usr.sbin/bsdconfig/networking/share/routing.subr	(revision 256169)
+++ usr.sbin/bsdconfig/networking/share/routing.subr	(working copy)
@@ -75,7 +75,7 @@ f_dialog_input_defaultrouter()
 		local setting="$( printf "$msg_current_default_router" \
 		                         "$defaultrouter" )"
 		f_noyes "$msg_nfs_mounts_may_cause_hang" "$setting" ||
-			return $FAILURE
+			return $DIALOG_CANCEL
 	fi
 
 	#
@@ -87,8 +87,8 @@ f_dialog_input_defaultrouter()
 		               "$msg_please_enter_default_router" \
 		               "$defaultrouter" "$hline_num_punc_tab_enter"
 		retval=$?
-		[ "$defaultrouter" ] || return $SUCCESS
-		[ $retval -eq $SUCCESS ] || return $retval
+		[ "$defaultrouter" ] || return $DIALOG_OK
+		[ $retval -eq $DIALOG_OK ] || return $retval
 
 		# Taint-check the user's input
 		f_dialog_validate_ipaddr "$defaultrouter" && break
@@ -112,7 +112,7 @@ f_dialog_input_defaultrouter()
 		f_dialog_clear
 		f_yesno "$msg_activate_default_router" \
 		        "$( f_route_get_default )" "$defaultrouter"
-		if [ $? -eq $SUCCESS ]; then
+		if [ $? -eq $DIALOG_OK ]; then
 			local err
 
 			# Apply the default router/gateway
@@ -120,7 +120,7 @@ f_dialog_input_defaultrouter()
 			err=$( route add default "$defaultrouter" 2>&1 )
 			if [ $? -ne $SUCCESS ]; then
 				f_dialog_msgbox "$err"
-				return $FAILURE
+				return $DIALOG_CANCEL
 			fi
 		fi
 	fi
Index: usr.sbin/bsdconfig/password/share/password.subr
===================================================================
--- usr.sbin/bsdconfig/password/share/password.subr	(revision 256169)
+++ usr.sbin/bsdconfig/password/share/password.subr	(working copy)
@@ -114,7 +114,7 @@ f_dialog_input_password()
 		break
 	done
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/security/kern_securelevel
===================================================================
--- usr.sbin/bsdconfig/security/kern_securelevel	(revision 256169)
+++ usr.sbin/bsdconfig/security/kern_securelevel	(working copy)
@@ -131,11 +131,10 @@ while :; do
 	retval=$?
 	f_dialog_menutag_fetch mtag
 
-	if [ $retval -eq 2 ]; then
-		# The Help button was pressed
+	if [ $retval -eq $DIALOG_HELP ]; then
 		f_show_help "$SECURELEVEL_HELPFILE"
 		continue
-	elif [ $retval -ne 0 ]; then
+	elif [ $retval -ne $DIALOG_OK ]; then
 		f_die
 	fi
 
Index: usr.sbin/bsdconfig/security/security
===================================================================
--- usr.sbin/bsdconfig/security/security	(revision 256169)
+++ usr.sbin/bsdconfig/security/security	(working copy)
@@ -123,7 +123,7 @@ dialog_menu_main()
 	f_dialog_menutag_store "$menu_choice"
 
 	# Only update default-item on success
-	[ $retval -eq 0 ] && f_dialog_default_store "$menu_choice"
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
 
 	return $retval
 }
Index: usr.sbin/bsdconfig/share/common.subr
===================================================================
--- usr.sbin/bsdconfig/share/common.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/common.subr	(working copy)
@@ -560,11 +560,12 @@ f_index_file()
 
 	if [ "$lang" ]; then
 		awk -v keyword="$keyword" "$f_index_file_awk" \
-			$BSDCFG_LIBE${BSDCFG_LIBE:+/}*/INDEX.$lang && return
+			$BSDCFG_LIBE${BSDCFG_LIBE:+/}*/INDEX.$lang &&
+			return $SUCCESS
 		# No match, fall-thru to non-i18n sources
 	fi
 	awk -v keyword="$keyword" "$f_index_file_awk" \
-		$BSDCFG_LIBE${BSDCFG_LIBE:+/}*/INDEX && return
+		$BSDCFG_LIBE${BSDCFG_LIBE:+/}*/INDEX && return $SUCCESS
 
 	# No match? Fall-thru to `local' libexec sources (add-on modules)
 
@@ -571,7 +572,7 @@ f_index_file()
 	[ "$BSDCFG_LOCAL_LIBE" ] || return $FAILURE
 	if [ "$lang" ]; then
 		awk -v keyword="$keyword" "$f_index_file_awk" \
-			$BSDCFG_LOCAL_LIBE/*/INDEX.$lang && return
+			$BSDCFG_LOCAL_LIBE/*/INDEX.$lang && return $SUCCESS
 		# No match, fall-thru to non-i18n sources
 	fi
 	awk -v keyword="$keyword" "$f_index_file_awk" \
Index: usr.sbin/bsdconfig/share/device.subr
===================================================================
--- usr.sbin/bsdconfig/share/device.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/device.subr	(working copy)
@@ -49,6 +49,7 @@ f_struct_define DEVICE \
 	desc		\
 	devname		\
 	type		\
+	capacity	\
 	enabled		\
 	init		\
 	get		\
@@ -114,7 +115,7 @@ f_device_try()
 }
 
 # f_device_register $name $desc $devname $type $enabled $init_function \
-#                   $get_function $shutdown_function $private
+#                   $get_function $shutdown_function $private $capacity
 #
 # Register a device. A `structure' (see struct.subr) is created with the name
 # device_$name (so make sure $name contains only alpha-numeric characters or
@@ -128,6 +129,7 @@ f_device_register()
 {
 	local name="$1" desc="$2" devname="$3" type="$4" enabled="$5"
 	local init_func="$6" get_func="$7" shutdown_func="$8" private="$9"
+	local capacity="${10}"
 
 	f_struct_new DEVICE "device_$name" || return $FAILURE
 	device_$name set name     "$name"
@@ -139,6 +141,7 @@ f_device_register()
 	device_$name set get      "$get_func"
 	device_$name set shutdown "$shutdown_func"
 	device_$name set private  "$private"
+	device_$name set capacity "$capacity"
 
 	# Scan our global register to see if it needs ammending
 	local dev found=
@@ -196,7 +199,7 @@ f_device_get_all()
 		f_dprintf "Found a network device named %s" "$devname"
 		f_device_register $devname \
 			"$desc" "$devname" $DEVICE_TYPE_NETWORK 1 \
-			f_media_init_network "" f_media_shutdown_network ""
+			f_media_init_network "" f_media_shutdown_network "" -1
 	done
 
 	# Next, try to find all the types of devices one might use
@@ -208,6 +211,10 @@ f_device_get_all()
 		n=$(( $n + 1 ))
 		# Get the desc, type, and max (with debugging disabled)
 		# NOTE: Bypassing f_device_name_get() for efficiency
+		# ASIDE: This would be equivalent to the following:
+		# 	debug= f_device_name_get $dev desc
+		# 	debug= f_device_name_get $dev type
+		# 	debug= f_device_name_get $dev max
 		debug= f_getvar _device_desc$n desc
 		debug= f_getvar _device_type$n type
 		debug= f_getvar _device_max$n max
@@ -222,7 +229,8 @@ f_device_get_all()
 				f_device_register "${devname##*/}" "$desc" \
 					"$devname" $DEVICE_TYPE_CDROM 1 \
 					f_media_init_cdrom f_media_get_cdrom \
-					f_media_shutdown_cdrom ""
+					f_media_shutdown_cdrom "" \
+					"$( f_device_capacity "$devname" )"
 				f_dprintf "Found a CDROM device for %s" \
 				          "$devname"
 				;;
@@ -232,7 +240,8 @@ f_device_get_all()
 					"$devname" $DEVICE_TYPE_FLOPPY 1 \
 					f_media_init_floppy \
 					f_media_get_floppy \
-					f_media_shutdown_floppy ""
+					f_media_shutdown_floppy "" \
+					"$( f_device_capacity "$devname" )"
 				f_dprintf "Found a floppy device for %s" \
 				          "$devname"
 				;;
@@ -241,7 +250,8 @@ f_device_get_all()
 				f_device_register "${devname##*/}" "$desc" \
 					"$devname" $DEVICE_TYPE_USB 1 \
 					f_media_init_usb f_media_get_usb \
-					f_media_shutdown_usb ""
+					f_media_shutdown_usb "" \
+					"$( f_device_capacity "$devname" )"
 				f_dprintf "Found a USB disk for %s" "$devname"
 				;;
 			esac
@@ -254,7 +264,8 @@ f_device_get_all()
 		f_device_register "${devname##*/}" "ISO9660 file system" \
 			"$devname" $DEVICE_TYPE_CDROM 1 \
 			f_media_init_cdrom f_media_get_cdrom \
-			f_media_shutdown_cdrom ""
+			f_media_shutdown_cdrom "" \
+			"$( f_device_capacity "$devname" )"
 		f_dprintf "Found a CDROM device for %s" "$devname"
 	done
 
@@ -281,7 +292,8 @@ f_device_get_all()
 				"md(4) vnode file system" \
 				"$devname" $DEVICE_TYPE_CDROM 1 \
 				f_media_init_cdrom f_media_get_cdrom \
-				f_media_shutdown_cdrom ""
+				f_media_shutdown_cdrom "" \
+				"$( f_device_capacity "$devname" )"
 			f_dprintf "Found a CDROM device for %s" "$devname"
 			;;
 		esac
@@ -313,8 +325,13 @@ f_device_get_all()
 			continue
 		fi
 
-		f_device_register "$diskname" "" \
-		                  "/dev/$diskname" $DEVICE_TYPE_DISK 0
+		# Try and find its description
+		f_device_desc "$diskname" $DEVICE_TYPE_DISK desc
+
+		f_device_register "$diskname" "$desc" \
+		                  "/dev/$diskname" $DEVICE_TYPE_DISK 0 \
+		                  "" "" "" "" \
+		                  "$( f_device_capacity "$diskname" )"
 		f_dprintf "Found a disk device named %s" "$diskname"
 
 		# Look for existing partitions to register
@@ -327,7 +344,8 @@ f_device_get_all()
 				f_device_register "$slice" "" \
 					"/dev/$slice" $DEVICE_TYPE_DOS 1 \
 					f_media_init_dos f_media_get_dos \
-					f_media_shutdown_dos ""
+					f_media_shutdown_dos "" \
+					"$( f_device_capacity "/dev/$slice" )"
 				f_dprintf "Found a DOS partition %s" "$slice"
 				;;
 			0xa5) # FreeBSD partition
@@ -347,7 +365,9 @@ f_device_get_all()
 						$DEVICE_TYPE_UFS 1 \
 						f_media_init_ufs \
 						f_media_get_ufs \
-						f_media_shutdown_ufs ""
+						f_media_shutdown_ufs "" \
+						"$( f_device_capacity \
+							"$/dev/$part" )"
 					f_dprintf "Found a UFS partition %s" \
 					          "$part"
 				done # parts
@@ -379,10 +399,27 @@ f_device_name_get()
 	case "$__prop" in type|desc|max) : good ;;
 	*) return $FAILURE; esac
 
+	#
+	# Attempt to create an alternate-form of $__name that contains the
+	# first contiguous string of numbers replaced with `%d' for comparison
+	# against stored pattern names (see MAIN).
+	#
+	local __left="${__name%%[0-9]*}" __right="${__name#*[0-9]}" __dname=
+	if [ "$__left" != "$__name" ]; then
+		# Chop leading digits from right 'til we hit first non-digit
+		while :; do
+			case "$__right" in
+			[0-9]*) __right="${__right#[0-9]}" ;;
+			     *) break
+			esac
+		done
+		__dname="${__left}%d$__right"
+	fi
+
 	[ "$__type" = "$DEVICE_TYPE_ANY" ] && __type=
 	for __dev in $DEVICE_NAMES; do
 		__n=$(( $__n + 1 ))
-		[ "$__dev" = "$__name" ] || continue
+		[ "$__dev" = "$__name" -o "$__dev" = "$__dname" ] || continue
 		f_getvar _device_type$__n __devtype
 		[ "${__type:-$__devtype}" = "$__devtype" ] || continue
 		f_getvar _device_$__prop$__n $__var_to_set
@@ -463,6 +500,39 @@ f_device_desc()
 		fi
 	fi
 
+	#
+	# For disks, attempt to return camcontrol(8) descriptions.
+	# Otherwise fall through to below static list.
+	#
+	f_have camcontrol &&
+	[ "${__type:-$DEVICE_TYPE_DISK}" = "$DEVICE_TYPE_DISK" ] &&
+	__cp=$( camcontrol devlist 2> /dev/null | awk -v disk="$__name" '
+		$0~"(\\(|,)"disk"(,|\\))" {
+			if (!match($0, "<[^>]+>")) next
+			print substr($0, RSTART+1, RLENGTH-2)
+			found = 1
+			exit
+		}
+		END { exit ! found }
+	' ) && setvar "$__var_to_set" "$__cp" && return $SUCCESS
+
+	#
+	# Attempt to create an alternate-form of $__name that contains the
+	# first contiguous string of numbers replaced with `%d' for comparison
+	# against stored pattern names (see MAIN).
+	#
+	local __left="${__name%%[0-9]*}" __right="${__name#*[0-9]}" __dname=
+	if [ "$__left" != "$__name" ]; then
+		# Chop leading digits from right 'til we hit first non-digit
+		while :; do
+			case "$__right" in
+			[0-9]*) __right="${__right#[0-9]}" ;;
+			     *) break
+			esac
+		done
+		__dname="${__left}%d$__right"
+	fi
+
 	local __dev __devtype __n=0
 	for __dev in $DEVICE_NAMES; do
 		__n=$(( $__n + 1 ))
@@ -472,11 +542,8 @@ f_device_desc()
 			__devname=$( f_substr "$__name" 0 ${#__dev} )
 			[ "$__devname" = "$__dev" ] || continue
 		else
-			__devname="${__name%%[0-9]*}"
-			__devunit="${__name#$__devname}"
-			__devunit="${__devunit%%[!0-9]*}"
-			__devname=$( printf "$__dev" $__devunit )
-			[ "$__devname" = "$__name" ] || continue
+			[ "$__dev" = "$__name" -o "$__dev" = "$__dname" ] ||
+				continue
 		fi
 		debug= f_getvar _device_desc$__n $__var_to_set
 		return $?
@@ -552,7 +619,7 @@ f_device_find()
 f_device_init()
 {
 	local name="$1" init_func
-	device_$name get init init_func || return
+	device_$name get init init_func || return $?
 	${init_func:-:} $name
 }
 
@@ -564,7 +631,7 @@ f_device_init()
 f_device_get()
 {
 	local name="$1" file="$2" probe="$3" get_func
-	device_$name get get get_func || return
+	device_$name get get get_func || return $?
 	${get_func:-:} $name "$file" ${3+"$probe"}
 }
 
@@ -575,7 +642,7 @@ f_device_get()
 f_device_shutdown()
 {
 	local name="$1" shutdown_func
-	device_$name get shutdown shutdown_func || return
+	device_$name get shutdown shutdown_func || return $?
 	${shutdown_func:-:} $name
 }
 
@@ -597,7 +664,7 @@ f_device_menu()
 		[ "$devtype" = "$type" ] || continue
 		devs="$devs $dev"
 	done
-	[ "$devs" ] || return $FAILURE
+	[ "$devs" ] || return $DIALOG_CANCEL
 
 	local desc menu_list=
 	for dev in $devs; do
@@ -637,7 +704,7 @@ f_device_menu()
 		)
 		local retval=$?
 
-		[ $retval -ne 2 ] && break
+		[ $retval -ne $DIALOG_HELP ] && break
 			# Otherwise, the Help button was pressed
 		f_show_help "$helpfile"
 			# ...then loop back to menu
@@ -646,7 +713,7 @@ f_device_menu()
 
 	[ "$errexit" ] && set -e
 
-	if [ $retval -eq 0 ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		# Clean up the output of [X]dialog(1) and return it
 		f_dialog_data_sanitize mtag
 		echo "$mtag" >&2
@@ -655,7 +722,26 @@ f_device_menu()
 	return $retval
 }
 
+# f_device_capacity $device [$var_to_set]
 #
+# Return the capacity of $device in bytes.
+#
+f_device_capacity()
+{
+	local __dev="$1" __var_to_set="$2"
+	local __bytes
+
+	__bytes=$( diskinfo -v "$__dev" 2> /dev/null |
+		awk '/# mediasize in bytes/{print $1}' ) || __bytes=-1
+
+	if [ "$__var_to_set" ]; then
+		setvar "$__var_to_set" "$__bytes"
+	else
+		echo "$__bytes"
+	fi
+}
+
+#
 # Short-hand
 #
 f_cdrom()   {  f_device_name_set $DEVICE_TYPE_CDROM   "$1" "$2" "$3";  }
@@ -680,6 +766,7 @@ f_disk   "ipsd%d" "IBM ServeRAID RAID array"
 f_disk   "mfid%d" "LSI MegaRAID SAS array"            4
 f_disk   "mlxd%d" "Mylex RAID disk"                   4
 f_disk   "twed%d" "3ware ATA RAID array"              4
+f_disk   "vtbd%d" "VirtIO Block Device"               16
 f_floppy "fd%d"   "Floppy Drive unit A"               4
 f_serial "cuau%d" "%s on device %s (COM%d)"           16
 f_usb    "da%da"  "USB Mass Storage Device"           16
Index: usr.sbin/bsdconfig/share/dialog.subr
===================================================================
--- usr.sbin/bsdconfig/share/dialog.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/dialog.subr	(working copy)
@@ -74,6 +74,18 @@ unset XDIALOG_FORCE_AUTOSIZE
 unset XDIALOG_INFOBOX_TIMEOUT
 
 #
+# Exit codes for [X]dialog(1)
+#
+DIALOG_OK=${SUCCESS:-0}
+DIALOG_CANCEL=${FAILURE:-1}
+DIALOG_HELP=2
+DIALOG_ITEM_HELP=2
+DIALOG_EXTRA=3
+DIALOG_ITEM_HELP=4
+export DIALOG_ERROR=254
+DIALOG_ESC=255
+
+#
 # Default behavior is to call f_dialog_init() automatically when loaded.
 #
 : ${DIALOG_SELF_INITIALIZE=1}
Index: usr.sbin/bsdconfig/share/media/any.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/any.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/any.subr	(working copy)
@@ -113,11 +113,10 @@ f_media_get_type()
 		f_dialog_data_sanitize mtag
 		f_dprintf "retval=%s mtag=[%s]" $retval "$mtag"
 
-		if [ $retval -eq 2 ]; then
-			# The Help button was pressed
+		if [ $retval -eq $DIALOG_HELP ]; then
 			f_show_help "$MEDIA_HELPFILE"
 			continue
-		elif [ $retval -ne 0 ]; then
+		elif [ $retval -ne $DIALOG_OK ]; then
 			return $FAILURE
 		fi
 
Index: usr.sbin/bsdconfig/share/media/cdrom.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/cdrom.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/cdrom.subr	(working copy)
@@ -170,7 +170,7 @@ f_media_shutdown_cdrom()
 {
 	local dev="$1" err
 
-	[ "$CDROM_MOUNTED" ] || return
+	[ "$CDROM_MOUNTED" ] || return $FAILURE
 
 	if [ "$CDROM_PREVIOUSLY_MOUNTED" ]; then
 		CDROM_MOUNTED=
Index: usr.sbin/bsdconfig/share/media/common.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/common.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/common.subr	(working copy)
@@ -127,7 +127,7 @@ f_media_generic_get()
 			fi
 			[ "$probe_type" ] && return $SUCCESS
 			cat "$path"
-			return
+			return $?
 		fi
 	done
 
Index: usr.sbin/bsdconfig/share/media/dos.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/dos.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/dos.subr	(working copy)
@@ -148,7 +148,7 @@ f_media_shutdown_dos()
 {
 	local dev="$1" err
 
-	[ "$DOS_MOUNTED" ] || return
+	[ "$DOS_MOUNTED" ] || return $FAILURE
 
 	if ! err=$( umount -f "$MOUNTPOINT" 2>&1 ); then
 		err="${err#umount: }"; err="${err#*: }"
Index: usr.sbin/bsdconfig/share/media/floppy.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/floppy.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/floppy.subr	(working copy)
@@ -205,7 +205,7 @@ f_media_shutdown_floppy()
 {
 	local dev="$1" err mp
 
-	[ "$FLOPPY_MOUNTED" ] || return
+	[ "$FLOPPY_MOUNTED" ] || return $FAILURE
 
 	device_$dev get private mp
 	if ! err=$( umount -f "${mp:=$MOUNTPOINT}" 2>&1 ); then
Index: usr.sbin/bsdconfig/share/media/ftp.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/ftp.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/ftp.subr	(working copy)
@@ -213,7 +213,7 @@ f_dialog_menu_media_ftp()
 		$height $width $rows            \
 		$menu_list                      \
 		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
-	) || return $FAILURE
+	) || return $DIALOG_CANCEL
 	f_dialog_data_sanitize mtag
 
 	case "$mtag" in
@@ -224,7 +224,7 @@ f_dialog_menu_media_ftp()
 		setvar $VAR_FTP_PATH "ftp://$value"
 	esac
 	
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_media_set_ftp
@@ -740,7 +740,7 @@ f_media_init_ftp()
 			else
 				f_yesno "$msg_cant_find_distribution" \
 				        "$rel" "$ftp_host"
-				if [ $? -eq $SUCCESS ]; then
+				if [ $? -eq $DIALOG_OK ]; then
 					unset $VAR_FTP_PATH
 					f_media_set_ftp && continue
 				fi
Index: usr.sbin/bsdconfig/share/media/http.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/http.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/http.subr	(working copy)
@@ -101,7 +101,7 @@ f_dialog_menu_media_http()
 		$height $width $rows            \
 		$menu_list                      \
 		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
-	) || return $FAILURE
+	) || return $DIALOG_CANCEL
 	f_dialog_data_sanitize mtag
 
 	case "$mtag" in
@@ -112,7 +112,7 @@ f_dialog_menu_media_http()
 		setvar $VAR_HTTP_PATH "http://$value"
 	esac
 	
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_media_set_http
Index: usr.sbin/bsdconfig/share/media/nfs.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/nfs.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/nfs.subr	(working copy)
@@ -233,7 +233,7 @@ f_media_shutdown_nfs()
 {
 	local dev="$1" err
 
-	[ "$NFS_MOUNTED" ] || return
+	[ "$NFS_MOUNTED" ] || return $FAILURE
 
 	f_dprintf "Unmounting NFS partition on %s" "$MOUNTPOINT"
 	if ! err=$( umount -f "$MOUNTPOINT" 2>&1 ); then
Index: usr.sbin/bsdconfig/share/media/options.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/options.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/options.subr	(working copy)
@@ -224,11 +224,10 @@ f_media_options_menu()
 		defaultitem="$mtag"
 		f_dprintf "retval=%s mtag=[%s]" $retval "$mtag"
 
-		if [ $retval -eq 2 ]; then
-			# The Help button was pressed
+		if [ $retval -eq $DIALOG_HELP ]; then
 			f_show_help "$OPTIONS_HELPFILE"
 			continue
-		elif [ $retval -ne 0 ]; then
+		elif [ $retval -ne $DIALOG_OK ]; then
 			break # to success
 		fi
 
Index: usr.sbin/bsdconfig/share/media/tcpip.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/tcpip.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/tcpip.subr	(working copy)
@@ -471,10 +471,10 @@ f_dialog_validate_tcpip()
 	     ! f_validate_gateway "$gateway" "$ipaddr" "$netmask"; then
 		f_show_msg "$msg_invalid_gateway_ipv4_address_specified"
 	else
-		return $SUCCESS
+		return $DIALOG_OK
 	fi
 
-	return $FAILURE
+	return $DIALOG_CANCEL
 }
 
 # f_ifconfig_inet $interface [$var_to_set]
@@ -1102,7 +1102,7 @@ f_device_dialog_tcp()
 	local use_dhcp="" use_rtsol=""
 	local _ipaddr _netmask _extras
 
-	[ "$dev" ] || return $FAILURE
+	[ "$dev" ] || return $DIALOG_CANCEL
 
 	# Initialize vars from previous device values
 	local private
@@ -1125,7 +1125,6 @@ f_device_dialog_tcp()
 			unset $VAR_NONINTERACTIVE
 		fi
 
-
 		#
 		# Try a RTSOL scan if such behavior is desired.
 		# If the variable was configured and is YES, do it.
@@ -1321,7 +1320,7 @@ f_device_dialog_tcp()
 				if [ ! "$cp" ]; then
 					# User either chose "Cancel", pressed
 					# ESC, or blanked every form field
-					return $FAILURE
+					return $DIALOG_CANCEL
 				else
 					n=$( echo "$cp" | f_number_of_lines )
 					[ $n -eq 1 ] && case "$cp" in HELP*)
@@ -1404,14 +1403,12 @@ f_device_dialog_tcp()
 				f_dialog_data_sanitize cp
 				f_dprintf "retval=%u mtag=[%s]" $retval "$cp"
 
-				if [ $retval -eq 2 ]; then
-					# The Help button was pressed
+				if [ $retval -eq $DIALOG_HELP ]; then
 					f_show_help "$TCP_HELPFILE"
 					continue
-				elif [ $retval -ne 0 ]; then
-					# User chose "Cancel" or pressed ESC
+				elif [ $retval -ne $DIALOG_OK ]; then
 					f_dialog_title_restore
-					return $FAILURE
+					return $DIALOG_CANCEL
 				fi
 
 				case "$cp" in
@@ -1490,7 +1487,7 @@ f_device_dialog_tcp()
 	[ "$use_dhcp" ] ||
 		f_config_resolv # XXX this will do it on the MFS copy
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_device_scan_tcp [$var_to_set]
@@ -1586,15 +1583,15 @@ f_device_select_tcp()
 			if [ ${cnt:=0} -gt 0 ]; then
 				dev="${devs%%[$IFS]*}"
 				f_device_dialog_tcp $dev
-				if [ $? -eq $SUCCESS ]; then
+				if [ $? -eq $DIALOG_OK ]; then
 					setvar $VAR_NETWORK_DEVICE $dev
-					return $SUCCESS
+					return $DIALOG_OK
 				fi
 			fi
 		done
 
 		f_interactive && f_show_msg "$msg_no_network_devices"
-		return $FAILURE
+		return $DIALOG_CANCEL
 
 	fi # $network_dev
 
@@ -1610,7 +1607,7 @@ f_device_select_tcp()
 		if f_dialog_yesno "$msg_assume_network_is_already_configured"
 		then
 			setvar $VAR_NETWORK_DEVICE $dev
-			return $SUCCESS
+			return $DIALOG_OK
 		fi
 	fi
 
@@ -1617,11 +1614,11 @@ f_device_select_tcp()
 	local retval=$SUCCESS
 	if [ ${cnt:=0} -eq 0 ]; then
 		f_show_msg "$msg_no_network_devices"
-		retval=$FAILURE
+		retval=$DIALOG_CANCEL
 	elif [ $cnt -eq 1 ]; then
 		f_device_dialog_tcp $dev
 		retval=$?
-		[ $retval -eq $SUCCESS ] && setvar $VAR_NETWORK_DEVICE $dev
+		[ $retval -eq $DIALOG_OK ] && setvar $VAR_NETWORK_DEVICE $dev
 	else
 		local title="$msg_network_interface_information_required"
 		local prompt="$msg_please_select_ethernet_device_to_configure"
@@ -1632,15 +1629,15 @@ f_device_select_tcp()
 			"$NETWORK_DEVICE_HELPFILE" \
 			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
 		retval=$?
-		[ "$dev" ] || return $FAILURE
+		[ "$dev" ] || return $DIALOG_CANCEL
 
 		f_device_find "$dev" $DEVICE_TYPE_NETWORK devs
-		[ "$devs" ] || return $FAILURE
+		[ "$devs" ] || return $DIALOG_CANCEL
 		dev="${devs%%[$IFS]*}"
 
 		f_device_dialog_tcp $dev
 		retval=$?
-		if [ $retval -eq $SUCCESS ]; then
+		if [ $retval -eq $DIALOG_OK ]; then
 			f_struct_copy device_$dev device_network
 			setvar $VAR_NETWORK_DEVICE network
 		else
@@ -1675,7 +1672,7 @@ f_dialog_menu_select_tcp()
 			           "$name"
 		fi
 	fi
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/share/media/ufs.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/ufs.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/ufs.subr	(working copy)
@@ -177,7 +177,7 @@ f_media_shutdown_ufs()
 {
 	local dev="$1" err
 
-	[ "$UFS_MOUNTED" ] || return
+	[ "$UFS_MOUNTED" ] || return $FAILURE
 
 	if ! err=$( umount -f "$MOUNTPOINT" 2>&1 ); then
 		err="${err#umount: }"; err="${err#*: }"
Index: usr.sbin/bsdconfig/share/media/usb.subr
===================================================================
--- usr.sbin/bsdconfig/share/media/usb.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/media/usb.subr	(working copy)
@@ -158,7 +158,7 @@ f_media_shutdown_usb()
 {
 	local dev="$1" err
 
-	[ "$USB_MOUNTED" ] || return
+	[ "$USB_MOUNTED" ] || return $FAILURE
 
 	if ! err=$( umount -f "$MOUNTPOINT" 2>&1 ); then
 		err="${err#umount: }"; err="${err#*: }"
Index: usr.sbin/bsdconfig/share/mustberoot.subr
===================================================================
--- usr.sbin/bsdconfig/share/mustberoot.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/mustberoot.subr	(working copy)
@@ -176,9 +176,9 @@ f_become_root_via_sudo()
 				retval=$?
 
 				# Catch X11-related errors
-				if [ $retval -eq 255 ]; then
+				if [ $retval -eq $DIALOG_ESC ]; then
 					f_die $retval "$password"
-				elif [ $retval -ne 0 ]; then
+				elif [ $retval -ne $DIALOG_OK ]; then
 					# User cancelled
 					exit $retval
 				fi
@@ -316,10 +316,10 @@ f_authenticate_some_user()
 		retval=$?
 
 		# Catch X11-related errors
-		[ $retval -eq 255 ] && f_die $retval "$user_pass"
+		[ $retval -eq $DIALOG_ESC ] && f_die $retval "$user_pass"
 
 		# Exit if the user cancelled.
-		[ $retval -eq $SUCCESS ] || exit $retval
+		[ $retval -eq $DIALOG_OK ] || exit $retval
 
 		#
 		# Make sure the user exists and is non-root
Index: usr.sbin/bsdconfig/share/packages/packages.subr
===================================================================
--- usr.sbin/bsdconfig/share/packages/packages.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/packages/packages.subr	(working copy)
@@ -132,7 +132,7 @@ f_package_select()
 		package="$1"
 		shift 1 # package
 		for pkgsel in $SELECTED_PACKAGES; do
-			[ "$package" = "$pkgsel" ] && return
+			[ "$package" = "$pkgsel" ] && return $SUCCESS
 		done
 		SELECTED_PACKAGES="$SELECTED_PACKAGES $package"
 		f_dprintf "Added %s to selection list" "$package"
@@ -312,7 +312,7 @@ f_package_menu_categories()
 		# creates _{varcat}_ninstalled and _{varcat}_nselected
 
 	local category_list
-	debug= f_getvar "$var_to_get" category_list || return $FAILURE
+	debug= f_getvar "$var_to_get" category_list || return $DIALOG_CANCEL
 
 	# Accent the category menu list with ninstalled/nselected
 	eval f_package_accent_category_menu category_list $category_list
@@ -395,7 +395,7 @@ f_package_menu_select()
 	local defaultitem="$3"
 	local hline="$hline_arrows_tab_punc_enter"
 
-	f_isinteger "$page" || return $FAILURE
+	f_isinteger "$page" || return $DIALOG_CANCEL
 
 	local varcat
 	f_str2varname "$category" varcat
@@ -518,7 +518,7 @@ f_package_menu_select()
 	f_dialog_data_sanitize menu_choice
 	f_dialog_menutag_store "$menu_choice"
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		local item
 		item=$( eval f_dialog_menutag2item${SHOW_DESC:+_with_help} \
 		             	\"\$menu_choice\" $menu_list )
@@ -603,7 +603,7 @@ f_package_review()
 	done
 	if [ ! "$menu_list" ]; then
 		f_show_msg "$msg_no_packages_were_selected_for_extraction"
-		return $FAILURE # They might have selected this by accident
+		return $DIALOG_CANCEL # Might have selected this by accident
 	fi
 	menu_list=$( echo "$menu_list" | sort )
 
@@ -660,7 +660,7 @@ f_package_review()
 		f_package_deselect "$package"
 	done
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_package_config
@@ -693,7 +693,7 @@ f_package_config()
 		f_dprintf "retval=%u mtag=[%s]" $retval "$category"
 		category_defaultitem="$category"
 
-		[ $retval -eq $SUCCESS ] || break
+		[ $retval -eq $DIALOG_OK ] || break
 
 		# Maybe the user chose an action (like `Review')
 		case "$category" in
@@ -729,14 +729,14 @@ f_package_config()
 			# the Cancel button because stdout will be NULL.
 			# Alternatively, Xdialog(1) will terminate with 1
 			# if/when Cancel is chosen on any widget.
-			if [ $retval -eq 255 -o ! "$menu_choice" ]; then
-				# User pressed ESC or chose Cancel
+			if [ $retval -eq $DIALOG_ESC -o ! "$menu_choice" ]
+			then
 				break
-			elif [ $retval -eq 1 ]; then
+			elif [ $retval -eq $DIALOG_CANCEL ]; then
 				# Using X11, Xdialog(1) returned 1 for Cancel
 				f_show_msg "%s" "$menu_choice"
 				break
-			elif [ $retval -ne $SUCCESS ]; then
+			elif [ $retval -ne $DIALOG_OK ]; then
 				# X11-related error occurred using Xdialog(1)
 				f_show_msg "%s" "$menu_choice"
 				break
Index: usr.sbin/bsdconfig/share/strings.subr
===================================================================
--- usr.sbin/bsdconfig/share/strings.subr	(revision 256169)
+++ usr.sbin/bsdconfig/share/strings.subr	(working copy)
@@ -26,6 +26,11 @@ if [ ! "$_STRINGS_SUBR" ]; then _STRINGS_SUBR=1
 #
 # $FreeBSD$
 #
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+
 ############################################################ GLOBALS
 
 #
@@ -319,6 +324,112 @@ f_shell_unescape()
 	f_replaceall "$__string" "'\\''" "'" "$__var_to_set"
 }
 
+# f_expand_number $string [$var_to_set]
+#
+# Unformat $string into a number, optionally to be stored in $var_to_set. This
+# function follows the SI power of two convention.
+#
+# The prefixes are:
+#
+# 	Prefix	Description	Multiplier
+# 	k	kilo		1024
+# 	M	mega		1048576
+# 	G	giga		1073741824
+# 	T	tera		1099511627776
+# 	P	peta		1125899906842624
+# 	E	exa		1152921504606846976
+#
+# NOTE: Prefixes are case-insensitive.
+#
+# Upon successful completion, the value 0 is returned (or stored to
+# $var_to_set); otherwise -1. Reasons for a -1 return include:
+#
+# 	Given $string contains no digits.
+# 	An unrecognized prefix was given.
+# 	Result too large to calculate.
+#
+f_expand_number()
+{
+	local __string="$1" __var_to_set="$2"
+	local __cp __num
+
+	# Remove any leading non-digits
+	while :; do
+		__cp="$__string"
+		__string="${__cp#[!0-9]}"
+		[ "$__string" = "$__cp" ] && break
+	done
+
+	# Return `-1' if string didn't contain any digits
+	if [ ! "$__string" ]; then
+		if [ "$__var_to_set" ]; then
+			setvar "$__var_to_set" -1
+		else
+			echo -1
+		fi
+		return $FAILURE
+	fi
+
+	# Store the numbers
+	__num="${__string%%[!0-9]*}"
+
+	# Shortcut
+	if [ $__num -eq 0 ]; then
+		if [ "$__var_to_set" ]; then
+			setvar "$__var_to_set" 0
+		else
+			echo 0
+		fi
+		return $SUCCESS
+	fi
+
+	# Remove all the leading numbers from the string to get at the prefix
+	while :; do
+		__cp="$__string"
+		__string="${__cp#[0-9]}"
+		[ "$__string" = "$__cp" ] && break
+	done
+
+	# Test for invalid prefix
+	case "$__string" in
+	""|[KkMmGgTtPpEe]*) : known prefix ;;
+	*)
+		# Unknown prefix
+		if [ "$__var_to_set" ]; then
+			setvar "$__var_to_set" -1
+		else
+			echo -1
+		fi
+		return $FAILURE
+	esac
+
+	# Multiply the number out
+	case "$__string" in
+	[Kk]) __num=$(( $__num * 1024 )) ;;
+	[Mm]) __num=$(( $__num * 1048576 )) ;;
+	[Gg]) __num=$(( $__num * 1073741824 )) ;;
+	[Tt]) __num=$(( $__num * 1099511627776 )) ;;
+	[Pp]) __num=$(( $__num * 1125899906842624 )) ;;
+	[Ee]) __num=$(( $__num * 1152921504606846976 )) ;;
+	esac
+	if [ $__num -le 0 ]; then
+		# Arithmetic overflow
+		if [ "$__var_to_set" ]; then
+			setvar "$__var_to_set" -1
+		else
+			echo -1
+		fi
+		return $FAILURE
+	fi
+
+	# Return the number
+	if [ "$__var_to_set" ]; then
+		setvar "$__var_to_set" $__num
+	else
+		echo $__num
+	fi
+}
+
 ############################################################ MAIN
 
 f_dprintf "%s: Successfully loaded." strings.subr
Index: usr.sbin/bsdconfig/startup/misc
===================================================================
--- usr.sbin/bsdconfig/startup/misc	(revision 256169)
+++ usr.sbin/bsdconfig/startup/misc	(working copy)
@@ -309,10 +309,10 @@ dialog_input_value()
 	f_dialog_title_restore
 
 	# Return if user has either pressed ESC or chosen Cancel/No
-	[ $retval -eq $SUCCESS ] || return $retval
+	[ $retval -eq $DIALOG_OK ] || return $retval
 
 	value="$_input"
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
@@ -429,7 +429,7 @@ while :; do
 		;;
 	esac
 
-	[ $? -eq $SUCCESS ] || f_dialog_msgbox "$err\n"
+	[ $? -eq $DIALOG_OK ] || f_dialog_msgbox "$err\n"
 done
 
 exit $SUCCESS
Index: usr.sbin/bsdconfig/startup/rcconf
===================================================================
--- usr.sbin/bsdconfig/startup/rcconf	(revision 256169)
+++ usr.sbin/bsdconfig/startup/rcconf	(working copy)
@@ -195,7 +195,7 @@ dialog_menu_main()
 	f_dialog_menutag_store "$menu_choice"
 
 	# Only update default-item on success
-	[ $retval -eq 0 ] && f_dialog_default_store "$menu_choice"
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
 
 	return $retval
 }
@@ -236,13 +236,13 @@ while :; do
 			f_dialog_input_view_details
 			continue
 		esac
-	elif [ $retval -eq 2 ]; then
+	elif [ $retval -eq $DIALOG_HELP ]; then
 		# The ``Help'' button (labeled "Details") was pressed
 		f_dialog_input_view_details
 		continue
 	fi
 
-	[ $retval -eq 0 ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	case "$mtag" in
 	"X $msg_exit") break ;;
Index: usr.sbin/bsdconfig/startup/rcdelete
===================================================================
--- usr.sbin/bsdconfig/startup/rcdelete	(revision 256169)
+++ usr.sbin/bsdconfig/startup/rcdelete	(working copy)
@@ -232,7 +232,7 @@ dialog_menu_main()
 	f_dialog_menutag_store "$menu_choice"
 
 	# Only update default-item on success
-	[ $retval -eq 0 ] && f_dialog_default_store "$menu_choice"
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
 
 	return $retval
 }
@@ -249,7 +249,7 @@ dialog_menu_confirm_delete()
 	local menu_list # Calculated below
 	local hline="$hline_arrows_tab_enter"
 
-	[ $# -ge 1 ] || return $FAILURE
+	[ $# -ge 1 ] || return $DIALOG_CANCEL
 
 	# If asked to delete only one variable, simply ask and return
 	if [ $# -eq 1 ]; then
@@ -351,13 +351,13 @@ while :; do
 			f_dialog_input_view_details && dialog_create_main
 			continue
 		esac
-	elif [ $retval -eq 2 ]; then
+	elif [ $retval -eq $DIALOG_HELP ]; then
 		# The ``Help'' button (labeled "Details") was pressed
 		f_dialog_input_view_details && dialog_create_main
 		continue
 	fi
 
-	[ $retval -eq 0 ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	case "$mtag" in
 	"X $msg_exit_cancel") break ;;
Index: usr.sbin/bsdconfig/startup/rcvar
===================================================================
--- usr.sbin/bsdconfig/startup/rcvar	(revision 256169)
+++ usr.sbin/bsdconfig/startup/rcvar	(working copy)
@@ -158,7 +158,7 @@ dialog_menu_main()
 	f_dialog_menutag_store "$menu_choice"
 	f_dialog_default_store "$menu_choice"
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		local item
 		item=$( eval f_dialog_menutag2item${SHOW_DESC:+_with_help} \
 		         	\"\$menu_choice\" $menu_list )
Index: usr.sbin/bsdconfig/startup/share/rcconf.subr
===================================================================
--- usr.sbin/bsdconfig/startup/share/rcconf.subr	(revision 256169)
+++ usr.sbin/bsdconfig/startup/share/rcconf.subr	(working copy)
@@ -336,7 +336,7 @@ f_dialog_input_view_details()
 
 	f_dialog_title_restore
 
-	[ $retval -eq 0 ] || return $FAILURE
+	[ $retval -eq $DIALOG_OK ] || return $DIALOG_CANCEL
 
 	case "$mtag" in
 	"R $msg_reset")
@@ -465,7 +465,7 @@ f_dialog_input_rcvar()
 
 		# Return if user either pressed ESC or chosen Cancel/No
 		f_dialog_input _input "$msg_please_enter_rcvar_name" \
-		               "$_input" "$hline_alnum_tab_enter" || return
+		               "$_input" "$hline_alnum_tab_enter" || return $?
 
 		# Check for invalid entry (1of2)
 		if ! echo "$_input" | grep -q "^[[:alpha:]_]"; then
@@ -486,7 +486,7 @@ f_dialog_input_rcvar()
 
 	f_dprintf "f_dialog_input_rcvar: rcvar->[%s]" "$rcvar"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/startup/share/rcedit.subr
===================================================================
--- usr.sbin/bsdconfig/startup/share/rcedit.subr	(revision 256169)
+++ usr.sbin/bsdconfig/startup/share/rcedit.subr	(working copy)
@@ -69,11 +69,11 @@ f_dialog_rcedit()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg" "$_input" \
-	               "$hline_alnum_punc_tab_enter" || return
+	               "$hline_alnum_punc_tab_enter" || return $?
 
 	# Return if the value has not changed from current
 	local cur_val="$( f_sysrc_get "$var" )"
-	[ "$_input" = "$cur_val" ] && return $SUCCESS
+	[ "$_input" = "$cur_val" ] && return $DIALOG_OK
 
 	f_dprintf "%s: [%s]->[%s]" "$var" "$cur_val" "$_input"
 
Index: usr.sbin/bsdconfig/timezone/timezone
===================================================================
--- usr.sbin/bsdconfig/timezone/timezone	(revision 256169)
+++ usr.sbin/bsdconfig/timezone/timezone	(working copy)
@@ -226,7 +226,7 @@ if [ "$_PATH_WALL_CMOS_CLOCK" -a ! "$SKIPUTC" ]; t
 		result=$?
 	fi
 
-	if [ $result -eq 0 ]; then
+	if [ $result -eq $DIALOG_OK ]; then
 		# User chose YES
 		[ "$REALLYDOIT" ] &&
 			f_quietly rm -f "$_PATH_WALL_CMOS_CLOCK"
@@ -250,7 +250,7 @@ if [ $# -ge 1 ]; then
 	result=$?
 	f_dialog_title_restore
 
-	if [ $result -eq 0 ]; then
+	if [ $result -eq $DIALOG_OK ]; then
 		# User chose YES
 		f_install_zoneinfo_file "$default"
 		result=$?
@@ -287,7 +287,7 @@ while :; do
 		retval=$?
 		f_dialog_menutag_fetch mtag
 
-		if [ $retval -ne 0 ]; then
+		if [ $retval -ne $DIALOG_OK ]; then
 			[ "$TZ_OR_FAIL" ] && f_die
 			exit $SUCCESS
 		fi
@@ -368,7 +368,7 @@ while :; do
 			f_dialog_data_sanitize tag
 			defaultctry="$tag"
 
-			if [ $retval -ne 0 ]; then
+			if [ $retval -ne $DIALOG_OK ]; then
 				NEED_CONTINENT=1
 				continue # back to main menu
 			fi
@@ -427,7 +427,7 @@ while :; do
 		f_dialog_data_sanitize n
 		defaultzone="$n"
 
-		if [ $retval -ne 0 ]; then
+		if [ $retval -ne $DIALOG_OK ]; then
 			[ $nitems -eq 1 ] && NEED_CONTINENT=1
 			NEED_COUNTRY=1
 			continue
@@ -441,7 +441,7 @@ while :; do
 		f_confirm_zone "$real_continent/$filename" || continue
 	fi
 
-	[ $retval -eq 0 ] || continue # back to main menu
+	[ $retval -eq $DIALOG_OK ] || continue # back to main menu
 
 	if ! f_install_zoneinfo "$real_continent/$filename"; then
 		[ $nzones -lt 0 ] && NEED_COUNTRY=1
Index: usr.sbin/bsdconfig/usermgmt/groupdel
===================================================================
--- usr.sbin/bsdconfig/usermgmt/groupdel	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/groupdel	(working copy)
@@ -75,7 +75,7 @@ while :; do
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 	defaultitem="$mtag"
 
-	[ $retval -eq 0 ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	[ "$mtag" = "X $msg_exit" ] && break
 
Index: usr.sbin/bsdconfig/usermgmt/groupedit
===================================================================
--- usr.sbin/bsdconfig/usermgmt/groupedit	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/groupedit	(working copy)
@@ -75,7 +75,7 @@ while :; do
 	f_dprintf "retval=%s mtag=[%s]" $retval "$mtag"
 	defaultitem="$mtag"
 
-	[ $retval -eq 0 ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	[ "$mtag" = "X $msg_exit" ] && break
 
Index: usr.sbin/bsdconfig/usermgmt/groupinput
===================================================================
--- usr.sbin/bsdconfig/usermgmt/groupinput	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/groupinput	(working copy)
@@ -162,9 +162,9 @@ if [ "$mode" = "Add" ]; then
 	f_dialog_noyes "$msg_use_default_values_for_all_account_details"
 	retval=$?
 
-	if [ $retval -eq 255 ]; then # User pressed ESC
+	if [ $retval -eq $DIALOG_ESC ]; then
 		exit $SUCCESS
-	elif [ $retval -ne $SUCCESS ]; then
+	elif [ $retval -ne $DIALOG_OK ]; then
 		#
 		# Ask a series of questions to pre-fill the editor screen.
 		#
@@ -174,9 +174,9 @@ if [ "$mode" = "Add" ]; then
 		#
 	
 		[ "$passwdtype" = "yes" ] &&
-			{ f_dialog_input_group_password || exit 0; }
-		f_dialog_input_group_gid  || exit 0
-		f_dialog_input_group_members || exit 0
+			{ f_dialog_input_group_password || exit $SUCCESS; }
+		f_dialog_input_group_gid  || exit $SUCCESS
+		f_dialog_input_group_members || exit $SUCCESS
 	fi
 fi
 
@@ -255,13 +255,11 @@ while :; do
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 
 	# Exit if user has either pressed ESC or chosen Cancel/No
-	[ $retval -eq $SUCCESS ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	case "$mtag" in
 	X) # Exit
-	   if [ "$save_flag" ]; then
-	   	save_changes || continue
-	   fi
+	   [ "$save_flag" ] && { save_changes || continue; }
 	   break
 	   ;;
 	1) # Group Name
@@ -274,7 +272,7 @@ while :; do
 	   	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 
 	   	# Loop if user has either pressed ESC or chosen Cancel/No
-	   	[ $retval -eq $SUCCESS ] || continue
+	   	[ $retval -eq $DIALOG_OK ] || continue
 
 	   	[ "$mtag" = "X $msg_exit" ] && continue
 
Index: usr.sbin/bsdconfig/usermgmt/share/group_input.subr
===================================================================
--- usr.sbin/bsdconfig/usermgmt/share/group_input.subr	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/share/group_input.subr	(working copy)
@@ -125,15 +125,15 @@ f_dialog_input_group_name()
 
 		# Return if user has either pressed ESC or chosen Cancel/No
 		f_dialog_input _input "$msg_group" "$_input" \
-		               "$hline_alnum_tab_enter" || return
+		               "$hline_alnum_tab_enter" || return $?
 
 		# Check for no-change
-		[ "$_input" = "$_name" ] && return $SUCCESS
+		[ "$_input" = "$_name" ] && return $DIALOG_OK
 
 		# Check for reversion
 		if [ "$_input" = "$cur_group_name" ]; then
 			group_name="$cur_group_name"
-			return $SUCCESS
+			return $DIALOG_OK
 		fi
 
 		# Check for NULL entry
@@ -161,7 +161,7 @@ f_dialog_input_group_name()
 
 	f_dprintf "group_name: [%s]->[%s]" "$cur_group_name" "$group_name"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_group_password
@@ -210,7 +210,7 @@ f_dialog_input_group_password()
 		debug= f_dialog_line_sanitize _password1
 
 		# Return if user has either pressed ESC or chosen Cancel/No
-		[ $retval -eq $SUCCESS ] || return $retval
+		[ $retval -eq $DIALOG_OK ] || return $retval
 
 		_password2=$( $DIALOG \
 			--title "$DIALOG_TITLE"         \
@@ -227,7 +227,7 @@ f_dialog_input_group_password()
 		debug= f_dialog_line_sanitize _password2
 
 		# Return if user has either pressed ESC or chosen Cancel/No
-		[ $retval -eq $SUCCESS ] || return $retval
+		[ $retval -eq $DIALOG_OK ] || return $retval
 
 		# Check for password mismatch
 		if [ "$_password1" != "$_password2" ]; then
@@ -239,9 +239,9 @@ f_dialog_input_group_password()
 		if [ ! "$_password1" ]; then
 			f_dialog_yesno "$msg_disable_password_auth_for_group"
 			local retval=$?
-			if [ $retval -eq 255 ]; then # ESC was pressed
+			if [ $retval -eq $DIALOG_ESC ]; then
 				return $retval
-			elif [ $retval -eq $SUCCESS ]; then
+			elif [ $retval -eq $DIALOG_OK ]; then
 				pw_group_password_disable=1
 			else
 				continue # back to password prompt
@@ -258,7 +258,7 @@ f_dialog_input_group_password()
 	f_dprintf "group_password: [%s]->[%s]" \
 	          "$cur_group_password" "$group_password"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_group_gid [$group_gid]
@@ -273,7 +273,7 @@ f_dialog_input_group_gid()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg_group_id_leave_empty_for_default" \
-	               "$_input" "$hline_num_tab_enter" || return
+	               "$_input" "$hline_num_tab_enter" || return $?
 
 	group_gid="$_input"
 	save_flag=1
@@ -280,7 +280,7 @@ f_dialog_input_group_gid()
 
 	f_dprintf "group_gid: [%s]->[%s]" "$cur_group_gid" "$group_gid"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_group_members [$group_members]
@@ -329,7 +329,7 @@ f_dialog_input_group_members()
 		f_dprintf "retval=%u menu_choice=[%s]" $retval "$menu_choice"
 
 		# Return if user has either pressed ESC or chosen Cancel/No
-		[ $retval -eq $SUCCESS ] || return $retval
+		[ $retval -eq $DIALOG_OK ] || return $retval
 
 		local _group_members
 		case "$menu_choice" in
@@ -399,7 +399,7 @@ f_dialog_input_group_members()
 	f_dprintf "group_members: [%s]->[%s]" \
 	          "$cur_group_members" "$group_members"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/usermgmt/share/user_input.subr
===================================================================
--- usr.sbin/bsdconfig/usermgmt/share/user_input.subr	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/share/user_input.subr	(working copy)
@@ -206,7 +206,7 @@ f_dialog_input_member_groups()
 	f_dprintf "pw_member_groups: [%s]->[%s]" \
 	          "$cur_pw_member_groups" "$pw_member_groups"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_name [$name]
@@ -229,15 +229,15 @@ f_dialog_input_name()
 
 		# Return if user has either pressed ESC or chosen Cancel/No
 		f_dialog_input _input "$msg_login" "$_input" \
-		               "$hline_alnum_tab_enter" || return
+		               "$hline_alnum_tab_enter" || return $?
 
 		# Check for no-change
-		[ "$_input" = "$_name" ] && return $SUCCESS
+		[ "$_input" = "$_name" ] && return $DIALOG_OK
 
 		# Check for reversion
 		if [ "$_input" = "$cur_pw_name" ]; then
 			pw_name="$cur_pw_name"
-			return $SUCCESS
+			return $DIALOG_OK
 		fi
 
 		# Check for NULL entry
@@ -265,7 +265,7 @@ f_dialog_input_name()
 
 	f_dprintf "pw_name: [%s]->[%s]" "$cur_pw_name" "$pw_name"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_password
@@ -336,9 +336,9 @@ f_dialog_input_password()
 		if [ ! "$_password1" ]; then
 			f_dialog_yesno "$msg_disable_password_auth_for_account"
 			local retval=$?
-			if [ $retval -eq 255 ]; then # ESC was pressed
+			if [ $retval -eq $DIALOG_ESC ]; then
 				return $retval
-			elif [ $retval -eq $SUCCESS ]; then
+			elif [ $retval -eq $DIALOG_OK ]; then
 				pw_password_disable=1
 			else
 				continue # back to password prompt
@@ -354,7 +354,7 @@ f_dialog_input_password()
 
 	f_dprintf "pw_password: [%s]->[%s]" "$cur_pw_password" "$pw_password"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_gecos [$gecos]
@@ -370,7 +370,7 @@ f_dialog_input_gecos()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg_full_name" "$_input" \
-	               "$hline_alnum_punc_tab_enter" || return
+	               "$hline_alnum_punc_tab_enter" || return $?
 
 	pw_gecos="$_input"
 	save_flag=1
@@ -377,7 +377,7 @@ f_dialog_input_gecos()
 
 	f_dprintf "pw_gecos: [%s]->[%s]" "$cur_pw_gecos" "$pw_gecos"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_uid [$uid]
@@ -392,7 +392,7 @@ f_dialog_input_uid()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg_user_id_leave_empty_for_default" \
-	               "$_input" "$hline_num_tab_enter" || return
+	               "$_input" "$hline_num_tab_enter" || return $?
 
 	pw_uid="$_input"
 	save_flag=1
@@ -399,7 +399,7 @@ f_dialog_input_uid()
 
 	f_dprintf "pw_uid: [%s]->[%s]" "$cur_pw_uid" "$pw_uid"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_gid [$gid]
@@ -414,7 +414,7 @@ f_dialog_input_gid()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg_group_id_leave_empty_for_default" \
-	               "$_input" "$hline_num_tab_enter" || return
+	               "$_input" "$hline_num_tab_enter" || return $?
 
 	pw_gid="$_input"
 	save_flag=1
@@ -421,7 +421,7 @@ f_dialog_input_gid()
 
 	f_dprintf "pw_gid: [%s]->[%s]" "$cur_pw_gid" "$pw_gid"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_class [$class]
@@ -436,7 +436,7 @@ f_dialog_input_class()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg_login_class" "$_input" \
-	               "$hline_alnum_tab_enter" || return
+	               "$hline_alnum_tab_enter" || return $?
 
 	pw_class="$_input"
 	save_flag=1
@@ -443,7 +443,7 @@ f_dialog_input_class()
 
 	f_dprintf "pw_class: [%s]->[%s]" "$cur_pw_class" "$pw_class"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_expire_password [$seconds]
@@ -508,7 +508,7 @@ f_dialog_input_expire_password()
 		f_dprintf "retval=%u date_type=[%s]" $retval "$date_type"
 
 		# Return if user has either pressed ESC or chosen Cancel/No
-		[ $retval -eq $SUCCESS ] || return $retval
+		[ $retval -eq $DIALOG_OK ] || return $retval
 
 		case "$date_type" in
 		1) # Password does not expire
@@ -538,7 +538,7 @@ f_dialog_input_expire_password()
 			f_dprintf "retval=%u ret_date=[%s]" $retval "$ret_date"
 
 			# Return to menu if either ESC or Cancel/No
-			[ $retval -eq $SUCCESS ] || continue
+			[ $retval -eq $DIALOG_OK ] || continue
 
 			_input_time=
 			[ "$secs" ] && _input_time=$( date -j \
@@ -559,7 +559,7 @@ f_dialog_input_expire_password()
 			f_dprintf "retval=%u ret_time=[%s]" $retval "$ret_time"
 
 			# Return to menu if either ESC or Cancel/No
-			[ $retval -eq $SUCCESS ] || continue
+			[ $retval -eq $DIALOG_OK ] || continue
 
 			_input=$( date \
 			          	-j -f "%d/%m/%Y %T" \
@@ -627,7 +627,7 @@ f_dialog_input_expire_password()
 	f_dprintf "pw_password_expire: [%s]->[%s]" \
 	          "$cur_pw_password_expire" "$pw_password_expire"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_expire_account [$seconds]
@@ -692,7 +692,7 @@ f_dialog_input_expire_account()
 		f_dprintf "retval=%u date_type=[%s]" $retval "$date_type"
 
 		# Return if user has either pressed ESC or chosen Cancel/No
-		[ $retval -eq $SUCCESS ] || return $retval
+		[ $retval -eq $DIALOG_OK ] || return $retval
 
 		case "$date_type" in
 		1) # Account does not expire
@@ -722,7 +722,7 @@ f_dialog_input_expire_account()
 			f_dprintf "retval=%u ret_date=[%s]" $retval "$ret_date"
 
 			# Return to menu if either ESC or Cancel/No
-			[ $retval -eq $SUCCESS ] || continue
+			[ $retval -eq $DIALOG_OK ] || continue
 
 			_input_time=
 			[ "$secs" ] && _input_time=$( date -j \
@@ -743,7 +743,7 @@ f_dialog_input_expire_account()
 			f_dprintf "retval=%u ret_time=[%s]" $retval "$ret_time"
 
 			# Return to menu if either ESC or Cancel/No
-			[ $retval -eq $SUCCESS ] || continue
+			[ $retval -eq $DIALOG_OK ] || continue
 
 			_input=$( date \
 			          	-j -f "%d/%m/%Y %T" \
@@ -811,7 +811,7 @@ f_dialog_input_expire_account()
 	f_dprintf "pw_account_expire: [%s]->[%s]" \
 	          "$cur_pw_account_expire" "$pw_account_expire"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_home_dir [$home_dir]
@@ -826,7 +826,7 @@ f_dialog_input_home_dir()
 
 	# Return if user has either pressed ESC or chosen Cancel/No
 	f_dialog_input _input "$msg_home_directory" "$_input" \
-	               "$hline_alnum_punc_tab_enter" || return
+	               "$hline_alnum_punc_tab_enter" || return $?
 
 	pw_home_dir="$_input"
 	save_flag=1
@@ -833,7 +833,7 @@ f_dialog_input_home_dir()
 
 	f_dprintf "pw_home_dir: [%s]->[%s]" "$cur_pw_home_dir" "$pw_home_dir"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 # f_dialog_input_home_create
@@ -850,7 +850,7 @@ f_dialog_input_home_create()
 	f_dialog_yesno "$msg_create_home_directory"
 	retval=$?
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		pw_home_create="$msg_yes"
 	else
 		pw_home_create="$msg_no"
@@ -860,7 +860,7 @@ f_dialog_input_home_create()
 	f_dprintf "pw_home_create: [%s]->[%s]" \
 	          "$cur_pw_home_create" "$pw_home_create"
 
-	[ $retval -ne 255 ] # return failure if user pressed ESC
+	[ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC
 }
 
 # f_dialog_input_group_delete
@@ -893,7 +893,7 @@ f_dialog_input_group_delete()
 	fi
 	retval=$?
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		pw_group_delete="$msg_yes"
 	else
 		pw_group_delete="$msg_no"
@@ -903,7 +903,7 @@ f_dialog_input_group_delete()
 	f_dprintf "pw_group_delete: [%s]->[%s]" \
 	          "$cur_pw_group_delete" "$pw_group_delete"
 
-	[ $retval -ne 255 ] # return failure if user pressed ESC
+	[ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC
 }
 
 # f_dialog_input_home_delete
@@ -920,7 +920,7 @@ f_dialog_input_home_delete()
 	f_dialog_yesno "$msg_delete_home_directory"
 	retval=$?
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		pw_home_delete="$msg_yes"
 	else
 		pw_home_delete="$msg_no"
@@ -930,7 +930,7 @@ f_dialog_input_home_delete()
 	f_dprintf "pw_home_delete: [%s]->[%s]" \
 	          "$cur_pw_home_delete" "$pw_home_delete"
 
-	[ $retval -ne 255 ] # return failure if user pressed ESC
+	[ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC
 }
 
 # f_dialog_input_dotfiles_create
@@ -948,7 +948,7 @@ f_dialog_input_dotfiles_create()
 	f_dialog_yesno "$msg_create_dotfiles"
 	retval=$?
 
-	if [ $retval -eq $SUCCESS ]; then
+	if [ $retval -eq $DIALOG_OK ]; then
 		pw_dotfiles_create="$msg_yes"
 	else
 		pw_dotfiles_create="$msg_no"
@@ -958,7 +958,7 @@ f_dialog_input_dotfiles_create()
 	f_dprintf "pw_dotfiles_create: [%s]->[%s]" \
 	          "$cur_pw_dotfiles_create" "$pw_dotfiles_create"
 
-	[ $retval -ne 255 ] # return failure if user pressed ESC
+	[ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC
 }
 
 # f_dialog_input_shell [$shell]
@@ -1015,7 +1015,7 @@ f_dialog_input_shell()
 
 	f_dprintf "pw_shell: [%s]->[%s]" "$cur_pw_shell" "$pw_shell"
 
-	return $SUCCESS
+	return $DIALOG_OK
 }
 
 ############################################################ MAIN
Index: usr.sbin/bsdconfig/usermgmt/userdel
===================================================================
--- usr.sbin/bsdconfig/usermgmt/userdel	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/userdel	(working copy)
@@ -75,7 +75,7 @@ while :; do
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 	defaultitem="$mtag"
 
-	[ $retval -eq 0 ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	[ "$mtag" = "X $msg_exit" ] && break
 
Index: usr.sbin/bsdconfig/usermgmt/useredit
===================================================================
--- usr.sbin/bsdconfig/usermgmt/useredit	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/useredit	(working copy)
@@ -75,7 +75,7 @@ while :; do
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 	defaultitem="$mtag"
 
-	[ $retval -eq 0 ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	[ "$mtag" = "X $msg_exit" ] && break
 
Index: usr.sbin/bsdconfig/usermgmt/userinput
===================================================================
--- usr.sbin/bsdconfig/usermgmt/userinput	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/userinput	(working copy)
@@ -257,9 +257,9 @@ if [ "$mode" = "Add" ]; then
 	f_dialog_noyes "$msg_use_default_values_for_all_account_details"
 	retval=$?
 
-	if [ $retval -eq 255 ]; then # User pressed ESC
+	if [ $retval -eq $DIALOG_ESC ]; then
 		exit $SUCCESS
-	elif [ $retval -ne $SUCCESS ]; then
+	elif [ $retval -ne $DIALOG_OK ]; then
 		#
 		# Ask a series of questions to pre-fill the editor screen.
 		#
@@ -431,7 +431,7 @@ while :; do
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 
 	# Exit if user has either pressed ESC or chosen Cancel/No
-	[ $retval -eq $SUCCESS ] || f_die
+	[ $retval -eq $DIALOG_OK ] || f_die
 
 	case "$mtag" in
 	X) # Exit
@@ -450,7 +450,7 @@ while :; do
 	   	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 
 	   	# Loop if user has either pressed ESC or chosen Cancel/No
-	   	[ $retval -eq $SUCCESS ] || continue
+	   	[ $retval -eq $DIALOG_OK ] || continue
 
 	   	[ "$mtag" = "X $msg_exit" ] && continue
 
Index: usr.sbin/bsdconfig/usermgmt/usermgmt
===================================================================
--- usr.sbin/bsdconfig/usermgmt/usermgmt	(revision 256169)
+++ usr.sbin/bsdconfig/usermgmt/usermgmt	(working copy)
@@ -100,7 +100,7 @@ dialog_menu_main()
 	f_dialog_menutag_store "$menu_choice"
 
 	# Only update default-item on success
-	[ $retval -eq 0 ] && f_dialog_default_store "$menu_choice"
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
 
 	return $retval
 }
@@ -136,11 +136,10 @@ while :; do
 	f_dialog_menutag_fetch mtag
 	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
 
-	if [ $retval -eq 2 ]; then
-		# The Help button was pressed
+	if [ $retval -eq $DIALOG_HELP ]; then
 		f_show_help "$USERMGMT_HELPFILE"
 		continue
-	elif [ $retval -ne $SUCCESS ]; then
+	elif [ $retval -ne $DIALOG_OK ]; then
 		f_die
 	fi
 
Index: usr.sbin/bsdinstall/bsdinstall
===================================================================
--- usr.sbin/bsdinstall/bsdinstall	(revision 256169)
+++ usr.sbin/bsdinstall/bsdinstall	(working copy)
@@ -28,6 +28,7 @@
 
 : ${BSDINSTALL_LOG="/tmp/bsdinstall_log"}; export BSDINSTALL_LOG
 : ${BSDINSTALL_TMPETC="/tmp/bsdinstall_etc"}; export BSDINSTALL_TMPETC
+: ${BSDINSTALL_TMPBOOT="/tmp/bsdinstall_boot"}; export BSDINSTALL_TMPBOOT
 : ${PATH_FSTAB="$BSDINSTALL_TMPETC/fstab"}; export PATH_FSTAB
 : ${BSDINSTALL_DISTDIR="/usr/freebsd-dist"}; export BSDINSTALL_DISTDIR
 : ${BSDINSTALL_CHROOT="/mnt"}; export BSDINSTALL_CHROOT
@@ -35,5 +36,6 @@
 VERB=${1:-auto}; shift
 
 [ -d "$BSDINSTALL_TMPETC" ] || mkdir -p "$BSDINSTALL_TMPETC"
+[ -d "$BSDINSTALL_TMPBOOT" ] || mkdir -p "$BSDINSTALL_TMPBOOT"
 echo "Running installation step: $VERB $@" >> "$BSDINSTALL_LOG"
 exec "/usr/libexec/bsdinstall/$VERB" "$@" 2>> "$BSDINSTALL_LOG"
Index: usr.sbin/bsdinstall/scripts/Makefile
===================================================================
--- usr.sbin/bsdinstall/scripts/Makefile	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/Makefile	(working copy)
@@ -2,7 +2,7 @@
 
 SCRIPTS= auto adduser checksum config docsinstall hostname jail keymap \
 	 mirrorselect mount netconfig netconfig_ipv4 netconfig_ipv6 rootpass \
-	 script services time umount wlanconfig
+	 script services time umount wlanconfig zfsboot
 BINDIR= /usr/libexec/bsdinstall
 
 NO_MAN=	true
Index: usr.sbin/bsdinstall/scripts/auto
===================================================================
--- usr.sbin/bsdinstall/scripts/auto	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/auto	(working copy)
@@ -93,24 +93,46 @@ fi
 rm $PATH_FSTAB
 touch $PATH_FSTAB
 
-dialog --backtitle "FreeBSD Installer" --title "Partitioning" --extra-button \
-    --extra-label "Manual" --ok-label "Guided" --cancel-label "Shell" \
-    --yesno "Would you like to use the guided partitioning tool (recommended for beginners) or to set up partitions manually (experts)? You can also open a shell and set up partitions entirely by hand." 0 0
+PMODES="\
+Guided \"Partitioning Tool (Recommended for Beginners)\" \
+Manual \"Manually Configure Partitions (Expert)\" \
+Shell \"Open a shell and partition by hand\""
 
-case $? in
-0)	# Guided
+CURARCH=$( uname -m )
+case $CURARCH in
+	amd64|i386)	# Booting ZFS Supported
+		PMODES="$PMODES ZFS \"Automatic Root-on-ZFS (Experimental)\""
+		;;
+	*)		# Booting ZFS Unspported
+		;;
+esac
+
+exec 3>&1
+PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \
+	--title "Partitioning" \
+	--menu "How would you like to partition your disk?" \
+	0 0 0 2>&1 1>&3`
+if [ $? -eq $DIALOG_CANCEL ]; then exit 1; fi
+exec 3>&-
+
+case "$PARTMODE" in
+"Guided")	# Guided
 	bsdinstall autopart || error
 	bsdinstall mount || error
 	;;
-1)	# Shell
+"Shell")	# Shell
 	clear
 	echo "Use this shell to set up partitions for the new system. When finished, mount the system at $BSDINSTALL_CHROOT and place an fstab file for the new system at $PATH_FSTAB. Then type 'exit'. You can also enter the partition editor at any time by entering 'bsdinstall partedit'."
 	sh 2>&1
 	;;
-3)	# Manual
+"Manual")	# Manual
 	bsdinstall partedit || error
 	bsdinstall mount || error
 	;;
+"ZFS")	# ZFS
+	bsdinstall zfsboot || error
+	bsdinstall mount || error
+	;;
 *)
 	error
 	;;
Index: usr.sbin/bsdinstall/scripts/config
===================================================================
--- usr.sbin/bsdinstall/scripts/config	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/config	(working copy)
@@ -31,6 +31,11 @@ rm $BSDINSTALL_TMPETC/rc.conf.*
 
 cp $BSDINSTALL_TMPETC/* $BSDINSTALL_CHROOT/etc
 
+cat $BSDINSTALL_TMPBOOT/loader.conf.* >> $BSDINSTALL_TMPBOOT/loader.conf
+rm $BSDINSTALL_TMPBOOT/loader.conf.*
+
+cp $BSDINSTALL_TMPBOOT/* $BSDINSTALL_CHROOT/boot
+
 # Set up other things from installed config
 chroot $BSDINSTALL_CHROOT /usr/bin/newaliases
 
Index: usr.sbin/bsdinstall/scripts/keymap
===================================================================
--- usr.sbin/bsdinstall/scripts/keymap	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/keymap	(working copy)
@@ -1,6 +1,7 @@
 #!/bin/sh
 #-
 # Copyright (c) 2011 Nathan Whitehorn
+# Copyright (c) 2013 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -25,11 +26,159 @@
 # SUCH DAMAGE.
 #
 # $FreeBSD$
+#
+############################################################ INCLUDES
+ 
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." "$0"
+f_include $BSDCFG_SHARE/dialog.subr
 
-kbdcontrol -d >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-	dialog --backtitle "FreeBSD Installer" --title "Keymap Selection" \
-	    --yesno "Would you like to set a non-default key mapping for your keyboard?" 0 0 || exit 0
-	exec 3>&1
-	kbdmap 2>&1 1>&3 | grep 'keymap=' > $BSDINSTALL_TMPETC/rc.conf.keymap
-fi
+############################################################ CONFIGURATION
+
+#
+# Default file to store keymap selection in
+#
+: ${KEYMAPFILE:=$BSDINSTALL_TMPETC/rc.conf.keymap}
+
+#
+# Default path to keymap INDEX containing descriptions
+#
+: ${MAPDESCFILE:=/usr/share/syscons/keymaps/INDEX.keymaps}
+
+############################################################ GLOBALS
+
+#
+# Strings that should be moved to an i18n file and loaded with f_include_lang()
+#
+msg_change_keymap="Change keymap"
+msg_current_keyboard_mapping_is="The current keyboard mapping is:\n%s"
+msg_default="default"
+msg_freebsd_installer="FreeBSD Installer"
+msg_keymap_selection="Keymap Selection"
+msg_ok="OK"
+msg_test_keymap="Test keymap"
+msg_test_the_keymap_by_typing="Test the keymap by typing letters, numbers, and symbols.  Characters should match the labels on the keyboard keys.\nPress Enter to stop testing."
+msg_use_this_keymap="Use this keymap"
+
+############################################################ FUNCTIONS
+
+# dialog_menu_main
+#
+# Display the dialog(1)-based application main menu.
+#
+dialog_menu_main()
+{
+	local title="$DIALOG_TITLE"
+	local btitle="$DIALOG_BACKTITLE"
+	local prompt= # Calculated below
+	local hline=
+
+	local mapdesc="$msg_default" keymap
+	if [ -s "$KEYMAPFILE" ]; then
+		# Get the current keymap and a description to display
+		keymap=$( awk '/keymap=/{sub(/^.*=/,"");gsub(/"/,"");print}' \
+			"$KEYMAPFILE" )
+		mapdesc=$( awk -v keymap="$keymap" len=${#keymap} '
+			substr($0,0,len+4)==keymap":en:"{
+				if (length($0) < len+5) continue
+				print substr($0, len+5) " (" keymap ")"
+				exit
+			}' "$MAPDESCFILE" )
+	fi
+	prompt=$( printf "$msg_current_keyboard_mapping_is" "$mapdesc" )
+
+	local height width
+	f_dialog_buttonbox_size height width \
+		"$title" "$btitle" "$prompt" "$hline"
+
+	[ $width -ge 56 ] || width=56
+
+	$DIALOG \
+		--title "$title"                    \
+		--backtitle "$btitle"               \
+		--ok-label "$msg_use_this_keymap"   \
+		--cancel-label "$msg_change_keymap" \
+		--extra-button                      \
+		--extra-label "$msg_test_keymap"    \
+		--yesno "$prompt" $height $width    \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+}
+
+# dialog_keymap_test
+#
+# Display an input box (without cancel button) for the user to test keyboard
+# input and return. Always returns success.
+#
+dialog_keymap_test()
+{
+	local title= # Calculated below
+	local btitle= # Calculated below
+	local prompt="$msg_test_the_keymap_by_typing"
+	local hline=
+
+	f_dialog_title "$msg_test_keymap"
+	title="$DIALOG_TITLE"
+	btitle="$DIALOG_BACKTITLE"
+	f_dialog_title_restore
+
+	local height width
+	f_dialog_inputbox_size height width \
+		"$title" "$btitle" "$prompt" "" "$hline"
+
+	$DIALOG \
+		--title "$title"      \
+		--backtitle "$btitle" \
+		--hline "$hline"      \
+		--ok-label "$msg_ok"  \
+		--no-cancel           \
+		--inputbox "$prompt"  \
+		$height $width        \
+		2>/dev/null >&$DIALOG_TERMINAL_PASSTHRU_FD
+
+	return $DIALOG_OK
+}
+
+############################################################ MAIN
+
+#
+# Initialize
+#
+f_dialog_title "$msg_keymap_selection"
+f_dialog_backtitle "$msg_freebsd_installer"
+
+#
+# Die immediately if we can't dump the current keyboard map
+#
+error=$( kbdcontrol -d 2>&1 > /dev/null ) || f_die $FAILURE "%s" "$error"
+
+# Capture Ctrl-C for clean-up
+trap 'rm -f $KEYMAPFILE; exit $FAILURE' SIGINT
+
+#
+# Loop until the user has finalized their selection
+#
+while :; do
+	dialog_menu_main
+	retval=$?
+	f_dprintf "retval=%u" $retval
+
+	[ $retval -eq $DIALOG_OK ] && break
+
+	case $retval in
+	$DIALOG_ESC)
+		rm -f "$KEYMAPFILE"
+		exit 1 ;; # Exit with an error so bsdinstall restarts
+	$DIALOG_CANCEL)
+		# User chose ``Change keymap'' option
+		kbdmap 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD |
+			grep 'keymap=' > "$KEYMAPFILE" ;;
+	$DIALOG_EXTRA)
+		# User chose ``Test keymap'' option
+		dialog_keymap_test ;;
+	esac
+done
+
+################################################################################
+# END
+################################################################################
Index: usr.sbin/bsdinstall/scripts/netconfig
===================================================================
--- usr.sbin/bsdinstall/scripts/netconfig	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/netconfig	(working copy)
@@ -41,11 +41,19 @@ DIALOG_TAGS=""
 : ${DIALOG_ITEM_HELP=4}
 : ${DIALOG_ESC=255}
 
+# Do a dirty check to see if this a wireless interface -- there should be a
+# better way
+is_wireless_if() {
+	ifconfig $1 | grep -q 'media: IEEE 802.11 Wireless'
+}
+
+
 for IF in `ifconfig -l`; do
 	test "$IF" = "lo0" && continue
 	(ifconfig -g wlan | egrep -wq $IF) && continue
 	INTERFACES="$INTERFACES $IF"
 	DESC=`sysctl -n dev.$(echo $IF | sed -E 's/([[:alpha:]]*)([[:digit:]]*)/\1.\2/g').%desc`
+	is_wireless_if $IF && echo $DESC | grep -iqv wireless && DESC="Wireless $DESC"
 	DIALOG_TAGS="$DIALOG_TAGS $IF \"$DESC\""
 done
 
@@ -63,10 +71,8 @@ exec 3>&-
 
 : > $BSDINSTALL_TMPETC/._rc.conf.net
 
-# Do a dirty check to see if this a wireless interface -- there should be a
-# better way
 IFCONFIG_PREFIX=""
-if ifconfig $INTERFACE | grep -q 'media: IEEE 802.11 Wireless'; then
+if is_wireless_if $INTERFACE; then
 	NEXT_WLAN_IFACE=wlan0	# XXX
 	echo wlans_$INTERFACE=\"$NEXT_WLAN_IFACE\" >> $BSDINSTALL_TMPETC/._rc.conf.net
 	IFCONFIG_PREFIX="WPA "
@@ -90,14 +96,18 @@ case $? in
 esac
 
 if [ ${IPV4_AVAIL} -eq 1 ]; then
-	dialog --backtitle 'FreeBSD Installer' --title 'Network Configuration' \
-	    --yesno 'Would you like to configure IPv4 for this interface?' 0 0
-	if [ $? -eq $DIALOG_OK ]; then
-		bsdinstall netconfig_ipv4 ${INTERFACE} "${IFCONFIG_PREFIX}" || \
-		exec $0
-	else
-		IPV4_AVAIL=0
-	fi
+	bsdinstall netconfig_ipv4 ${INTERFACE} "${IFCONFIG_PREFIX}"
+	case $? in
+		0)	#OK
+			break
+			;;
+		3)	#No ipv4
+			IPV4_AVAIL=0
+			;;
+		*)	#Error
+			exec $0
+			;;
+	esac
 fi
 # In case wlanconfig left an option and we do not support IPv4 we need to write
 # it out on its own.  We cannot write it out with IPv6 as that suffix.
Index: usr.sbin/bsdinstall/scripts/netconfig_ipv4
===================================================================
--- usr.sbin/bsdinstall/scripts/netconfig_ipv4	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/netconfig_ipv4	(working copy)
@@ -43,32 +43,49 @@ case "${INTERFACE}" in
 	;;
 esac
 
-dialog --backtitle 'FreeBSD Installer' --title 'Network Configuration' --yesno 'Would you like to use DHCP to configure this interface?' 0 0
-if [ $? -eq $DIALOG_OK ]; then
-	echo ifconfig_$INTERFACE=\"${IFCONFIG_PREFIX}DHCP\" >> $BSDINSTALL_TMPETC/._rc.conf.net
-
-	if [ ! -z $BSDINSTALL_CONFIGCURRENT ]; then
-		dialog --backtitle 'FreeBSD Installer' --infobox "Acquiring DHCP lease..." 0 0
-		dhclient $INTERFACE 2>> $BSDINSTALL_LOG
-		if [ $? -ne 0 ]; then
-			dialog --backtitle 'FreeBSD Installer' --msgbox "DHCP lease acquisition failed." 0 0
-			exec $0 ${INTERFACE} "${IFCONFIG_PREFIX}"
-		fi
-	fi
-	exit 0
-fi
-
 IP_ADDRESS=`ifconfig $INTERFACE inet | awk '/inet/ {printf("%s\n", $2); }'`
 NETMASK=`ifconfig $INTERFACE inet | awk '/inet/ {printf("%s\n", $4); }'`
 ROUTER=`netstat -rn -f inet | awk '/default/ {printf("%s\n", $2);}'`
 
 exec 3>&1
-IF_CONFIG=$(dialog --backtitle 'FreeBSD Installer' --title 'Network Configuration' --form 'Static Network Interface Configuration' 0 0 0 \
+
+
+IF_CONFIG=$(dialog --backtitle 'FreeBSD Installer' \
+	--title 'Network Configuration' \
+	--extra-button --extra-label "No IPv4" --defaultno \
+	--cancel-label "DHCP" --ok-label "Static" \
+	--form 'Network Interface Configuration' 0 0 0 \
 	'IP Address' 1 0 "$IP_ADDRESS" 1 20 16 0 \
 	'Subnet Mask' 2 0 "$NETMASK" 2 20 16 0 \
 	'Default Router' 3 0 "$ROUTER" 3 20 16 0 \
 2>&1 1>&3)
-if [ $? -eq $DIALOG_CANCEL ]; then exit 1; fi
+case $? in
+	0)	# Static
+		break
+		;;
+	1)	# DHCP
+		echo ifconfig_$INTERFACE=\"${IFCONFIG_PREFIX}DHCP\" >> \
+		    $BSDINSTALL_TMPETC/._rc.conf.net
+
+		if [ ! -z $BSDINSTALL_CONFIGCURRENT ]; then
+		    dialog --backtitle 'FreeBSD Installer' \
+			--infobox "Acquiring DHCP lease..." 0 0
+		    dhclient $INTERFACE 2>> $BSDINSTALL_LOG
+		    if [ $? -ne 0 ]; then
+			dialog --backtitle 'FreeBSD Installer' \
+			    --msgbox "DHCP lease acquisition failed." 0 0
+			    exec $0 ${INTERFACE} "${IFCONFIG_PREFIX}"
+		    fi
+		fi
+		exit 0
+		;;
+	3)	# No IPv4
+		exit 3
+		;;
+	*)	
+		error
+		;;
+esac
 exec 3>&-
 
 echo $INTERFACE $IF_CONFIG | 
@@ -85,4 +102,3 @@ if [ ! -z $BSDINSTALL_CONFIGCURRENT ]; then
 		route add -inet default $defaultrouter
 	fi
 fi
-
Index: usr.sbin/bsdinstall/scripts/services
===================================================================
--- usr.sbin/bsdinstall/scripts/services	(revision 256169)
+++ usr.sbin/bsdinstall/scripts/services	(working copy)
@@ -46,22 +46,23 @@ DAEMONS=$(dialog --backtitle "FreeBSD Installer" \
 	moused	"PS/2 mouse pointer on console" ${moused_enable:-off} \
 	ntpd	"Synchronize system and network time" ${ntpd_enable:-off} \
 	powerd	"Adjust CPU frequency dynamically if supported" ${powerd_enable:-off} \
+	dumpdev "Would you like to enable crash dumps to /var ?" ${dumpdev:-on} \
 2>&1 1>&3)
 exec 3>&-
 
+local havedump=
 for daemon in $DAEMONS; do
+	if [ "$daemon" == "dumpdev" ]; then
+		havedump=1
+		echo \# Set dumpdev to \"AUTO\" to enable crash dumps, \
+			\"NO\" to disable >> \ 
+			$BSDINSTALL_TMPETC/rc.conf.services
+		echo dumpdev=\"AUTO\" >> $BSDINSTALL_TMPETC/rc.conf.services
+		continue
+	fi
 	echo ${daemon}_enable=\"YES\" >> $BSDINSTALL_TMPETC/rc.conf.services
 done
 
-echo \# Set dumpdev to \"AUTO\" to enable crash dumps, \"NO\" to disable >> \
-	$BSDINSTALL_TMPETC/rc.conf.services
-
-dialog --backtitle "FreeBSD Installer" --title "Dumpdev Configuration" \
-	--nocancel --yesno \
-	"Would you like to enable crash dumps?  If you start having problems with the system it can help the FreeBSD developers debug the problem.  But the crash dumps can take up a lot of disk space in /var." 0 0
-
-if [ $? -eq $DIALOG_OK ]; then
-	echo dumpdev=\"AUTO\" >> $BSDINSTALL_TMPETC/rc.conf.services
-else
+if [ ! "$havedump" ]; then
 	echo dumpdev=\"NO\" >> $BSDINSTALL_TMPETC/rc.conf.services
 fi
Index: usr.sbin/bsdinstall/scripts/zfsboot
===================================================================
--- usr.sbin/bsdinstall/scripts/zfsboot	(revision 0)
+++ usr.sbin/bsdinstall/scripts/zfsboot	(working copy)
@@ -0,0 +1,956 @@
+#!/bin/sh
+#-
+# Copyright (c) 2013 Allan Jude
+# Copyright (c) 2013 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." "$0"
+f_include $BSDCFG_SHARE/device.subr
+f_include $BSDCFG_SHARE/dialog.subr
+
+############################################################ CONFIGURATION
+
+#
+# Default name of the boot-pool
+#
+: ${ZFSBOOT_POOL_NAME:=zroot}
+
+#
+# Default name for the boot environment parent dataset
+#
+: ${ZFSBOOT_BEROOT_NAME:=bootenv}
+
+#
+# Default name for the primany boot environment
+#
+: ${ZFSBOOT_BOOTFS_NAME:=default}
+
+#
+# Default Virtual Device (vdev) type to create
+#
+: ${ZFSBOOT_VDEV_TYPE:=stripe}
+
+#
+# Should we use gnop(8) to configure a transparent mapping to 4K sectors?
+#
+: ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:=1}
+
+#
+# Should we use geli(8) to encrypt the drives?
+#
+: ${ZFSBOOT_GELI_ENCRYPTION:=}
+
+#
+# Default name the unencrypted pool when using geli(8) to encrypt the drives
+#
+: ${ZFSBOOT_GELI_POOL_NAME:=bootpool}
+
+#
+# Default size for the unencrypted boot pool when using geli(8)
+#
+: ${ZFSBOOT_GELI_BOOT_SIZE:=2g}
+
+#
+# Default path to the geli(8) keyfile used in drive encryption
+#
+: ${ZFSBOOT_GELI_KEY_FILE:=/boot/encryption.key}
+
+#
+# Default disks to use (always empty unless being scripted)
+#
+: ${ZFSBOOT_DISKS:=}
+
+#
+# Default partitioning scheme to use on disks
+#
+: ${ZFSBOOT_PARTITION_SCHEME:=GPT}
+
+#
+# How much swap to put on each block device in the boot zpool
+# NOTE: Value passed to gpart(8); which supports SI unit suffixes.
+#
+: ${ZFSBOOT_SWAP_SIZE:=2g}
+
+#
+# Default ZFS layout for root zpool
+#
+# NOTE: Requires /tmp, /var/tmp, /$ZFSBOOT_BOOTFS_NAME/$ZFSBOOT_BOOTFS_NAME
+# NOTE: Anything after pound/hash character [#] is ignored as a comment.
+#
+f_isset ZFSBOOT_DATASETS || ZFSBOOT_DATASETS="
+	# DATASET	OPTIONS (comma or space separated; or both)
+
+	# Boot Environment [BE] root and default boot dataset
+	/$ZFSBOOT_BEROOT_NAME				mountpoint=none
+	/$ZFSBOOT_BEROOT_NAME/$ZFSBOOT_BOOTFS_NAME	mountpoint=/
+
+	# Compress /tmp, allow exec but not setuid
+	/tmp		mountpoint=/tmp,compression=lz4,exec=on,setuid=off
+
+	# Don't mount /usr so that 'base' files go to the BEROOT
+	/usr		mountpoint=/usr,canmount=off
+
+	/usr/local # local files (i.e. from packages) separate from base system
+
+	# Home directories separated so they are common to all BEs
+	/usr/home	setuid=off
+
+	# Ports tree
+	/usr/ports		compression=lz4,setuid=off
+	/usr/ports/distfiles	compression=off,exec=off,setuid=off
+	/usr/ports/packages	compression=off,exec=off,setuid=off
+
+	# Source tree (compressed)
+	/usr/src	compression=lz4,exec=off,setuid=off
+	/usr/obj	# Object files
+
+	# Create /var and friends
+	/var		mountpoint=/var
+	/var/crash	compression=lz4,exec=off,setuid=off
+	/var/db		exec=off,setuid=off
+	/var/db/pkg	compression=lz4,exec=off,setuid=off
+	/var/empty	exec=off,setuid=off
+	/var/log	compression=lz4,exec=off,setuid=off
+	/var/mail	compression=lz4,exec=off,setuid=off
+	/var/run	exec=off,setuid=off
+	/var/tmp	compression=lz4,exec=on,setuid=off
+" # END-QUOTE
+
+############################################################ GLOBALS
+
+#
+# Strings that should be moved to an i18n file and loaded with f_include_lang()
+#
+hline_alnum_arrows_punc_tab_enter="Use alnum, arrows, punctuation, TAB or ENTER"
+hline_arrows_space_tab_enter="Use arrows, SPACE, TAB or ENTER"
+hline_arrows_tab_enter="Press arrows, TAB or ENTER"
+msg_back="Back"
+msg_cancel="Cancel"
+msg_configure_options="Configure Options:"
+msg_create="Install"
+msg_create_desc="Proceed with Installation"
+msg_create_help="Create ZFS boot pool with displayed options"
+msg_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"
+msg_disk_info="Disk Info"
+msg_disk_info_help="Get detailed information on disk device(s)"
+msg_disks_to_use="Disks To Use"
+msg_disks_to_use_help="Choose which disks to use for the Virtual Device (Required)"
+msg_force_4k_sectors="Force 4K Sectors?"
+msg_force_4k_sectors_help="Use gnop(8) to configure forced 4K sector alignment"
+msg_geli_encryption="Encrypt Disks?"
+msg_geli_encryption_help="Use geli(8) to encrypt all data partitions"
+msg_freebsd_installer="FreeBSD Installer"
+msg_invalid_virtual_device_type="Invalid Virtual Device type \`%s'"
+msg_last_chance_are_you_sure="Last Chance! Are you sure you want to destroy the current contents of the following disks:\n%s"
+msg_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"
+msg_mirror_desc="Mirror - n-Way Mirroring"
+msg_mirror_help="[2+ Disks] Mirroring provides the best performance, but the least storage"
+msg_no="NO"
+msg_no_disks_present_to_configure="No disk(s) present to configure"
+msg_no_disks_selected="No disks selected."
+msg_not_enough_disks_selected="Not enough disks selected (minimum %u)"
+msg_ok="OK"
+msg_partition_scheme="Partition Scheme"
+msg_partition_scheme_help="Toggle between GPT and MBR partitioning schemes"
+msg_please_enter_a_name_for_your_zpool="Please enter a name for your zpool:"
+msg_please_enter_amount_of_swap_space="Please enter amount of swap space (SI-Unit suffixes\nrecommended; e.g., \`2g' for 2 Gigabytes):"
+msg_please_select_one_or_more_disks="Please select one or more disks to create a zpool:"
+msg_pool_name="Pool Name"
+msg_pool_name_cannot_be_empty="Pool name cannot be empty."
+msg_pool_name_help="Customize the name of the zpool to be created (Required)"
+msg_raidz1_desc="RAID-Z1 - Single Redundant RAID"
+msg_raidz1_help="[3+ Disks] Withstand failure of 1 disk. Recommended for: 3, 5 or 9 disks"
+msg_raidz2_desc="RAID-Z2 - Double Redundant RAID"
+msg_raidz2_help="[4+ Disks] Withstand failure of 2 disks. Recommended for: 4, 6 or 10 disks"
+msg_raidz3_desc="RAID-Z3 - Triple Redundant RAID"
+msg_raidz3_help="[5+ Disks] Withstand failure of 3 disks. Recommended for: 5, 7 or 11 disks"
+msg_rescan_devices="Rescan Devices"
+msg_rescan_devices_help="Scan for device changes"
+msg_select="Select"
+msg_select_a_disk_device="Select a disk device"
+msg_select_virtual_device_type="Select Virtual Device type:"
+msg_stripe_desc="Stripe - No Redundancy"
+msg_stripe_help="[1+ Disks] Striping provides maximum storage but no redundancy"
+msg_swap_size="Swap Size"
+msg_swap_size_help="Customize how much swap space is allocated to each selected disk"
+msg_yes="YES"
+msg_zfs_configuration="ZFS Configuration"
+msg_zfs_vdev_type="ZFS VDev Type"
+msg_zfs_vdev_type_help="Select type of ZFS Virtual Device to create"
+
+############################################################ FUNCTIONS
+
+# dialog_menu_main
+#
+# Display the dialog(1)-based application main menu.
+#
+dialog_menu_main()
+{
+	local title="$DIALOG_TITLE"
+	local btitle="$DIALOG_BACKTITLE"
+	local prompt="$msg_configure_options"
+	local force4k="$msg_no"
+	local usegeli="$msg_no"
+	[ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && force4k="$msg_yes"
+	[ "$ZFSBOOT_GELI_ENCRYPTION" ] && usegeli="$msg_yes"
+	local menu_list="
+		'>>> $msg_create'         '$msg_create_desc'
+		                          '$msg_create_help'
+		'- $msg_rescan_devices'   '*'
+		                          '$msg_rescan_devices_help'
+		'- $msg_disk_info'        '*'
+		                          '$msg_disk_info_help'
+		'1 $msg_pool_name'        '$ZFSBOOT_POOL_NAME'
+		                          '$msg_pool_name_help'
+		'2 $msg_disks_to_use'     '$ZFSBOOT_DISKS'
+		                          '$msg_disks_to_use_help'
+		'3 $msg_zfs_vdev_type'    '$ZFSBOOT_VDEV_TYPE'
+		                          '$msg_zfs_vdev_type_help'
+		'4 $msg_force_4k_sectors' '$force4k'
+		                          '$msg_force_4k_sectors_help'
+		'5 $msg_geli_encryption'  '$usegeli'
+		                          '$msg_geli_encryption_help'
+		'6 $msg_partition_scheme' '$ZFSBOOT_PARTITION_SCHEME'
+		                          '$msg_partition_scheme_help'
+		'7 $msg_swap_size'        '$ZFSBOOT_SWAP_SIZE'
+		                          '$msg_swap_size_help'
+	" # END-QUOTE
+	local defaultitem= # Calculated below
+	local hline="$hline_alnum_arrows_punc_tab_enter"
+
+	local height width rows
+	eval f_dialog_menu_with_help_size height width rows \
+		\"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $menu_list
+
+	# Obtain default-item from previously stored selection
+	f_dialog_default_fetch defaultitem
+
+	local menu_choice
+	menu_choice=$( eval $DIALOG \
+		--title \"\$title\"              \
+		--backtitle \"\$btitle\"         \
+		--hline \"\$hline\"              \
+		--item-help                      \
+		--ok-label \"\$msg_select\"      \
+		--cancel-label \"\$msg_cancel\"  \
+		--default-item \"\$defaultitem\" \
+		--menu \"\$prompt\"              \
+		$height $width $rows             \
+		$menu_list                       \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	)
+	local retval=$?
+	f_dialog_data_sanitize menu_choice
+	f_dialog_menutag_store "$menu_choice"
+
+	# Only update default-item on success
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
+
+	return $retval
+}
+
+# dialog_edit_disks
+#
+# Edit the list of disks to be used by the ZFS boot pool.
+#
+dialog_edit_disks()
+{
+	local title="$DIALOG_TITLE"
+	local btitle="$DIALOG_BACKTITLE"
+	local prompt="$msg_please_select_one_or_more_disks"
+	local check_list= # Calculated below
+	local hline="$hline_arrows_space_tab_enter"
+	local dev vardev disks=
+
+	#
+	# Get a [new] list of disk devices
+	#
+	f_device_find "" $DEVICE_TYPE_DISK disks
+	if [ ! "$disks" ]; then
+		f_show_msg "$msg_no_disks_present_to_configure"
+		return $FAILURE
+	fi
+
+	# Lets sort the disks array to be more user friendly
+	disks=$( echo "$disks" | tr ' ' '\n' | sort | tr '\n' ' ' )
+
+	#
+	# Loop through the list of selected disks and create temporary local
+	# variables mapping their status onto an up-to-date list of disks.
+	#
+	for dev in $ZFSBOOT_DISKS; do
+		f_str2varname "$dev" vardev
+		local _${vardev}_status=on
+	done
+
+	#
+	# Create the checklist menu of discovered disk devices
+	#
+	local on_off
+	for dev in $disks; do
+		local desc=
+		device_$dev get desc desc
+		f_shell_escape "$desc" desc
+		f_str2varname "$dev" vardev
+		f_getvar _${vardev}_status:-off on_off
+		check_list="$check_list '$dev' '$desc' $on_off"
+	done
+
+	#
+	# Prompt the user to check some disks
+	#
+	local height width rows
+	eval f_dialog_checklist_size height width rows \
+		\"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $check_list
+	disks=$( eval $DIALOG \
+		--title \"\$DIALOG_TITLE\"         \
+		--backtitle \"\$DIALOG_BACKTITLE\" \
+		--hline \"\$hline\"                \
+		--ok-label \"\$msg_ok\"            \
+		--cancel-label \"\$msg_cancel\"    \
+		--checklist \"\$prompt\"           \
+		$height $width $rows               \
+		$check_list                        \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	) || return $?
+		# Exit if user either pressed ESC or chose Cancel/No
+	f_dialog_data_sanitize disks
+
+	ZFSBOOT_DISKS="$disks"
+
+	return $DIALOG_OK
+}
+
+# dialog_menu_vdev
+#
+# Prompt the user to select a a Virtual Device type.
+#
+dialog_menu_vdev()
+{
+	local title="$DIALOG_TITLE"
+	local btitle="$DIALOG_BACKTITLE"
+	local prompt="$msg_select_virtual_device_type"
+	
+	# Make sure [potentially scripted] selections are real
+	real_disks=
+	for disk in $ZFSBOOT_DISKS; do
+		f_struct device_$disk && real_disks="$real_disks $disk"
+	done
+	# Make sure we have at least one real disk selected
+	ndisks=$( set -- $real_disks; echo $# )
+
+	local menu_list="
+		'stripe' '$msg_stripe_desc' '$msg_stripe_help'
+		'mirror' '$msg_mirror_desc' '$msg_mirror_help'
+		'raidz1' '$msg_raidz1_desc' '$msg_raidz1_help'
+		'raidz2' '$msg_raidz2_desc' '$msg_raidz2_help'
+		'raidz3' '$msg_raidz3_desc' '$msg_raidz3_help'
+	" # END-QUOTE
+
+	local defaultitem="$ZFSBOOT_VDEV_TYPE"
+	local hline="$hline_arrows_tab_enter"
+
+	local height width rows
+	eval f_dialog_menu_size height width rows \
+		\"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $menu_list
+
+	local menu_choice
+	menu_choice=$( eval $DIALOG \
+		--title \"\$title\"              \
+		--backtitle \"\$btitle\"         \
+		--hline \"\$hline\"              \
+		--ok-label \"\$msg_ok\"          \
+		--cancel-label \"\$msg_cancel\"  \
+		--item-help                      \
+		--default-item \"\$defaultitem\" \
+		--menu \"\$prompt\"              \
+		$height $width $rows             \
+		$menu_list                       \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	) || return $FAILURE
+	f_dialog_data_sanitize menu_choice
+
+	ZFSBOOT_VDEV_TYPE="$menu_choice"
+}
+
+# zfs_create_diskpart $disk $index
+#
+# For each block device to be used in the zpool, rather than just create the
+# zpool with the raw block devices (e.g., da0, da1, etc.) we create partitions
+# so we can have some real swap. This also provides wiggle room incase your
+# replacement drivers do not have the exact same sector counts.
+#
+# NOTE: The MBR layout is more complicated (GPT is preferred).
+#
+zfs_create_diskpart()
+{
+	local disk="$1" index="$2"
+	local funcname=zfs_create_diskpart
+	local disksize partsize
+
+	# Check arguments
+	[ "$disk" -a "$index" ] || return $FAILURE
+
+	#
+	# Destroy whatever partition layout is currently on disk.
+	# NOTE: `-F' required to destroy if partitions still exist.
+	# NOTE: Failure is ok here, blank disk will have nothing to destroy.
+	#
+	f_quietly gpart destroy -F $disk
+	f_quietly zpool labelclear -f /dev/$disk # Kill it with fire
+
+	# Make doubly-sure backup GPT is destroyed
+	f_quietly gpart create -s gpt $disk || return $FAILURE
+	f_quietly gpart destroy -F $disk || return $FAILURE
+
+	# Calculate partition size given desired amount of swap
+	device_$disk get capacity disksize || return $FAILURE
+	partsize=$(( $disksize - $swapsize ))
+
+	#
+	# Lay down the desired type of partition scheme
+	#
+	local bootpart targetpart setsize=
+	case "$ZFSBOOT_PARTITION_SCHEME" in
+	""|GPT)
+		#
+		# 1. Create GPT layout using labels
+		#
+		gpart create -s gpt $disk || return $FAILURE
+
+		#
+		# 2. Add small freebsd-boot partition labeled `boot#'
+		#
+		gpart add -l gptboot$index -t freebsd-boot -s 512k $disk ||
+			return $FAILURE
+		gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $disk ||
+			return $FAILURE
+
+		# zpool will use the `zfs#' GPT labels
+		bootpart=p2 targetpart=p2
+
+		# Change things around if we are using GELI
+		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+			bootpart=p2 targetpart=p3
+			partsize=$(( $partsize - $gelisize ))
+			gpart add -l boot$index -t freebsd-zfs \
+				-s ${gelisize}b -a 1m $disk || return $FAILURE
+			zpool labelclear -f /dev/$disk$bootpart # Pedantic
+		fi
+
+		#
+		# 3. Add freebsd-zfs partition labeled `zfs#' for zpool
+		# NOTE: Using above calculated partsize to leave room for swap.
+		#
+		[ $swapsize -gt 0 ] && setsize="-s ${partsize}b"
+		gpart add -l zfs$index -t freebsd-zfs $setsize -a 1m $disk ||
+			return $FAILURE
+		f_quietly zpool labelclear -f /dev/$disk$targetpart # Pedantic
+
+		#
+		# 4. Add freebsd-swap partition labeled `swap#'
+		#
+		if [ $swapsize -gt 0 ]; then
+			gpart add -l swap$index -t freebsd-swap -a 1m $disk ||
+				return $FAILURE
+			# Update fstab(5)
+			printf "$fstab_fmt" \
+				/dev/gpt/swap$index none swap sw 0 0 \
+				>> $BSDINSTALL_TMPETC/fstab || return $FAILURE
+		fi
+		;;
+
+	MBR)
+		#
+		# 1. Create MBR layout (no labels)
+		#
+		gpart create -s mbr $disk || return $FAILURE
+		gpart bootcode -b /boot/boot0 $disk || return $FAILURE
+
+		#
+		# 2. Add freebsd slice with all available space
+		#
+		gpart add -t freebsd $disk || return $FAILURE
+		gpart set -a active -i 1 $disk || return $FAILURE
+		f_quietly gpart destroy -F ${disk}s1 # Pedantic
+
+		#
+		# 3. Write BSD sceme to the freebsd slice
+		#
+		gpart create -s BSD ${disk}s1 || return $FAILURE
+
+		# zpool will use s1a (no labels)
+		bootpart=s1a targetpart=s1a
+
+		# Change things around if we are using GELI
+		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+			bootpart=s1a targetpart=s1d
+			partsize=$(( $partsize - $gelisize ))
+			gpart add -t freebsd-zfs -s ${gelisize}b ${disk}s1 ||
+				return $FAILURE
+			# Pedantically nuke anything old labels
+			f_quietly zpool labelclear -f /dev/$disk$bootpart
+		fi
+
+		#
+		# 4. Partition the BSD slice for ZFS
+		# NOTE: Using above calculated partsize to leave room for swap.
+		#
+		[ $swapsize -gt 0 ] && setsize="-s ${partsize}b"
+		gpart add -t freebsd-zfs $setsize ${disk}s1 || return $FAILURE
+		f_quietly zpool labelclear -f /dev/$disk$targetpart # Pedantic
+
+		#
+		# 5. Add freebsd-swap partition
+		#
+		if [ $swapsize -gt 0 ]; then
+			gpart add -t freebsd-swap ${disk}s1 || return $FAILURE
+			# Update fstab(5)
+			printf "$fstab_fmt" /dev/${disk}s1b none swap sw 0 0 \
+				>> $BSDINSTALL_TMPETC/fstab || return $FAILURE
+		fi
+		;;
+
+	*)
+		printf "%s: %s is an unsupported partition scheme" \
+		       "$funcname" "$ZFSBOOT_PARTITION_SCHEME" >&2
+		return $FAILURE
+
+	esac # $ZFSBOOT_PARTITION_SCHEME
+
+	return $SUCCESS
+}
+
+# zfs_create_boot $poolname $vdev_type $real_disks ...
+#
+# Creates boot pool and dataset layout. Returns error if something goes wrong.
+# Errors are printed to stderr for collection and display.
+#
+zfs_create_boot()
+{
+	local poolname="$1" vdev_type="$2"
+	local fstab_fmt="%s\t\t%s\t%s\t%s\t\t%s\t%s\n"
+	local funcname=zfs_create_boot
+
+	shift 2 # name vdev_type
+
+	# We may need this later
+	local realdisks=$*
+
+	# Pedantic checks; should never be seen
+	if [ ! "$poolname" ]; then
+		echo "$funcname: NULL poolname" >&2
+		return $FAILURE
+	fi
+	if [ $# -lt 1 ]; then
+		echo "$funcname: missing disk arguments" >&2
+		return $FAILURE
+	fi
+
+	# Initialize fstab(5)
+	printf "$fstab_fmt" \
+		"# Device" Mountpoint FStype Options Dump "Pass#" \
+		>> $BSDINSTALL_TMPETC/fstab || return $FAILURE
+
+	# Expand SI units in desired sizes
+	local swapsize gelisize
+	f_expand_number "$ZFSBOOT_SWAP_SIZE" swapsize || return $FAILURE
+	f_expand_number "$ZFSBOOT_GELI_BOOT_SIZE" gelisize || return $FAILURE
+
+	# Prepare the disks
+	local n=0
+	for disk in $*; do
+		zfs_create_diskpart $disk $n || return $FAILURE
+		n=$(( $n + 1 ))
+	done
+
+	# MBR boot loader hack part 1
+	# We have to do this early because geli gets in the way later
+	if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
+		for disk in $realdisks; do
+			dd if=/boot/zfsboot of=/dev/${disk}s1 count=1 ||
+				return $FAILURE
+		done
+	fi
+
+	# Forced 4k alignment support provided by Geom NOP (see gnop(8))
+	local unenc_list=
+	if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then
+		local new_list=
+		for disk in $*; do
+			if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+				# We don't gnop the encrypted partition 
+				# because geli will do this for us
+				# gnop the unencrypted disk
+				gnop create -S 4096 $disk$bootpart ||
+					return $FAILURE
+				unenc_list="$unenc_list $disk$bootpart.nop"
+			else
+				gnop create -S 4096 $disk$targetpart ||
+					return $FAILURE
+				new_list="$new_list $disk$targetpart.nop"
+			fi
+		done
+		set -- $new_list
+	else
+		local new_list=
+		for disk in $*; do
+			new_list="$new_list $disk$targetpart"
+			[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
+				unenc_list="$unenc_list $disk$bootpart"
+		done
+		set -- $new_list
+	fi
+
+	#
+	# If encryption is enabled, we need to create the GEOMs
+	#
+	if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+		local bootvdev=
+		local geli_pool="$BSDINSTALL_CHROOT/$ZFSBOOT_GELI_POOL_NAME"
+		local key="$ZFSBOOT_GELI_KEY_FILE"
+
+		# Create the parent directories for our unencrypted pool
+		f_quietly umount /mnt
+		mount -t tmpfs none $BSDINSTALL_CHROOT || return $FAILURE
+
+		# Create mirror across the unencrypted partition on all disks
+		[ $( set -- $unenc_list; echo $# ) -gt 1 ] && bootvdev=mirror
+
+		zpool create -o altroot=$BSDINSTALL_CHROOT \
+			-m "/$ZFSBOOT_GELI_POOL_NAME" -f \
+			"$ZFSBOOT_GELI_POOL_NAME" $bootvdev $unenc_list || 
+			return $FAILURE
+		mkdir -p $geli_pool/boot || return $FAILURE
+
+		# Generate an encryption key using random(4)
+		dd if=/dev/random of="$geli_pool/$key" bs=4096 count=1 ||
+			return $FAILURE
+
+		# Create the geli(8) GEOMS
+		local geli_list=
+		for disk in $realdisks; do
+			geli init -b -B \
+				"$geli_pool/boot/$disk$targetpart.eli" \
+				-e AES-XTS -K "$geli_pool/$key" -l 256 \
+				-s 4096 $disk$targetpart || return $FAILURE
+			geli attach -k "$geli_pool/$key" $disk$targetpart ||
+				return $FAILURE
+			geli_list="$geli_list $disk$targetpart.eli"
+		done
+		set -- $geli_list
+		zfs unmount "$ZFSBOOT_GELI_POOL_NAME" || return $FAILURE
+	fi
+
+	#
+	# Create the ZFS pool with desired type and disk devices
+	#
+	zpool create -o altroot=$BSDINSTALL_CHROOT -m none -f \
+		"$poolname" $vdev_type $* || return $FAILURE
+
+	# Customize the zpool a bit...
+	zfs set checksum=fletcher4	"$poolname" || return $FAILURE
+	zfs set atime=off		"$poolname" || return $FAILURE
+
+	#
+	# Create ZFS dataset layout within the new boot pool
+	#
+	echo "$ZFSBOOT_DATASETS" | while read dataset options; do
+		# Skip blank lines and comments
+		case "$dataset" in "#"*|"") continue; esac
+		# Remove potential inline comments in options
+		options="${options%%#*}"
+		# Replace tabs with spaces
+		f_replaceall "$options" "	" " " foo
+		# Reduce contiguous runs of space to one single space
+		oldoptions=
+		while [ "$oldoptions" != "$options" ]; do
+			oldoptions="$options"
+			f_replaceall "$options" "  " " " options
+		done
+		# Replace both commas and spaces with ` -o '
+		f_replaceall "$options" "[ ,]" " -o " options
+		# Create the dataset with desired options
+		zfs create ${options:+-o $options} "$poolname$dataset" ||
+			return $FAILURE
+	done
+
+	# Touch up permissions on the tmp directories
+	chmod 1777 $BSDINSTALL_CHROOT/tmp || return $FAILURE
+	chmod 1777 $BSDINSTALL_CHROOT/var/tmp || return $FAILURE
+
+	# Create symlink(s)
+	[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
+		{ ln -s $ZFSBOOT_GELI_POOL_NAME/boot $BSDINSTALL_CHROOT/boot ||
+			return $FAILURE; }
+
+	# Set bootfs property
+	zpool set bootfs="$poolname/$ZFSBOOT_BEROOT_NAME/$ZFSBOOT_BOOTFS_NAME" \
+		"$poolname" || return $FAILURE
+
+	# Export the pool(s)
+	zpool export "$poolname" || return $FAILURE
+	[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
+		{ zpool export "$ZFSBOOT_GELI_POOL_NAME" || return $FAILURE; }
+
+	# Destroy the gnop devices (if enabled)
+	for disk in ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:+$realdisks}; do
+		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+			f_quietly gnop destroy $disk$bootpart.nop
+		else
+			f_quietly gnop destroy $disk$targetpart.nop
+		fi
+	done
+
+	# MBR boot loader hack part 2
+	if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
+		# Stick the ZFS boot loader in the "convienient hole" after 
+		# the ZFS internal metadata
+		for disk in $realdisks; do
+			dd if=/boot/zfsboot of=/dev/$disk$bootpart \
+				skip=1 seek=1024 || return $FAILURE
+		done
+	fi
+
+	# Re-import the ZFS pool(s)
+	zpool import -o altroot=$BSDINSTALL_CHROOT $poolname ||	return $FAILURE
+	[ "$ZFSBOOT_GELI_ENCRYPTION" ] &&
+		{ zpool import -o altroot=$BSDINSTALL_CHROOT \
+			"$ZFSBOOT_GELI_POOL_NAME" || return $FAILURE; }
+
+	# While this is apparently not needed, it seems to help MBR
+	mkdir -p $BSDINSTALL_CHROOT/boot/zfs || return $FAILURE
+	zpool set cachefile=$BSDINSTALL_CHROOT/boot/zfs/zpool.cache \
+		"$poolname" || return $FAILURE
+
+	# Last, but not least... add required lines to rc.conf(5)
+	# NOTE: We later concatenate these into their destination
+	echo 'zfs_enable="YES"' > $BSDINSTALL_TMPETC/rc.conf.zfs ||
+		return $FAILURE
+	echo 'zfs_load="YES"' > $BSDINSTALL_TMPBOOT/loader.conf.zfs ||
+		return $FAILURE
+
+	# We're all done unless we should go on to do encryption
+	[ "$ZFSBOOT_GELI_ENCRYPTION" ] || return $SUCCESS
+
+	#
+	# Configure geli(8)-based encryption
+	#
+	echo 'aesni_load="YES"' \
+		> $BSDINSTALL_TMPBOOT/loader.conf.aesni || return $FAILURE
+	echo 'geom_eli_load="YES"' \
+		> $BSDINSTALL_TMPBOOT/loader.conf.geli || return $FAILURE
+	printf 'vfs.root.mountfrom="zfs:%s/%s/%s"\n' "$poolname" \
+		"$ZFSBOOT_BEROOT_NAME" "$ZFSBOOT_BOOTFS_NAME" \
+		> $BSDINSTALL_TMPBOOT/loader.conf.root || return $FAILURE
+	for disk in $realdisks; do
+		printf 'geli_%s_keyfile0_load="YES"\n' \
+			"$disk$targetpart" \
+			> $BSDINSTALL_TMPBOOT/loader.conf.$disk$targetpart ||
+			return $FAILURE
+		printf 'geli_%s_keyfile0_type="%s:geli_keyfile0"\n' \
+			"$disk$targetpart" "$disk$targetpart" \
+			>> $BSDINSTALL_TMPBOOT/loader.conf.$disk$targetpart ||
+			return $FAILURE
+		printf 'geli_%s_keyfile0_name="%s"\n' \
+			"$disk$targetpart" "$ZFSBOOT_GELI_KEY_FILE" \
+			>> $BSDINSTALL_TMPBOOT/loader.conf.$disk$targetpart ||
+			return $FAILURE
+	done
+
+	return $SUCCESS
+}
+
+# dialog_menu_diskinfo
+#
+# Prompt the user to select a disk and then provide detailed info on it.
+#
+dialog_menu_diskinfo()
+{
+	local disk
+
+	#
+	# Break from loop when user cancels disk selection
+	#
+	while :; do
+		disk=$( msg_cancel="$msg_back" f_device_menu \
+			"$DIALOG_TITLE" "$msg_select_a_disk_device" "" \
+			$DEVICE_TYPE_DISK 2>&1 ) || break
+
+		# Show gpart(8) `show' and camcontrol(8) `inquiry' data
+		f_show_msg "$msg_detailed_disk_info" \
+			"$disk" "$( gpart show $disk 2> /dev/null )" \
+			"$disk" "$( camcontrol inquiry $disk 2> /dev/null )" \
+			"$disk" "$( camcontrol identify $disk 2> /dev/null )"
+	done
+
+	return $SUCCESS
+}
+
+############################################################ MAIN
+
+#
+# Initialize
+#
+f_dialog_title "$msg_zfs_configuration"
+f_dialog_backtitle "$msg_freebsd_installer"
+
+#
+# Loop over the main menu until we've accomplished what we came here to do
+#
+while :; do
+	dialog_menu_main
+	retval=$?
+	f_dialog_menutag_fetch mtag
+	f_dprintf "retval=%u mtag=[%s]" $reval "$mtag"
+
+	[ $retval -eq $DIALOG_OK ] || f_die
+
+	case "$mtag" in
+	">>> $msg_create")
+		#
+		# First, validate the user's selections
+		#
+
+		# Make sure they gave us a name for the pool
+		if [ ! "$ZFSBOOT_POOL_NAME" ]; then
+			f_show_msg "$msg_pool_name_cannot_be_empty"
+			continue
+		fi
+		# Make sure [potentially scripted] selections are real
+		real_disks=
+		for disk in $ZFSBOOT_DISKS; do
+			f_struct device_$disk && real_disks="$real_disks $disk"
+		done
+		# Make sure we have at least one real disk selected
+		ndisks=$( set -- $real_disks; echo $# )
+		if [ $ndisks -lt 1 ]; then
+			f_show_msg "$msg_no_disks_selected"
+			continue
+		fi
+		# Make sure we have enough disks for the desired vdev type
+		case "$ZFSBOOT_VDEV_TYPE" in
+		stripe) want_disks=1 ;;
+		mirror) want_disks=2 ;;
+		raidz1) want_disks=3 ;;
+		raidz2) want_disks=4 ;;
+		raidz3) want_disks=5 ;;
+		*)
+			f_show_msg "$msg_invalid_virtual_device_type" \
+		                   "$ZFSBOOT_VDEV_TYPE"
+			continue
+			;;
+		esac
+		if [ $ndisks -lt $want_disks ]; then
+			f_show_msg "%s: $msg_not_enough_disks_selected" \
+			           "$ZFSBOOT_VDEV_TYPE" "$want_disks"
+			continue
+		fi
+
+		#
+		# Last Chance!
+		#
+		if [ ! "$USE_XDIALOG" ]; then
+			DIALOG="$DIALOG --colors" f_noyes \
+				"$msg_last_chance_are_you_sure_color" \
+				"$ZFSBOOT_DISKS" || continue
+		else
+			f_noyes "$msg_last_chance_are_you_sure" \
+				"$ZFSBOOT_DISKS" || continue
+		fi
+
+		#
+		# Let's do this
+		#
+
+		vdev_type="$ZFSBOOT_VDEV_TYPE"
+
+		# Blank the vdev type for the default layout
+		[ "$vdev_type" = "stripe" ] && vdev_type=
+
+		if ! error=$( zfs_create_boot "$ZFSBOOT_POOL_NAME" \
+			"$vdev_type" $real_disks 2>&1 )
+		then
+			f_dialog_msgbox "$error"
+			continue
+		fi
+
+		break # to success
+		;;
+	"- $msg_rescan_devices") f_device_rescan ;;
+	"- $msg_disk_info") dialog_menu_diskinfo ;;
+	?" $msg_pool_name")
+		# Prompt the user to input/change the name for the new pool
+		f_dialog_input input \
+			"$msg_please_enter_a_name_for_your_zpool" \
+			"$ZFSBOOT_POOL_NAME" &&
+			ZFSBOOT_POOL_NAME="$input"
+		;;
+	?" $msg_disks_to_use") dialog_edit_disks ;;
+	?" $msg_zfs_vdev_type") dialog_menu_vdev ;;
+	?" $msg_force_4k_sectors")
+		# Toggle the variable referenced both by the menu and later
+		if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then
+			ZFSBOOT_GNOP_4K_FORCE_ALIGN=
+		else
+			ZFSBOOT_GNOP_4K_FORCE_ALIGN=1
+		fi
+		;;
+	?" $msg_geli_encryption")
+		# Toggle the variable referenced both by the menu and later
+		if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+			ZFSBOOT_GELI_ENCRYPTION=
+		else
+			ZFSBOOT_GELI_ENCRYPTION=1
+		fi
+		;;
+	?" $msg_partition_scheme")
+		# Toggle between GPT and MBR
+		if [ "$ZFSBOOT_PARTITION_SCHEME" = GPT ]; then
+			ZFSBOOT_PARTITION_SCHEME=MBR
+		else
+			ZFSBOOT_PARTITION_SCHEME=GPT
+		fi
+		;;
+	?" $msg_swap_size")
+		# Prompt the user to input/change the swap size for each disk
+		f_dialog_input input \
+			"$msg_please_enter_amount_of_swap_space" \
+			"$ZFSBOOT_SWAP_SIZE" &&
+			ZFSBOOT_SWAP_SIZE="$input"
+		;;
+	esac
+done
+
+return $SUCCESS
+
+################################################################################
+# END
+################################################################################

Property changes on: usr.sbin/bsdinstall/scripts/zfsboot
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property

--------------040306070903020902050706--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5254D231.5070803>