svn commit: r264437 - in stable/9/usr.sbin/bsdinstall: . scripts
Devin Teske
dteske at FreeBSD.org
Mon Apr 14 01:18:04 UTC 2014
Author: dteske
Date: Mon Apr 14 01:18:02 2014
New Revision: 264437
URL: http://svnweb.freebsd.org/changeset/base/264437
Log:
MFC r256343,256540-256541,256544,256549,256551,256553,257939,258021,258927,
259144,259148,259470,259472,259474,259476-259478,259480-259481,259570,
259597-259598, and 261960 (24 revisions; summarized below)...
r256343: Add zfsboot module as an option for automatic configuration
r256540: Add zpool_cache_* variables to loader.conf(5)
r256541: Document BSDINSTALL_TMPBOOT in bsdinstall.8
r256544: Fix a typo when setting up loader.conf(5) GELI entries
r256549: Document zfsboot in bsdinstall.8
r256551: Bump .Dd date in bsdinstall.8
r256553: Align ZFSBOOT_BEROOT_NAME with sysutils/beadm + Solaris beadm
r257939: Validate scripted partition entry before acting on disks
r258021: Switch default MBR bootcode from /boot/boot0 to /boot/mbr
r258927: Fix early regression in enabling the Encryption feature
r259144: Fix early regression in entering passphrase for Encryption
r259148: Fix typo that broke booting from Encrypted setup
r259470: Add default /var/mail with atime=on for mail apps
r259472: Accept NULL input as also meaning zero swap
r259474: Bug fixes and debugging improvements
r259476: Improve default ZFS disk layout
r259477: fletcher4 is currently the default
r259478: De-uglify the geli(8)-setup infobox by adding a newline
r259480: Fix ghosted zroot pool issue
r259481: Auto-enable 4k alignment with Encryption
r259570: Fix "[: -eq: argument expected" error
r259597: Fix installation to 3-4+ disks
r259598: Set the cachefile property so bootpools get imported
r261960: Add zfsboot to scripted interface of bsdinstall
Added:
stable/9/usr.sbin/bsdinstall/scripts/zfsboot
- copied, changed from r256343, head/usr.sbin/bsdinstall/scripts/zfsboot
Modified:
stable/9/usr.sbin/bsdinstall/bsdinstall
stable/9/usr.sbin/bsdinstall/bsdinstall.8
stable/9/usr.sbin/bsdinstall/scripts/Makefile
stable/9/usr.sbin/bsdinstall/scripts/auto
stable/9/usr.sbin/bsdinstall/scripts/config
stable/9/usr.sbin/bsdinstall/scripts/script
Directory Properties:
stable/9/ (props changed)
stable/9/usr.sbin/ (props changed)
stable/9/usr.sbin/bsdinstall/ (props changed)
stable/9/usr.sbin/bsdinstall/scripts/ (props changed)
Modified: stable/9/usr.sbin/bsdinstall/bsdinstall
==============================================================================
--- stable/9/usr.sbin/bsdinstall/bsdinstall Mon Apr 14 00:24:04 2014 (r264436)
+++ stable/9/usr.sbin/bsdinstall/bsdinstall Mon Apr 14 01:18:02 2014 (r264437)
@@ -41,6 +41,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
############################################################ GLOBALS
: ${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
@@ -61,6 +62,7 @@ shift $(( $OPTIND - 1 ))
VERB="${1:-auto}"; shift
[ -d "$BSDINSTALL_TMPETC" ] || mkdir -p "$BSDINSTALL_TMPETC"
+[ -d "$BSDINSTALL_TMPBOOT" ] || mkdir -p "$BSDINSTALL_TMPBOOT"
# Only enable debugging if debugFile is non-NULL and can be initialized
f_quietly f_debug_init
Modified: stable/9/usr.sbin/bsdinstall/bsdinstall.8
==============================================================================
--- stable/9/usr.sbin/bsdinstall/bsdinstall.8 Mon Apr 14 00:24:04 2014 (r264436)
+++ stable/9/usr.sbin/bsdinstall/bsdinstall.8 Mon Apr 14 01:18:02 2014 (r264437)
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 6, 2013
+.Dd October 15, 2013
.Dt BSDINSTALL 8
.Os
.Sh NAME
@@ -121,6 +121,21 @@ installations. Partitions disks, runs
.Xr newfs 8 ,
and writes the new system's
.Pa fstab .
+.It Cm zfsboot
+Provides the installer's
+.Pq experimental
+interactive/scriptable ZFS partitioner for multi-disk installations.
+Creates a single
+.Ic zpool
+with datasets and writes to the new system's
+.Pa rc.conf ,
+.Pa loader.conf ,
+and
+.Pa fstab .
+Supports
+.Xr geli 8 ,
+.Xr gnop 8 ,
+and many other features.
.It Cm partedit
Provides the installer's interactive manual disk partitioner, with support
for multi disk setups, non-UFS file systems, and manual selection of
@@ -267,6 +282,14 @@ will be stored until the
target is executed. If this directory does not already exist, it will be
created. Default:
.Pa /tmp/bsdinstall_etc
+.It Ev BSDINSTALL_TMPBOOT
+Directory where files destined for the new system's
+.Pa /boot
+will be stored until the
+.Cm config
+target is executed. If this directory does not already exist, it will be
+created. Default:
+.Pa /tmp/bsdinstall_boot
.El
.Sh SCRIPTING
.Nm
@@ -320,6 +343,15 @@ the preamble can contain a variable
which is passed to the
.Cm scriptedpart
target to control disk setup.
+Alternatively,
+instead of
+.Ev PARTITIONS ,
+the preamble can contain the variable
+.Ev ZFSBOOT_DATASETS
+which is parsed by the
+.Pq experimental
+.Cm zfsboot
+target to control ZFS datasets/options of the boot pool setup.
.Ss SETUP SCRIPT
Following the preamble is an optional shell script, beginning with a #!
declaration. This script will be run at the end of the installation process
Modified: stable/9/usr.sbin/bsdinstall/scripts/Makefile
==============================================================================
--- stable/9/usr.sbin/bsdinstall/scripts/Makefile Mon Apr 14 00:24:04 2014 (r264436)
+++ stable/9/usr.sbin/bsdinstall/scripts/Makefile Mon Apr 14 01:18:02 2014 (r264437)
@@ -2,7 +2,7 @@
SCRIPTS= auto adduser checksum config docsinstall entropy hostname jail \
keymap mirrorselect mount netconfig netconfig_ipv4 netconfig_ipv6 \
- rootpass script services time umount wlanconfig
+ rootpass script services time umount wlanconfig zfsboot
BINDIR= /usr/libexec/bsdinstall
NO_MAN= true
Modified: stable/9/usr.sbin/bsdinstall/scripts/auto
==============================================================================
--- stable/9/usr.sbin/bsdinstall/scripts/auto Mon Apr 14 00:24:04 2014 (r264436)
+++ stable/9/usr.sbin/bsdinstall/scripts/auto Mon Apr 14 01:18:02 2014 (r264437)
@@ -102,21 +102,38 @@ fi
rm -f $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\""
+
+CURARCH=$( uname -m )
+case $CURARCH in
+ amd64|i386) # Booting ZFS Supported
+ PMODES="$PMODES ZFS \"Automatic Root-on-ZFS (Experimental)\""
+ ;;
+ *) # Booting ZFS Unspported
+ ;;
+esac
-case $? in
-0) # Guided
+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` || exit 1
+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
if f_isset debugFile; then
# Give partedit the path to our logfile so it can append
BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error
@@ -125,6 +142,10 @@ case $? in
fi
bsdinstall mount || error
;;
+"ZFS") # ZFS
+ bsdinstall zfsboot || error
+ bsdinstall mount || error
+ ;;
*)
error
;;
Modified: stable/9/usr.sbin/bsdinstall/scripts/config
==============================================================================
--- stable/9/usr.sbin/bsdinstall/scripts/config Mon Apr 14 00:24:04 2014 (r264436)
+++ stable/9/usr.sbin/bsdinstall/scripts/config Mon Apr 14 01:18:02 2014 (r264437)
@@ -34,6 +34,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
+
[ "${debugFile#+}" ] && cp "${debugFile#+}" $BSDINSTALL_CHROOT/var/log/
# Set up other things from installed config
Modified: stable/9/usr.sbin/bsdinstall/scripts/script
==============================================================================
--- stable/9/usr.sbin/bsdinstall/scripts/script Mon Apr 14 00:24:04 2014 (r264436)
+++ stable/9/usr.sbin/bsdinstall/scripts/script Mon Apr 14 01:18:02 2014 (r264437)
@@ -95,7 +95,11 @@ fi
# Make partitions
rm -f $PATH_FSTAB
touch $PATH_FSTAB
-bsdinstall scriptedpart "$PARTITIONS"
+if [ "$ZFSBOOT_DISKS" ]; then
+ bsdinstall zfsboot
+else
+ bsdinstall scriptedpart "$PARTITIONS"
+fi
bsdinstall mount
# Unpack distributions
Copied and modified: stable/9/usr.sbin/bsdinstall/scripts/zfsboot (from r256343, head/usr.sbin/bsdinstall/scripts/zfsboot)
==============================================================================
--- head/usr.sbin/bsdinstall/scripts/zfsboot Fri Oct 11 20:41:35 2013 (r256343, copy source)
+++ stable/9/usr.sbin/bsdinstall/scripts/zfsboot Mon Apr 14 01:18:02 2014 (r264437)
@@ -47,7 +47,7 @@ f_include $BSDCFG_SHARE/variable.subr
#
# Default name for the boot environment parent dataset
#
-: ${ZFSBOOT_BEROOT_NAME:=bootenv}
+: ${ZFSBOOT_BEROOT_NAME:=ROOT}
#
# Default name for the primany boot environment
@@ -66,23 +66,30 @@ f_include $BSDCFG_SHARE/variable.subr
#
# Should we use geli(8) to encrypt the drives?
+# NB: Automatically enables ZFSBOOT_BOOT_POOL
#
-: ${ZFSBOOT_GELI_ENCRYPTION:=}
+: ${ZFSBOOT_GELI_ENCRYPTION=}
#
-# Default name the unencrypted pool when using geli(8) to encrypt the drives
+# Default path to the geli(8) keyfile used in drive encryption
#
-: ${ZFSBOOT_GELI_POOL_NAME:=bootpool}
+: ${ZFSBOOT_GELI_KEY_FILE:=/boot/encryption.key}
#
-# Default size for the unencrypted boot pool when using geli(8)
+# Create a separate boot pool?
+# NB: Automatically set when using geli(8) or MBR
#
-: ${ZFSBOOT_GELI_BOOT_SIZE:=2g}
+: ${ZFSBOOT_BOOT_POOL=}
#
-# Default path to the geli(8) keyfile used in drive encryption
+# Default name for boot pool when enabled (e.g., geli(8) or MBR)
#
-: ${ZFSBOOT_GELI_KEY_FILE:=/boot/encryption.key}
+: ${ZFSBOOT_BOOT_POOL_NAME:=bootpool}
+
+#
+# Default size for boot pool when enabled (e.g., geli(8) or MBR)
+#
+: ${ZFSBOOT_BOOT_POOL_SIZE:=2g}
#
# Default disks to use (always empty unless being scripted)
@@ -101,7 +108,7 @@ f_include $BSDCFG_SHARE/variable.subr
: ${ZFSBOOT_SWAP_SIZE:=2g}
#
-# Default ZFS layout for root zpool
+# Default ZFS datasets 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.
@@ -119,69 +126,117 @@ f_isset ZFSBOOT_DATASETS || ZFSBOOT_DATA
# 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
+ /usr/home # NB: /home is a symlink to /usr/home
# 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/mail compression=lz4,atime=on
/var/tmp compression=lz4,exec=on,setuid=off
" # END-QUOTE
+#
+# If interactive and the user has not explicitly chosen a vdev type or disks,
+# make the user confirm scripted/default choices when proceeding to install.
+#
+: ${ZFSBOOT_CONFIRM_LAYOUT:=1}
+
############################################################ GLOBALS
#
+# Format of a line in printf(1) syntax to add to fstab(5)
+#
+FSTAB_FMT="%s\t\t%s\t%s\t%s\t\t%s\t%s\n"
+
+#
+# Command strings for various tasks
+#
+CHMOD_MODE='chmod %s "%s"'
+DD_WITH_OPTIONS='dd if="%s" of="%s" %s'
+ECHO_APPEND='echo "%s" >> "%s"'
+GELI_ATTACH='geli attach -j - -k "%s" "%s"'
+GELI_DETACH_F='geli detach -f "%s"'
+GELI_PASSWORD_INIT='geli init -b -B "%s" -e %s -J - -K "%s" -l 256 -s 4096 "%s"'
+GNOP_CREATE='gnop create -S 4096 "%s"'
+GNOP_DESTROY='gnop destroy "%s"'
+GPART_ADD='gpart add -t %s "%s"'
+GPART_ADD_INDEX='gpart add -i %s -t %s "%s"'
+GPART_ADD_INDEX_WITH_SIZE='gpart add -i %s -t %s -s %s "%s"'
+GPART_ADD_LABEL='gpart add -l %s -t %s "%s"'
+GPART_ADD_LABEL_WITH_SIZE='gpart add -l %s -t %s -s %s "%s"'
+GPART_BOOTCODE='gpart bootcode -b "%s" "%s"'
+GPART_BOOTCODE_PART='gpart bootcode -b "%s" -p "%s" -i %s "%s"'
+GPART_CREATE='gpart create -s %s "%s"'
+GPART_DESTROY_F='gpart destroy -F "%s"'
+GPART_SET_ACTIVE='gpart set -a active -i %s "%s"'
+GRAID_DELETE='graid delete "%s"'
+LN_SF='ln -sf "%s" "%s"'
+MKDIR_P='mkdir -p "%s"'
+MOUNT_TYPE='mount -t %s "%s" "%s"'
+PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\""
+PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"'
+SHELL_TRUNCATE=':> "%s"'
+UMOUNT='umount "%s"'
+ZFS_CREATE_WITH_OPTIONS='zfs create %s "%s"'
+ZFS_SET='zfs set "%s" "%s"'
+ZFS_UNMOUNT='zfs unmount "%s"'
+ZPOOL_CREATE_WITH_OPTIONS='zpool create %s "%s" %s %s'
+ZPOOL_EXPORT='zpool export "%s"'
+ZPOOL_IMPORT_WITH_OPTIONS='zpool import %s "%s"'
+ZPOOL_LABELCLEAR_F='zpool labelclear -f "%s"'
+ZPOOL_SET='zpool set %s "%s"'
+
+#
# 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_an_unknown_error_occurred="An unknown error occurred"
msg_back="Back"
msg_cancel="Cancel"
-msg_change="Change Selection"
+msg_change_selection="Change Selection"
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_encrypt_disks="Encrypt Disks?"
+msg_encrypt_disks_help="Use geli(8) to encrypt all data partitions"
+msg_error="Error"
msg_force_4k_sectors="Force 4K Sectors?"
msg_force_4k_sectors_help="Use gnop(8) to configure forced 4K sector alignment"
msg_freebsd_installer="FreeBSD Installer"
-msg_geli_encryption="Encrypt Disks?"
-msg_geli_encryption_help="Use geli(8) to encrypt all data partitions"
msg_geli_password="Enter a strong passphrase, used to protect your encryption keys. You will be required to enter this passphrase each time the system is booted"
-msg_geli_setup="Initializing encryption on the selected disks, this will take several seconds per disk"
+msg_geli_setup="Initializing encryption on selected disks,\n this will take several seconds per disk"
+msg_install="Install"
+msg_install_desc="Proceed with Installation"
+msg_install_help="Create ZFS boot pool with displayed options"
+msg_invalid_boot_pool_size="Invalid boot pool size \`%s'"
+msg_invalid_disk_argument="Invalid disk argument \`%s'"
+msg_invalid_index_argument="Invalid index argument \`%s'"
+msg_invalid_swap_size="Invalid swap size \`%s'"
msg_invalid_virtual_device_type="Invalid Virtual Device type \`%s'"
-msg_invalid_virtual_device_type_help="Select another Virtual Device type or Cancel to\nreturn to the ZFS menu. From there you can select\nmore disks or rescan for additional devices."
-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_last_chance_are_you_sure="Last Chance! Are you sure you want to destroy\nthe current contents of the following disks:\n\n %s"
+msg_last_chance_are_you_sure_color='\\ZrLast Chance!\\ZR Are you \\Z1sure\\Zn you want to \\Zr\\Z1destroy\\Zn\nthe current contents of the following disks:\n\n %s'
msg_mirror_desc="Mirror - n-Way Mirroring"
msg_mirror_help="[2+ Disks] Mirroring provides the best performance, but the least storage"
+msg_missing_disk_arguments="missing disk arguments"
+msg_missing_one_or_more_scripted_disks="Missing one or more scripted disks!"
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. (%u < %u wanted)"
+msg_not_enough_disks_selected="Not enough disks selected. (%u < %u minimum)"
+msg_null_disk_argument="NULL disk argument"
+msg_null_index_argument="NULL index argument"
+msg_null_poolname="NULL poolname"
msg_ok="OK"
msg_partition_scheme="Partition Scheme"
msg_partition_scheme_help="Toggle between GPT and MBR partitioning schemes"
@@ -191,6 +246,8 @@ msg_please_select_one_or_more_disks="Ple
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_pool_type_disks="Pool Type/Disks:"
+msg_pool_type_disks_help="Choose type of ZFS Virtual Device and disks to use (Required)"
msg_processing_selection="Processing selection..."
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"
@@ -207,11 +264,12 @@ 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_these_disks_are_too_small="These disks are too small given the amount of requested\nswap (%s) and/or GELI (%s) partitions, which would take\n50%% or more (not recommended) of each of the following\nselected disk devices:\n\n %s\n\nRecommend changing partition size(s) and/or selecting a\ndifferent set of devices."
+msg_these_disks_are_too_small="These disks are too small given the amount of requested\nswap (%s) and/or geli(8) (%s) partitions, which would\ntake 50%% or more of each of the following selected disk\ndevices (not recommended):\n\n %s\n\nRecommend changing partition size(s) and/or selecting a\ndifferent set of devices."
+msg_unable_to_get_disk_capacity="Unable to get disk capacity of \`%s'"
+msg_unsupported_partition_scheme="%s is an unsupported partition scheme"
+msg_user_cancelled="User Cancelled."
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
@@ -228,26 +286,26 @@ dialog_menu_main()
local usegeli="$msg_no"
[ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && force4k="$msg_yes"
[ "$ZFSBOOT_GELI_ENCRYPTION" ] && usegeli="$msg_yes"
+ local disks n=$( set -- $ZFSBOOT_DISKS; echo $# )
+ { [ $n -eq 1 ] && disks=disk; } || disks=disks # grammar
local menu_list="
- '>>> $msg_create' '$msg_create_desc'
- '$msg_create_help'
+ '>>> $msg_install' '$msg_install_desc'
+ '$msg_install_help'
+ 'T $msg_pool_type_disks' '$ZFSBOOT_VDEV_TYPE: $n $disks'
+ '$msg_pool_type_disks_help'
'- $msg_rescan_devices' '*'
'$msg_rescan_devices_help'
'- $msg_disk_info' '*'
'$msg_disk_info_help'
- '1 $msg_pool_name' '$ZFSBOOT_POOL_NAME'
+ 'N $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'
+ 'E $msg_encrypt_disks' '$usegeli'
+ '$msg_encrypt_disks_help'
+ 'P $msg_partition_scheme' '$ZFSBOOT_PARTITION_SCHEME'
'$msg_partition_scheme_help'
- '7 $msg_swap_size' '$ZFSBOOT_SWAP_SIZE'
+ 'S $msg_swap_size' '$ZFSBOOT_SWAP_SIZE'
'$msg_swap_size_help'
" # END-QUOTE
local defaultitem= # Calculated below
@@ -284,158 +342,279 @@ dialog_menu_main()
return $retval
}
-# dialog_edit_disks
+# dialog_last_chance $disks ...
#
-# Edit the list of disks to be used by the ZFS boot pool.
+# Display a list of the disks that the user is about to destroy. The default
+# action is to return error status unless the user explicitly (non-default)
+# selects "Yes" from the noyes dialog.
#
-dialog_edit_disks()
+dialog_last_chance()
{
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=
+ local prompt # Calculated below
+ local hline="$hline_arrows_tab_enter"
- #
- # 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
+ local height=8 width=50 prefix=" "
+ local plen=${#prefix} list= line=
+ local max_width=$(( $width - 3 - $plen ))
+
+ local yes no defaultno extra_args format
+ if [ "$USE_XDIALOG" ]; then
+ yes=ok no=cancel defaultno=default-no
+ extra_args="--wrap --left"
+ format="$msg_last_chance_are_you_sure"
+ else
+ yes=yes no=no defaultno=defaultno
+ extra_args="--colors --cr-wrap"
+ format="$msg_last_chance_are_you_sure_color"
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"
+ local disk line_width
+ for disk in $*; do
+ if [ "$line" ]; then
+ line_width=${#line}
+ else
+ line_width=$plen
+ fi
+ line_width=$(( $line_width + 1 + ${#disk} ))
+ # Add newline before disk if it would exceed max_width
+ if [ $line_width -gt $max_width ]; then
+ list="$list$line\n"
+ line="$prefix"
+ height=$(( $height + 1 ))
+ fi
+ # Add the disk to the list
+ line="$line $disk"
done
+ # Append the left-overs
+ if [ "${line#$prefix}" ]; then
+ list="$list$line"
+ height=$(( $height + 1 ))
+ fi
- #
- # 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"
+ # Add height for Xdialog(1)
+ [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 ))
- return $DIALOG_OK
+ prompt=$( printf "$format" "$list" )
+ f_dprintf "%s: Last Chance!" "$0"
+ $DIALOG \
+ --title "$title" \
+ --backtitle "$btitle" \
+ --hline "$hline" \
+ --$defaultno \
+ --$yes-label "$msg_yes" \
+ --$no-label "$msg_no" \
+ $extra_args \
+ --yesno "$prompt" $height $width
}
-# dialog_menu_vdev
+# dialog_menu_layout
#
-# Prompt the user to select a a Virtual Device type.
+# Configure Virtual Device type and disks to use for the ZFS boot pool. User
+# must select enough disks to satisfy the chosen vdev type.
#
-dialog_menu_vdev()
+dialog_menu_layout()
{
+ local funcname=dialog_menu_layout
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="
+ local vdev_prompt="$msg_select_virtual_device_type"
+ local disk_prompt="$msg_please_select_one_or_more_disks"
+ local vdev_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 disk_check_list= # Calculated below
+ local vdev_hline="$hline_arrows_tab_enter"
+ local disk_hline="$hline_arrows_space_tab_enter"
+
+ # Warn the user if vdev type is not valid
+ case "$ZFSBOOT_VDEV_TYPE" in
+ stripe|mirror|raidz1|raidz2|raidz3) : known good ;;
+ *)
+ f_dprintf "%s: Invalid virtual device type \`%s'" \
+ $funcname "$ZFSBOOT_VDEV_TYPE"
+ f_show_err "$msg_invalid_virtual_device_type" \
+ "$ZFSBOOT_VDEV_TYPE"
+ f_interactive || return $FAILURE
+ esac
- local defaultitem="$ZFSBOOT_VDEV_TYPE"
- local hline="$hline_arrows_tab_enter"
- local error_msg revalidate_choice
+ # Calculate size of vdev menu once only
+ local vheight vwidth vrows
+ eval f_dialog_menu_with_help_size vheight vwidth vrows \
+ \"\$title\" \"\$btitle\" \"\$vdev_prompt\" \"\$vdev_hline\" \
+ $vdev_menu_list
- local mheight mwidth mrows
- eval f_dialog_menu_size mheight mwidth mrows \
- \"\$title\" \"\$btitle\" \"\$prompt\" \"\$hline\" $menu_list
- local iheight iwidth
- f_dialog_infobox_size iheight iwidth \
- "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_processing_selection"
+ # Get a list of probed disk devices
+ local disks=
+ f_device_find "" $DEVICE_TYPE_DISK disks
+ f_dprintf "$funcname: disks=[%s]" "$disks"
+ if [ ! "$disks" ]; then
+ f_dprintf "No disk(s) present to configure"
+ f_show_err "$msg_no_disks_present_to_configure"
+ return $FAILURE
+ fi
- 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\" \
- $mheight $mwidth $mrows \
- $menu_list \
- --and-widget \
- ${USE_XDIALOG:+--no-buttons} \
- --infobox \"\$msg_processing_selection\" \
- $iheight $iwidth \
- 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
- ) || return $FAILURE
- f_dialog_data_sanitize menu_choice
- sleep 0.5 # Give time to read `--and-widget --info-box'
+ # Lets sort the disks array to be more user friendly
+ disks=$( echo "$disks" | tr ' ' '\n' | sort | tr '\n' ' ' )
- # Make sure we have enough disks for the desired vdev type
- case "$menu_choice" 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" \
- "$menu_choice"
- continue
- esac
- if [ $ndisks -lt $want_disks ]; then
- msg_yes="$msg_change" msg_no="$msg_cancel" f_yesno \
- "%s: $msg_not_enough_disks_selected\n%s" \
- "$menu_choice" $ndisks $want_disks \
- "$msg_invalid_virtual_device_type_help" ||
- return $FAILURE
- dialog_menu_vdev
- else
- ZFSBOOT_VDEV_TYPE="$menu_choice"
- fi
+ #
+ # Operate in a loop so we can (if interactive) repeat if not enough
+ # disks are selected to satisfy the chosen vdev type or user wants to
+ # back-up to the previous menu.
+ #
+ local vardisk ndisks onoff selections vdev_choice
+ while :; do
+ #
+ # Confirm the vdev type that was selected
+ #
+ if f_interactive && [ "$ZFSBOOT_CONFIRM_LAYOUT" ]; then
+ vdev_choice=$( eval $DIALOG \
+ --title \"\$title\" \
+ --backtitle \"\$btitle\" \
+ --hline \"\$vdev_hline\" \
+ --ok-label \"\$msg_ok\" \
+ --cancel-label \"\$msg_cancel\" \
+ --item-help \
+ --default-item \"\$ZFSBOOT_VDEV_TYPE\" \
+ --menu \"\$vdev_prompt\" \
+ $vheight $vwidth $vrows \
+ $vdev_menu_list \
+ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+ ) || return $?
+ # Exit if user pressed ESC or chose Cancel/No
+ f_dialog_data_sanitize vdev_choice
+
+ ZFSBOOT_VDEV_TYPE="$vdev_choice"
+ f_dprintf "$funcname: ZFSBOOT_VDEV_TYPE=[%s]" \
+ "$ZFSBOOT_VDEV_TYPE"
+ fi
+
+ # Determine the number of disks needed for this vdev type
+ local want_disks=0
+ 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 ;;
+ esac
+
+ # Warn the user if any scripted disks are invalid
+ local disk valid_disks=
+ local all_valid=${ZFSBOOT_DISKS:+1} # optimism
+ for disk in $ZFSBOOT_DISKS; do
+ if f_struct device_$disk; then
+ valid_disks="$valid_disks $disk"
+ continue
+ fi
+ f_dprintf "$funcname: \`%s' is not a real disk" "$disk"
+ all_valid=
+ done
+ if [ ! "$all_valid" ]; then
+ if [ "$ZFSBOOT_DISKS" ]; then
+ f_show_err \
+ "$msg_missing_one_or_more_scripted_disks"
+ else
+ f_dprintf "No disks selected."
+ f_interactive ||
+ f_show_err "$msg_no_disks_selected"
+ fi
+ f_interactive || return $FAILURE
+ fi
+ ZFSBOOT_DISKS="${valid_disks# }"
+
+ #
+ # Short-circuit if we're running non-interactively
+ #
+ if ! f_interactive || [ ! "$ZFSBOOT_CONFIRM_LAYOUT" ]; then
+ ndisks=$( set -- $ZFSBOOT_DISKS; echo $# )
+ [ $ndisks -ge $want_disks ] && break # to success
+
+ # Not enough disks selected
+ f_dprintf "$funcname: %s: %s (%u < %u minimum)" \
+ "$ZFSBOOT_VDEV_TYPE" \
+ "Not enough disks selected." \
+ $ndisks $want_disks
+ f_interactive || return $FAILURE
+ msg_yes="$msg_change_selection" msg_no="$msg_cancel" \
+ f_yesno "%s: $msg_not_enough_disks_selected" \
+ "$ZFSBOOT_VDEV_TYPE" $ndisks $want_disks ||
+ return $FAILURE
+ fi
+
+ #
+ # Confirm the disks that were selected
+ # Loop until the user cancels or selects enough disks
+ #
+ local breakout=
+ while :; do
+ # Loop over list of available disks, resetting state
+ for disk in $disks; do unset _${disk}_status; done
+
+ # Loop over list of selected disks and create temporary
+ # locals to map statuses onto up-to-date list of disks
+ for disk in $ZFSBOOT_DISKS; do
+ local _${disk}_status=on
+ done
+
+ # Create the checklist menu of discovered disk devices
+ disk_check_list=
+ for disk in $disks; do
+ local desc=
+ device_$disk get desc desc
+ f_shell_escape "$desc" desc
+ f_getvar _${disk}_status:-off onoff
+ disk_check_list="$disk_check_list
+ $disk '$desc' $onoff"
+ done
+
+ local height width rows
+ eval f_dialog_checklist_size height width rows \
+ \"\$title\" \"\$btitle\" \"\$prompt\" \
+ \"\$hline\" $disk_check_list
+
+ selections=$( eval $DIALOG \
+ --title \"\$DIALOG_TITLE\" \
+ --backtitle \"\$DIALOG_BACKTITLE\" \
+ --hline \"\$hline\" \
+ --ok-label \"\$msg_ok\" \
+ --cancel-label \"\$msg_back\" \
+ --checklist \"\$prompt\" \
+ $height $width $rows \
+ $disk_check_list \
+ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+ ) || break
+ # Loop if user pressed ESC or chose Cancel/No
+ f_dialog_data_sanitize selections
+
+ ZFSBOOT_DISKS="$selections"
+ f_dprintf "$funcname: ZFSBOOT_DISKS=[%s]" \
+ "$ZFSBOOT_DISKS"
+
+ ndisks=$( set -- $ZFSBOOT_DISKS; echo $# )
+ [ $ndisks -ge $want_disks ] &&
+ breakout=break && break
+
+ # Not enough disks selected
+ f_dprintf "$funcname: %s: %s (%u < %u minimum)" \
+ "$ZFSBOOT_VDEV_TYPE" \
+ "Not enough disks selected." \
+ $ndisks $want_disks
+ msg_yes="$msg_change_selection" msg_no="$msg_cancel" \
+ f_yesno "%s: $msg_not_enough_disks_selected" \
+ "$ZFSBOOT_VDEV_TYPE" $ndisks $want_disks ||
+ break
+ done
+ [ "$breakout" = "break" ] && break
+ [ "$ZFSBOOT_CONFIRM_LAYOUT" ] || return $FAILURE
+ done
+
+ return $DIALOG_OK
}
# zfs_create_diskpart $disk $index
@@ -445,295 +624,446 @@ dialog_menu_vdev()
# 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).
+# NOTE: $swapsize and $bootsize should be defined by the calling function.
+# NOTE: Sets $bootpart and $targetpart for the calling function.
#
zfs_create_diskpart()
{
- local disk="$1" index="$2"
local funcname=zfs_create_diskpart
- local disksize partsize
+ local disk="$1" index="$2"
# Check arguments
- [ "$disk" -a "$index" ] || return $FAILURE
+ if [ ! "$disk" ]; then
+ f_dprintf "$funcname: NULL disk argument"
+ msg_error="$msg_error: $funcname" \
+ f_show_err "$msg_null_disk_argument"
+ return $FAILURE
+ fi
+ if [ "${disk#*[$IFS]}" != "$disk" ]; then
+ f_dprintf "$funcname: Invalid disk argument \`%s'" "$disk"
+ msg_error="$msg_error: $funcname" \
+ f_show_err "$msg_invalid_disk_argument" "$disk"
+ return $FAILURE
+ fi
+ if [ ! "$index" ]; then
+ f_dprintf "$funcname: NULL index argument"
+ msg_error="$msg_error: $funcname" \
+ f_show_err "$msg_null_index_argument"
+ return $FAILURE
+ fi
+ if ! f_isinteger "$index"; then
+ f_dprintf "$funcname: Invalid index argument \`%s'" "$index"
+ msg_error="$msg_error: $funcname" \
+ f_show_err "$msg_invalid_index_argument" "$index"
+ return $FAILURE
+ fi
+ f_dprintf "$funcname: disk=[%s] index=[%s]" "$disk" "$index"
+
+ # Check for unknown partition scheme before proceeding further
+ case "$ZFSBOOT_PARTITION_SCHEME" in
+ ""|MBR|GPT) : known good ;;
+ *)
+ f_dprintf "$funcname: %s is an unsupported partition scheme" \
+ "$ZFSBOOT_PARTITION_SCHEME"
+ msg_error="$msg_error: $funcname" f_show_err \
+ "$msg_unsupported_partition_scheme" \
+ "$ZFSBOOT_PARTITION_SCHEME"
+ return $FAILURE
+ esac
#
# 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
+ f_dprintf "$funcname: Destroying all data/layouts on \`%s'..." "$disk"
+ f_eval_catch -d $funcname gpart "$GPART_DESTROY_F" $disk
+ f_eval_catch -d $funcname graid "$GRAID_DELETE" $disk
+ f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" /dev/$disk
# Make doubly-sure backup GPT is destroyed
- f_quietly gpart create -s gpt $disk || return $FAILURE
- f_quietly gpart destroy -F $disk || return $FAILURE
+ f_eval_catch -d $funcname gpart "$GPART_CREATE" gpt $disk
+ f_eval_catch -d $funcname gpart "$GPART_DESTROY_F" $disk
- # Calculate partition size given desired amount of swap
- device_$disk get capacity disksize || return $FAILURE
- partsize=$(( $disksize - $swapsize ))
+ #
+ # Enable boot pool if encryption is desired
+ #
+ [ "$ZFSBOOT_GELI_ENCRYPTION" ] && ZFSBOOT_BOOT_POOL=1
#
# Lay down the desired type of partition scheme
#
local setsize mbrindex
case "$ZFSBOOT_PARTITION_SCHEME" in
- ""|GPT)
+ ""|GPT) f_dprintf "$funcname: Creating GPT layout..."
#
# 1. Create GPT layout using labels
#
- gpart create -s gpt $disk || return $FAILURE
+ f_eval_catch $funcname gpart "$GPART_CREATE" 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
+ f_eval_catch $funcname gpart "$GPART_ADD_LABEL_WITH_SIZE" \
+ gptboot$index freebsd-boot 512k $disk ||
+ return $FAILURE
+ f_eval_catch $funcname gpart "$GPART_BOOTCODE_PART" \
+ /boot/pmbr /boot/gptzfsboot 1 $disk ||
+ return $FAILURE
- # zpool will use the `zfs#' GPT labels
+ # NB: zpool will use the `zfs#' GPT labels
bootpart=p2 targetpart=p2
+ [ ${swapsize:-0} -gt 0 ] && targetpart=p3
- # Change things around if we are using GELI
- if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+ #
+ # Prepare boot pool if enabled (e.g., for geli(8))
+ #
+ if [ "$ZFSBOOT_BOOT_POOL" ]; then
bootpart=p2 targetpart=p3
- partsize=$(( $partsize - $gelisize ))
- gpart add -l boot$index -t freebsd-zfs \
- -s ${gelisize}b -a 1m $disk || return $FAILURE
- # Pedantically nuke any old labels, stop geli
- f_quietly zpool labelclear -f /dev/$disk$bootpart
- f_quietly geli detach -f /dev/$disk$targetpart
+ [ ${swapsize:-0} -gt 0 ] && targetpart=p4
+ f_eval_catch $funcname gpart \
+ "$GPART_ADD_LABEL_WITH_SIZE" boot$index \
+ freebsd-zfs ${bootsize}b $disk ||
+ return $FAILURE
+ # Pedantically nuke any old labels
+ f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \
+ /dev/$disk$bootpart
+ if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
+ # Pedantically detach targetpart for later
+ f_eval_catch -d $funcname geli \
+ "$GELI_DETACH_F" \
+ /dev/$disk$targetpart
+ fi
fi
#
- # 3. Add freebsd-zfs partition labeled `zfs#' for zpool
- # NOTE: Using above calculated partsize to leave room for swap.
+ # 3. Add freebsd-swap partition labeled `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
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-9
mailing list