]> git.proxmox.com Git - pve-manager.git/commitdiff
Fix #2051: preserve DB/WAL disk on destroy
authorAlwin Antreich <a.antreich@proxmox.com>
Thu, 7 Feb 2019 15:29:41 +0000 (16:29 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 8 Feb 2019 13:20:23 +0000 (14:20 +0100)
When destroying an OSD over API or CLI, e.g. by executing:

'pveceph osd destroy <num> --cleanup'

all disks associated with the OSD got wiped with dd, which included
any shared and by others still in use ones, e.g., separate disks with
DB/WAL.

The patch changes 'wipe_disks' to wipe the partition instead of the
whole disk.

Signed-off-by: Alwin Antreich <a.antreich@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
PVE/API2/Ceph/OSD.pm
PVE/Ceph/Tools.pm

index b4dc277ea9bdba310f9518661168101aae3604ae..9c08e37099753671ab50ea171e03b6e9402f5f63 100644 (file)
@@ -394,7 +394,6 @@ __PACKAGE__->register_method ({
            # try to unmount from standard mount point
            my $mountpoint = "/var/lib/ceph/osd/ceph-$osdid";
 
-           my $disks_to_wipe = {};
            my $remove_partition = sub {
                my ($part) = @_;
 
@@ -402,11 +401,10 @@ __PACKAGE__->register_method ({
                my $partnum = PVE::Diskmanage::get_partnum($part);
                my $devpath = PVE::Diskmanage::get_blockdev($part);
 
+               PVE::Ceph::Tools::wipe_disks($part);
                print "remove partition $part (disk '${devpath}', partnum $partnum)\n";
                eval { run_command(['/sbin/sgdisk', '-d', $partnum, "${devpath}"]); };
                warn $@ if $@;
-
-               $disks_to_wipe->{$devpath} = 1;
            };
 
            my $partitions_to_remove = [];
@@ -418,7 +416,9 @@ __PACKAGE__->register_method ({
                        next if !($dev && $path && $fstype);
                        next if $dev !~ m|^/dev/|;
                        if ($path eq $mountpoint) {
-                           my $data_part = abs_path($dev);
+                           my ($data_part) = abs_path($dev) =~ m|^(/.+)|
+                               or die "invalid path: $path \n"; # untaint $part
+
                            push @$partitions_to_remove, $data_part;
                            last;
                        }
@@ -427,7 +427,9 @@ __PACKAGE__->register_method ({
                }
 
                foreach my $path (qw(journal block block.db block.wal)) {
-                   my $part = abs_path("$mountpoint/$path");
+                   my ($part) = abs_path("$mountpoint/$path") =~ m|^(/.+)|
+                       or die "invalid path: $path \n"; # untaint $part
+
                    if ($part) {
                        push @$partitions_to_remove, $part;
                    }
@@ -443,8 +445,6 @@ __PACKAGE__->register_method ({
                foreach my $part (@$partitions_to_remove) {
                    $remove_partition->($part);
                }
-
-               PVE::Ceph::Tools::wipe_disks(keys %$disks_to_wipe);
            }
        };
 
index 0ada98cfefa12fdd017963b466ce6c41c6561e97..9b02d7c89689d3113519003b810e35d3d0d39e16 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use warnings;
 
 use File::Path;
+use File::Basename;
 use IO::File;
 
 use PVE::Tools qw(run_command dir_glob_foreach);
@@ -232,11 +233,21 @@ sub systemd_managed {
 sub wipe_disks {
     my (@devs) = @_;
 
-    my @wipe_cmd = qw(/bin/dd if=/dev/zero bs=1M count=200 conv=fdatasync);
+    my @wipe_cmd = qw(/bin/dd if=/dev/zero bs=1M conv=fdatasync);
+
     foreach my $devpath (@devs) {
-        print "wipe disk: $devpath\n";
-        eval { run_command([@wipe_cmd, "of=${devpath}"]) };
-        warn $@ if $@;
+       my $devname = basename($devpath);
+       my $dev_size = PVE::Tools::file_get_contents("/sys/class/block/$devname/size");
+
+       ($dev_size) = $dev_size =~ m|(\d+)|; # untaint $dev_size
+       die "Coulnd't get the size of the device $devname\n" if (!defined($dev_size));
+
+       my $size = ($dev_size * 512 / 1024 / 1024);
+       my $count = ($size < 200) ? $size : 200;
+
+       print "wipe disk/partition: $devpath\n";
+       eval { run_command([@wipe_cmd, "count=$count", "of=${devpath}"]) };
+       warn $@ if $@;
     }
 };