]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Diskmanage.pm
pbs: integrate support for protected
[pve-storage.git] / PVE / Diskmanage.pm
index 36f452c46d775c5aba6f52e964ff6ac21436af7f..18459f95291a5f70af8c051d49208cb7705fee71 100644 (file)
@@ -63,8 +63,8 @@ sub init_disk {
 
     assert_blockdev($disk);
 
-    # we should already have checked if it is in use in the api call
-    # but we check again for safety
+    # we should already have checked these in the api call, but we check again for safety
+    die "$disk is a partition\n" if is_partition($disk);
     die "disk $disk is already in use\n" if disk_is_used($disk);
 
     my $id = $uuid || 'R';
@@ -78,7 +78,7 @@ sub disk_is_used {
     my $dev = $disk;
     $dev =~ s|^/dev/||;
 
-    my $disklist = get_disks($dev, 1);
+    my $disklist = get_disks($dev, 1, 1);
 
     die "'$disk' is not a valid local disk\n" if !defined($disklist->{$dev});
     return 1 if $disklist->{$dev}->{used};
@@ -661,7 +661,7 @@ sub get_disks {
            # for devices, this check is done explicitly later
            return 'Device Mapper' if !dir_is_empty("$sysdir/holders");
 
-           return 'partition';
+           return; # unused partition
        };
 
        my $collect_ceph_info = sub {
@@ -730,7 +730,6 @@ sub get_disks {
        my $used = $determine_usage->($devpath, $sysdir, 0);
        if (!$include_partitions) {
            foreach my $part (sort keys %{$partitions}) {
-               next if $partitions->{$part}->{used} eq 'partition';
                $used //= $partitions->{$part}->{used};
            }
        } else {
@@ -813,6 +812,12 @@ sub get_blockdev {
     return $block_dev;
 }
 
+sub is_partition {
+    my ($dev_path) = @_;
+
+    return defined(eval { get_partnum($dev_path) });
+}
+
 sub locked_disk_action {
     my ($sub) = @_;
     my $res = PVE::Tools::lock_file('/run/lock/pve-diskmanage.lck', undef, $sub);
@@ -903,7 +908,25 @@ sub is_mounted {
     return $found;
 }
 
+# Currently only supports GPT-partitioned disks.
+sub change_parttype {
+    my ($partpath, $parttype) = @_;
+
+    my $err = "unable to change partition type for $partpath";
+
+    my $partnum = get_partnum($partpath);
+    my $blockdev = get_blockdev($partpath);
+    my $dev = strip_dev($blockdev);
+
+    my $info = get_disks($dev, 1);
+    die "$err - unable to get disk info for '$blockdev'\n" if !defined($info->{$dev});
+    die "$err - disk '$blockdev' is not GPT partitioned\n" if !$info->{$dev}->{gpt};
+
+    run_command(['sgdisk', "-t${partnum}:${parttype}", $blockdev], errmsg => $err);
+}
+
 # Wipes all labels and the first 200 MiB of a disk/partition (or the whole if it is smaller).
+# If called with a partition, also sets the partition type to 0x83 'Linux filesystem'.
 # Expected to be called with a result of verify_blockdev_path().
 sub wipe_blockdev {
     my ($devpath) = @_;
@@ -936,6 +959,11 @@ sub wipe_blockdev {
        ['dd', 'if=/dev/zero', "of=${devpath}", 'bs=1M', 'conv=fdatasync', "count=${count}"],
        errmsg => "error wiping '${devpath}'",
     );
+
+    if (is_partition($devpath)) {
+       eval { change_parttype($devpath, '8300'); };
+       warn $@ if $@;
+    }
 }
 
 1;