Date: Sat, 17 May 2014 11:58:26 -0400 From: Allan Jude <freebsd@allanjude.com> To: roberto@freebsd.org, freebsd-sysinstall@freebsd.org Subject: patch to bsdinstall to support BSD partitions Message-ID: <53778722.9000608@allanjude.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------020100060009040503090208 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On some Lenovo machines, booting ZFS off MBR partitions does not work On the Lenovo X61s that we were able to test on at the BSDCan Hackers Lounge, we were able to get them to boot properly using a BSD partitioning scheme instead. The attached patch makes the following changes: Add support for BSD partition type Moved the write of the MBR boot sector to the end of the process to avoid it being nuked by the pedantic zpool labelclear commands Change the MBR code to not always create 2 zpools when using MBR. The user only wants 2 pools (1 unencrypted to boot, and one encrypted for data) in the case where they enable encryption. Due to the simplicity of the code in previous versions of bsdinstall, two pools were used to avoid a problem with the order of the creation of the partitions to ensure that there was a partition at the front of the drive for the boot code, and that the swap partition was the 2nd partition (BSD partition 'b') Some style cleanup to make the flow of the MBR section more fix an syntax error introduced in the previous patch where a newline was not escaped Write the zfsboot code to the two different places require for MBR and BSD. Write the larger section first because writing the first sector first seems to make the BSD partition disappear and appear as an empty MBR (No idea why this was happening, reproduced on two Lenovo laptops) Resolve variable reuse by renaming 'disksize' in second card to 'usablesize' to avoid disksize being disksize less swap+boot size Sponsored By: ScaleEngine Inc. --------------020100060009040503090208 Content-Type: text/x-patch; name="zfsboot.bsd_partition_v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="zfsboot.bsd_partition_v2.patch" Index: usr.sbin/bsdinstall/scripts/zfsboot =================================================================== --- usr.sbin/bsdinstall/scripts/zfsboot (revision 266146) +++ usr.sbin/bsdinstall/scripts/zfsboot (working copy) @@ -77,17 +77,17 @@ # # Create a separate boot pool? -# NB: Automatically set when using geli(8) or MBR +# NB: Automatically set when using geli(8) # : ${ZFSBOOT_BOOT_POOL=} # -# Default name for boot pool when enabled (e.g., geli(8) or MBR) +# Default name for boot pool when enabled (e.g., geli(8)) # : ${ZFSBOOT_BOOT_POOL_NAME:=bootpool} # -# Default size for boot pool when enabled (e.g., geli(8) or MBR) +# Default size for boot pool when enabled (e.g., geli(8)) # : ${ZFSBOOT_BOOT_POOL_SIZE:=2g} @@ -253,7 +253,7 @@ msg_null_poolname="NULL poolname" msg_ok="OK" msg_partition_scheme="Partition Scheme" -msg_partition_scheme_help="Toggle between GPT and MBR partitioning schemes" +msg_partition_scheme_help="Toggle between GPT, MBR, and BSD partitioning schemes" msg_please_enter_a_name_for_your_zpool="Please enter a name for your zpool:" msg_please_enter_amount_of_swap_space="Please enter amount of swap space (SI-Unit suffixes\nrecommended; e.g., \`2g' for 2 Gigabytes):" msg_please_select_one_or_more_disks="Please select one or more disks to create a zpool:" @@ -721,7 +721,7 @@ # Check for unknown partition scheme before proceeding further case "$ZFSBOOT_PARTITION_SCHEME" in - ""|MBR|GPT) : known good ;; + ""|MBR|GPT|BSD) : known good ;; *) f_dprintf "$funcname: %s is an unsupported partition scheme" \ "$ZFSBOOT_PARTITION_SCHEME" @@ -777,7 +777,7 @@ [ ${swapsize:-0} -gt 0 ] && targetpart=p3 # - # Prepare boot pool if enabled (e.g., for geli(8)) + # 3. Prepare boot pool if enabled (e.g., for geli(8)) # if [ "$ZFSBOOT_BOOT_POOL" ]; then bootpart=p2 swappart=p3 targetpart=p3 @@ -798,7 +798,7 @@ fi # - # 3. Add freebsd-swap partition labeled `swap#' + # 4. Add freebsd-swap partition labeled `swap#' # if [ ${swapsize:-0} -gt 0 ]; then f_eval_catch $funcname gpart \ @@ -811,7 +811,7 @@ fi # - # 4. Add freebsd-zfs partition labeled `zfs#' for zroot + # 5. Add freebsd-zfs partition labeled `zfs#' for zroot # f_eval_catch $funcname gpart "$GPART_ADD_LABEL" \ zfs$index freebsd-zfs $disk || return $FAILURE @@ -819,6 +819,87 @@ /dev/$disk$targetpart ;; + BSD) f_dprintf "$funcname: Creating BSD layout..." + # + # 1. Create BSD layout and write boot sector + # + f_eval_catch $funcname gpart "$GPART_CREATE" bsd $disk || + return $FAILURE + + bootpart=a swappart=b targetpart=a mbrindex=1 + # + # 2. Prepare boot pool if enabled (e.g., for geli(8)) + # + if [ "$ZFSBOOT_BOOT_POOL" ]; then + bootpart=a swappart=b targetpart=d mbrindex=4 + # + # 3. Create an unencrypted boot pool + # + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX_WITH_SIZE" 1 \ + freebsd-zfs ${bootsize}b $disk || + return $FAILURE + # Pedantically detach bootpart + f_eval_catch -d $funcname geli \ + "$GELI_DETACH_F" \ + /dev/$disk$bootpart + # Pedantically nuke any old labels + f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$bootpart + # + # 4. Add freebsd-swap partition + # + if [ ${swapsize:-0} -gt 0 ]; then + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX_WITH_SIZE" 2 \ + freebsd-swap ${swapsize}b $disk || + return $FAILURE + # Pedantically nuke any old labels on the swap + f_eval_catch -d $funcname zpool \ + "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$swappart + fi + # + # 5. Add second freebsd-zfs partition for main pool + # + f_eval_catch $funcname gpart "$GPART_ADD_INDEX" \ + $mbrindex freebsd-zfs $disk || + return $FAILURE + # Pedantically detach targetpart + f_eval_catch -d $funcname geli \ + "$GELI_DETACH_F" \ + /dev/$disk$targetpart + f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$targetpart + else + # + # 6. Create and boot off of the main pool + # + local partsize=$(( $disksize - $swapsize )) + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX_WITH_SIZE" $mbrindex \ + freebsd-zfs ${partsize}b $disk || + return $FAILURE + # Pedantically nuke any old labels + f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$bootpart + # + # 7. There is no partition after this, so autosize swap + # + if [ ${swapsize:-0} -gt 0 ]; then + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX" 2 \ + freebsd-swap $disk || + return $FAILURE + # Pedantically nuke any old labels on the swap + f_eval_catch -d $funcname zpool \ + "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$swappart + fi + fi + + ;; + MBR) f_dprintf "$funcname: Creating MBR layout..." # # 1. Create MBR layout (no labels) @@ -825,8 +906,6 @@ # f_eval_catch $funcname gpart "$GPART_CREATE" mbr $disk || return $FAILURE - f_eval_catch $funcname gpart "$GPART_BOOTCODE" /boot/mbr \ - $disk || return $FAILURE # # 2. Add freebsd slice with all available space @@ -847,50 +926,86 @@ f_eval_catch $funcname gpart "$GPART_CREATE" BSD ${disk}s1 || return $FAILURE - # NB: zpool will use s1a (no labels) - bootpart=s1a swappart=s1b targetpart=s1d mbrindex=4 + bootpart=s1a swappart=s1b targetpart=s1a mbrindex=1 # - # Always prepare a boot pool on MBR + # 4. Prepare boot pool if enabled (e.g., for geli(8)) # - ZFSBOOT_BOOT_POOL=1 - f_eval_catch $funcname gpart \ - "$GPART_ADD_INDEX_WITH_SIZE" \ - 1 freebsd-zfs ${bootsize}b ${disk}s1 || - return $FAILURE - # Pedantically nuke any old labels - f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ - /dev/$disk$bootpart - if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then + if [ "$ZFSBOOT_BOOT_POOL" ]; then + bootpart=s1a swappart=s1b targetpart=s1d mbrindex=4 + # + # 5. Create an unencrypted boot pool + # + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX_WITH_SIZE" 1 \ + freebsd-zfs ${bootsize}b $disk || + return $FAILURE + # Pedantically nuke any old labels + f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$bootpart # Pedantically detach targetpart for later f_eval_catch -d $funcname geli \ - "$GELI_DETACH_F" \ - /dev/$disk$targetpart - fi + "$GELI_DETACH_F" \ + /dev/$disk$bootpart + # + # 6. Add freebsd-swap partition + # + if [ ${swapsize:-0} -gt 0 ]; then + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX_WITH_SIZE" 2 \ + freebsd-swap ${swapsize}b \ + ${disk}s1 || return $FAILURE + # Pedantically nuke any old labels on the swap + f_eval_catch -d $funcname zpool \ + "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$swappart + fi + # + # 7. Add second freebsd-zfs partition for main pool + # + f_eval_catch $funcname gpart "$GPART_ADD_INDEX" \ + $mbrindex freebsd-zfs ${disk}s1 || + return $FAILURE + # Pedantically detach targetpart + f_eval_catch -d $funcname geli \ + "$GELI_DETACH_F" \ + /dev/$disk$targetpart + f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$targetpart # Pedantic - # - # 4. Add freebsd-swap partition - # - if [ ${swapsize:-0} -gt 0 ]; then + else + # + # 8. Create and boot off of the main pool + # + local partsize=$(( $disksize - $swapsize )) f_eval_catch $funcname gpart \ - "$GPART_ADD_INDEX_WITH_SIZE" 2 \ - freebsd-swap ${swapsize}b ${disk}s1 || - return $FAILURE - # Pedantically nuke any old labels on the swap + "$GPART_ADD_INDEX_WITH_SIZE" $mbrindex \ + freebsd-zfs ${partsize}b ${disk}s1 || + return $FAILURE + # Pedantically nuke any old labels f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ - /dev/${disk}s1b + /dev/$disk$bootpart + # + # 9. There is no partition after this, so autosize swap + # + if [ ${swapsize:-0} -gt 0 ]; then + f_eval_catch $funcname gpart \ + "$GPART_ADD_INDEX" 2 \ + freebsd-swap ${disk}s1 || + return $FAILURE + # Pedantically nuke any old labels on the swap + f_eval_catch -d $funcname zpool \ + "$ZPOOL_LABELCLEAR_F" \ + /dev/$disk$swappart + fi fi # - # 5. Add freebsd-zfs partition for zroot + # 10. Install bootcode # - f_eval_catch $funcname gpart "$GPART_ADD_INDEX" \ - $mbrindex freebsd-zfs ${disk}s1 || return $FAILURE - f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ - /dev/$disk$targetpart # Pedantic - f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ - /boot/zfsboot /dev/${disk}s1 count=1 || - return $FAILURE + f_eval_catch $funcname gpart "$GPART_BOOTCODE" /boot/mbr \ + $disk || return $FAILURE + ;; esac # $ZFSBOOT_PARTITION_SCHEME @@ -898,6 +1013,7 @@ # Update fstab(5) if [ "$isswapmirror" ]; then # This is not the first disk in the mirror, do nothing + true elif [ "$ZFSBOOT_SWAP_ENCRYPTION" -a "$ZFSBOOT_SWAP_MIRROR" ]; then f_eval_catch $funcname printf "$PRINTF_FSTAB" \ /dev/mirror/swap.eli none swap sw 0 0 \ @@ -1149,7 +1265,7 @@ # f_dprintf "$funcname: Creating root pool..." f_eval_catch $funcname zpool "$ZPOOL_CREATE_WITH_OPTIONS" \ - "-o altroot=$BSDINSTALL_CHROOT -O compress=lz4 + "-o altroot=$BSDINSTALL_CHROOT -O compress=lz4 \ -m none -f" \ "$zroot_name" "$zroot_vdevtype" "$zroot_vdevs" || return $FAILURE @@ -1230,7 +1346,7 @@ fi done - # MBR boot loader touch-up + # write remainder of boot loader for MBR and BSD if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then f_dprintf "$funcname: Updating MBR boot loader on disks..." # Stick the ZFS boot loader in the "convienient hole" after @@ -1239,7 +1355,23 @@ f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ /boot/zfsboot /dev/$disk$bootpart \ "skip=1 seek=1024" || return $FAILURE + f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ + /boot/zfsboot /dev/${disk}s1 count=1 || + return $FAILURE done + elif [ "$ZFSBOOT_PARTITION_SCHEME" = "BSD" ]; then + f_dprintf "$funcname: Updating BSD boot loader on disks..." + # Stick the ZFS boot loader in the "convienient hole" after + # the ZFS internal metadata + # Install the first bit last, else odd things happen + for disk in $disks; do + f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ + /boot/zfsboot /dev/$disk$bootpart \ + "skip=1 seek=1024" || return $FAILURE + f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ + /boot/zfsboot /dev/${disk} count=1 || + return $FAILURE + done fi # Re-import the ZFS pool(s) @@ -1426,8 +1558,8 @@ $disk $DEVICE_TYPE_DISK device $device get capacity disksize || continue [ ${disksize:-0} -ge 0 ] || disksize=0 - disksize=$(( $disksize - $minsize )) - [ $disksize -lt $minsize ] && + usablesize=$(( $disksize - $minsize )) + [ $usablesize -lt $minsize ] && teeny_disks="$teeny_disks $disk" done if [ "$teeny_disks" ]; then @@ -1499,9 +1631,11 @@ fi ;; ?" $msg_partition_scheme") - # Toggle between GPT and MBR + # Toggle between GPT, MBR, and BSD if [ "$ZFSBOOT_PARTITION_SCHEME" = GPT ]; then ZFSBOOT_PARTITION_SCHEME=MBR + elif [ "$ZFSBOOT_PARTITION_SCHEME" = MBR ]; then + ZFSBOOT_PARTITION_SCHEME=BSD else ZFSBOOT_PARTITION_SCHEME=GPT fi --------------020100060009040503090208--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53778722.9000608>