]> git.proxmox.com Git - pve-installer.git/blobdiff - proxinstall
wipe partitiontable after early exits
[pve-installer.git] / proxinstall
index 6ee3aa0bad000365e132f4a8d0969eb31be452c3..7873acea66c0e3037fdeb2cf1a856d50e2dc34af 100755 (executable)
@@ -568,7 +568,7 @@ sub hd_list {
        my @disks = split /,/, $opt_testmode;
 
        for my $disk (@disks) {
-           push @$res, [-1, $disk, int((-s $disk)/512), "TESTDISK"];
+           push @$res, [-1, $disk, int((-s $disk)/512), "TESTDISK", 512];
        }
        return $res;
     }
@@ -611,7 +611,12 @@ sub hd_list {
            if (length ($model) > 30) {
                $model = substr ($model, 0, 30);
            }
-           push @$res, [$count++, $real_name, $size, $model] if $size;
+
+           my $logical_bsize = file_read_firstline("$bd/queue/logical_block_size") // '';
+           chomp $logical_bsize;
+           $logical_bsize = undef if !($logical_bsize && $logical_bsize =~ m/^\d+$/);
+
+           push @$res, [$count++, $real_name, $size, $model, $logical_bsize] if $size;
        } else {
            print STDERR "ERROR: unable to map device $dev ($bd)\n";
        }
@@ -685,14 +690,25 @@ sub hd_size {
     my ($dev) = @_;
 
     foreach my $hd (@$hds) {
-       my ($disk, $devname, $size, $model) = @$hd;
-       # size is always in 512B "sectors"! convert to KB
+       my ($disk, $devname, $size, $model, $logical_bsize) = @$hd;
+       # size is always (also for 4kn disks) in 512B "sectors"! convert to KB
        return int($size/2) if $devname eq $dev;
     }
 
     die "no such device '$dev'\n";
 }
 
