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