Installation on disks with 4k logical blocksize (4kn) failed, because the
bios_boot (a.k.a. gdisk partitiontype EF02, place for grub in legacy BIOS
boot mode) partition is created using start and end sectors (and sector 2047
is not at 1M, where the ESP starts)

This patch addresses the issue by not creating the bios_boot partition on
4kn disks at all - legacy boot from 4kn disks is not supported by most BIOS
implementations and grub does not support it [0].

Checks for 4kn disks, when booted in legacy mode are added, and prevent from
leaving the harddisk selection page, if an not bootable selection was made.

The partition numbering was kept (esp is partition 2, data is partition 3,
for consistency with other installations)

If any of the bootable disks is 4kn then the installation of the grub legacy
installation is skipped altogether.

Additionally the invokation of mkfs.vfat needs to add the parameter '-s1'
to create a bootable ESP on 4kn disks.

Tested with a qemu-machine by passing
'logical_block_size=4096,physical_block_size=4096' to the disk's device lines
and installing in UEFI and legacy booted mode:
* ZFS RAIDZ1
* ZFS single-disk
* ZFS RAID10 (in legacy mode grub fails to install, if any 4kn disk is in the
  pool, even if it's not in the first vdev)
* EXT4

[0] http://savannah.gnu.org/bugs/?46700

Signed-off-by: Stoiko Ivanov <s.iva...@proxmox.com>
---
 proxinstall | 58 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/proxinstall b/proxinstall
index d81d71d..f8bef52 100755
--- a/proxinstall
+++ b/proxinstall
@@ -975,11 +975,15 @@ sub partition_bootable_disk {
     syscmd($pcmd) == 0 ||
        die "unable to partition harddisk '${target_dev}'\n";
 
-    $pnum = 1;
-    $pcmd = ['sgdisk', '-a1', "-n$pnum:34:2047", "-t$pnum:EF02" , $target_dev];
+    my $blocksize = logical_blocksize($target_dev);
 
-    syscmd($pcmd) == 0 ||
-       die "unable to create bios_boot partition '${target_dev}'\n";
+    if ($blocksize != 4096) {
+       $pnum = 1;
+       $pcmd = ['sgdisk', '-a1', "-n$pnum:34:2047", "-t$pnum:EF02" , 
$target_dev];
+
+       syscmd($pcmd) == 0 ||
+           die "unable to create bios_boot partition '${target_dev}'\n";
+    }
 
     &$udevadm_trigger_block();
 
@@ -1289,6 +1293,8 @@ sub extract_data {
            my $disksize;
            foreach my $hd (@$devlist) {
                my $devname = @$hd[1];
+               my $logical_bsize = @$hd[4];
+
                &$clean_disk($devname);
                my ($size, $osdev, $efidev) =
                    partition_bootable_disk($devname, undef, '8300');
@@ -1299,6 +1305,7 @@ sub extract_data {
                    devname => $devname,
                    osdev => $osdev,
                    by_id => $by_id,
+                   logical_bsize => $logical_bsize,
                };
                push @$btrfs_partitions, $osdev;
                $disksize = $size;
@@ -1319,6 +1326,7 @@ sub extract_data {
            my $disksize;
            foreach my $hd (@$bootdevlist) {
                my $devname = @$hd[1];
+               my $logical_bsize = @$hd[4];
 
                my ($size, $osdev, $efidev) =
                    partition_bootable_disk($devname, 
$config_options->{hdsize}, 'BF01');
@@ -1328,7 +1336,8 @@ sub extract_data {
                push @$bootdevinfo, {
                    esp => $efidev,
                    devname => $devname,
-                   osdev => $osdev
+                   osdev => $osdev,
+                   logical_bsize => $logical_bsize,
                };
                $disksize = $size;
            }
@@ -1352,6 +1361,8 @@ sub extract_data {
 
            &$clean_disk($target_hd);
 
+           my $logical_bsize = logical_blocksize($target_hd);
+
            my ($os_size, $osdev, $efidev);
            ($os_size, $osdev, $efidev) =
                partition_bootable_disk($target_hd, $config_options->{hdsize}, 
'8E00');
@@ -1364,6 +1375,7 @@ sub extract_data {
                devname => $target_hd,
                osdev => $osdev,
                by_id => $by_id,
+               logical_bsize => $logical_bsize,
            };
 
            my $swap_size = compute_swapsize($os_size);
@@ -1390,7 +1402,8 @@ sub extract_data {
 
        foreach my $di (@$bootdevinfo) {
            next if !$di->{esp};
-           syscmd("mkfs.vfat -F32 $di->{esp}") == 0 ||
+           my $vfat_extra_opts = ($di->{logical_bsize} == 4096) ? '-s1' : '';
+           syscmd("mkfs.vfat $vfat_extra_opts -F32 $di->{esp}") == 0 ||
                die "unable to initialize EFI ESP on device $di->{esp}\n";
        }
 
@@ -1745,13 +1758,20 @@ _EOD
                syscmd("chroot $targetdir /usr/sbin/update-initramfs -c -k 
$kapi") == 0 ||
                    die "unable to install initramfs\n";
 
+               my $native_4k_disk_bootable = 0;
+               foreach my $di (@$bootdevinfo) {
+                   $native_4k_disk_bootable |= ($di->{logical_bsize} == 4096);
+               }
+
                foreach my $di (@$bootdevinfo) {
                    my $dev = $di->{devname};
-                   eval {
-                       syscmd("chroot $targetdir /usr/sbin/grub-install 
--target i386-pc --no-floppy --bootloader-id='proxmox' $dev") == 0 ||
-                               die "unable to install the i386-pc boot loader 
on '$dev'\n";
-                   };
-                   push @$bootloader_err_list, $@ if $@;
+                   if (!$native_4k_disk_bootable) {
+                       eval {
+                           syscmd("chroot $targetdir /usr/sbin/grub-install 
--target i386-pc --no-floppy --bootloader-id='proxmox' $dev") == 0 ||
+                                   die "unable to install the i386-pc boot 
loader on '$dev'\n";
+                       };
+                       push @$bootloader_err_list, $@ if $@;
+                   }
 
                    eval {
                        if (my $esp = $di->{esp}) {
@@ -3138,6 +3158,12 @@ sub zfs_mirror_size_check {
        if abs($expected - $actual) > $expected / 10;
 }
 
+sub legacy_bios_4k_check {
+    my ($lbs) = @_;
+    die "Booting from 4kn drive in legacy BIOS mode is not supported.\n"
+       if (($boot_type ne 'efi') && ($lbs == 4096));
+}
+
 sub get_zfs_raid_setup {
 
     my $filesys = $config_options->{filesys};
@@ -3153,6 +3179,7 @@ sub get_zfs_raid_setup {
     if ($filesys eq 'zfs (RAID0)') {
        push @$bootdevlist, @$devlist[0];
        foreach my $hd (@$devlist) {
+           legacy_bios_4k_check(@$hd[4]);
            $cmd .= " @$hd[1]";
        }
     } elsif ($filesys eq 'zfs (RAID1)') {
@@ -3162,6 +3189,7 @@ sub get_zfs_raid_setup {
        my $expected_size = @$hd[2]; # all disks need approximately same size
        foreach $hd (@$devlist) {
            zfs_mirror_size_check($expected_size, @$hd[2]);
+           legacy_bios_4k_check(@$hd[4]);
            $cmd .= " @$hd[1]";
            push @$bootdevlist, $hd;
        }
@@ -3175,6 +3203,8 @@ sub get_zfs_raid_setup {
            my $hd1 = @$devlist[$i];
            my $hd2 = @$devlist[$i+1];
            zfs_mirror_size_check(@$hd1[2], @$hd2[2]); # pairs need 
approximately same size
+           legacy_bios_4k_check(@$hd1[4]);
+           legacy_bios_4k_check(@$hd2[4]);
            $cmd .= ' mirror ' . @$hd1[1] . ' ' . @$hd2[1];
        }
 
@@ -3187,6 +3217,7 @@ sub get_zfs_raid_setup {
        $cmd .= " raidz$level";
        foreach $hd (@$devlist) {
            zfs_mirror_size_check($expected_size, @$hd[2]);
+           legacy_bios_4k_check(@$hd[4]);
            $cmd .= " @$hd[1]";
            push @$bootdevlist, $hd;
        }
@@ -3294,6 +3325,11 @@ sub create_hdsel_view {
            }
            $config_options->{target_hds} = [ map { $_->[1] } @$devlist ];
        } else {
+           eval { legacy_bios_4k_check(logical_blocksize($target_hd)) };
+           if (my $err = $@) {
+               display_message("Warning: $err\n");
+               return;
+           }
            $config_options->{target_hds} = [ $target_hd ];
        }
 
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to