+sub logical_blocksize {
+    my ($dev) = @_;
+
+    foreach my $hd (@$hds) {
+       my ($disk, $devname, $size, $model, $logical_bsize) = @$hd;
+       return $logical_bsize if $devname eq $dev;
+    }
+
+    die "no such device '$dev'\n";
+}
+
 sub get_partition_dev {
     my ($dev, $partnum) = @_;
 
@@ -921,7 +937,6 @@ sub partition_bootable_disk {
     die "unknown partition type '$ptype'"
        if !($ptype eq '8E00' || $ptype eq '8300' || $ptype eq 'BF01');
 
-    syscmd("sgdisk -Z ${target_dev}");
     my $hdsize = hd_size($target_dev); # size in KB (1024 bytes)
 
     my $restricted_hdsize_mb = 0; # 0 ==> end of partition
@@ -936,6 +951,8 @@ sub partition_bootable_disk {
     my $hdgb = int($hdsize/(1024*1024));
     die "hardisk '$target_dev' too small (${hdgb}GB)\n" if $hdgb < 8;
 
+    syscmd("sgdisk -Z ${target_dev}");
+
     # 1 - BIOS boot partition (Grub Stage2): first free 1M
     # 2 - EFI ESP: next free 512M
     # 3 - OS/Data partition: rest, up to $maxhdsize in MB
@@ -959,11 +976,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();
 
@@ -1273,13 +1294,20 @@ 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');
                $rootdev = $osdev if !defined($rootdev); # simply point to first disk
                my $by_id = find_stable_path("/dev/disk/by-id", $devname);
-               push @$bootdevinfo, { esp => $efidev, devname => $devname,
-                                     osdev => $osdev, by_id => $by_id };
+               push @$bootdevinfo, {
+                   esp => $efidev,
+                   devname => $devname,
+                   osdev => $osdev,
+                   by_id => $by_id,
+                   logical_bsize => $logical_bsize,
+               };
                push @$btrfs_partitions, $osdev;
                $disksize = $size;
            }
@@ -1299,6 +1327,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');
@@ -1308,7 +1337,8 @@ sub extract_data {
                push @$bootdevinfo, {
                    esp => $efidev,
                    devname => $devname,
-                   osdev => $osdev
+                   osdev => $osdev,
+                   logical_bsize => $logical_bsize,
                };
                $disksize = $size;
            }
@@ -1332,6 +1362,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');
@@ -1339,8 +1371,13 @@ sub extract_data {
            &$udevadm_trigger_block();
 
            my $by_id = find_stable_path ("/dev/disk/by-id", $target_hd);
-           push @$bootdevinfo, { esp => $efidev, devname => $target_hd,
-                                 osdev => $osdev, by_id => $by_id };
+           push @$bootdevinfo, {
+               esp => $efidev,
+               devname => $target_hd,
+               osdev => $osdev,
+               by_id => $by_id,
+               logical_bsize => $logical_bsize,
+           };
 
            my $swap_size = compute_swapsize($os_size);
            ($rootdev, $swapfile, $datadev) =
@@ -1366,7 +1403,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";
        }
 
@@ -1643,6 +1681,8 @@ _EOD
        syscmd("chroot $targetdir /usr/sbin/postfix check");
        # cleanup mail queue
        syscmd("chroot $targetdir /usr/sbin/postsuper -d ALL");
+       # create /etc/aliases.db (/etc/aliases is shipped in the base squashfs)
+       syscmd("chroot $targetdir /usr/bin/newaliases");
 
        # enable NTP (timedatectl set-ntp true  does not work without DBUS)
        syscmd("chroot $targetdir /bin/systemctl enable systemd-timesyncd.service");
@@ -1719,13 +1759,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}) {
@@ -2759,7 +2806,7 @@ my $create_raid_disk_grid = sub {
        $disk_selector->set_active(0);
        $disk_selector->set_visible(1);
        foreach my $hd (@$hds) {
-           my ($disk, $devname, $size, $model) = @$hd;
+           my ($disk, $devname, $size, $model, $logical_bsize) = @$hd;
            $disk_selector->append_text(get_device_desc ($devname, $size, $model));
            $disk_selector->{pve_disk_id} = $i;
            $disk_selector->signal_connect (changed => sub {
@@ -3094,7 +3141,7 @@ my $get_raid_devlist = sub {
     my $devlist = [];
     for (my $i = 0; $i < @$hds; $i++) {
        if (my $hd = $config_options->{"disksel$i"}) {
-           my ($disk, $devname, $size, $model) = @$hd;
+           my ($disk, $devname, $size, $model, $logical_bsize) = @$hd;
            die "device '$devname' is used more than once\n"
                if $dev_name_hash->{$devname};
            $dev_name_hash->{$devname} = $hd;
@@ -3112,6 +3159,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};
@@ -3127,6 +3180,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)') {
@@ -3136,6 +3190,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;
        }
@@ -3149,6 +3204,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];
        }
 
@@ -3161,6 +3218,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;
        }
@@ -3213,7 +3271,7 @@ sub create_hdsel_view {
     my $hbox =  Gtk3::HBox->new(0, 0);
     $vbox->pack_start($hbox, 0, 0, 10);
 
-    my ($disk, $devname, $size, $model) = @{@$hds[0]};
+    my ($disk, $devname, $size, $model, $logical_bsize) = @{@$hds[0]};
     $target_hd = $devname if !defined($target_hd);
 
     $target_hd_label = Gtk3::Label->new("Target Harddisk: ");
@@ -3222,7 +3280,7 @@ sub create_hdsel_view {
     $target_hd_combo = Gtk3::ComboBoxText->new();
 
     foreach my $hd (@$hds) {
-       ($disk, $devname, $size, $model) = @$hd;
+       ($disk, $devname, $size, $model, $logical_bsize) = @$hd;
        $target_hd_combo->append_text (get_device_desc($devname, $size, $model));
     }
 
@@ -3268,6 +3326,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 ];
        }