[pve-devel] [PATCH manager v2 8/8] fix: ceph: always set pool size first

Alwin Antreich a.antreich at proxmox.com
Tue Nov 24 11:58:11 CET 2020


Since Ceph Nautilus 14.2.10 and Octopus 15.2.2 the min_size of a pool is
calculated by the size (round(size / 2)). When size is applied after
min_size to the pool, the manual specified min_size will be overwritten.

With that a race condition can occur if the setting was set but is not
active yet. Run an extra rados command to verify the current setting.

Signed-off-by: Alwin Antreich <a.antreich at proxmox.com>
---
 PVE/Ceph/Tools.pm | 49 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/PVE/Ceph/Tools.pm b/PVE/Ceph/Tools.pm
index d95e8676..9505f0bf 100644
--- a/PVE/Ceph/Tools.pm
+++ b/PVE/Ceph/Tools.pm
@@ -203,16 +203,51 @@ sub check_ceph_enabled {
 sub set_pool {
     my ($pool, $param) = @_;
 
+    # by default pool size always sets min_size
+    # https://tracker.ceph.com/issues/44862
+    my $rados = PVE::RADOS->new();
+    if ($param->{size}) {
+	my $value = $param->{size};
+	eval { $rados->mon_command({
+		    prefix => "osd pool set",
+		    pool   => "$pool",
+		    var    => "size",
+		    val    => "$value",
+		    format => 'plain',
+		});
+	};
+	if ($@) {
+	    print "$@";
+	} else {
+	    my $result;
+	    eval { $result = $rados->mon_command({
+			prefix => "osd pool get",
+			pool   => "$pool",
+			var    => "size",
+		    });
+	    };
+	    if (!$@ && $result->{size} eq $value) {
+		delete $param->{size};
+	    }
+	}
+    }
+
     foreach my $setting (keys %$param) {
 	my $value = $param->{$setting};
+	next if $setting eq 'size';
 
 	my $command;
+	my $verify;
 	if ($setting eq 'application') {
 	    $command = {
 		prefix => "osd pool application enable",
 		pool   => "$pool",
 		app    => "$value",
 	    };
+	    $verify = {
+		prefix => "osd pool application get",
+		pool   => "$pool",
+	    };
 	} else {
 	    $command = {
 		prefix => "osd pool set",
@@ -221,14 +256,24 @@ sub set_pool {
 		val    => "$value",
 		format => 'plain',
 	    };
+
+	    $verify = {
+		prefix => "osd pool get",
+		pool   => "$pool",
+		var    => "$setting",
+	    };
 	}
 
-	my $rados = PVE::RADOS->new();
+	$rados = PVE::RADOS->new();
 	eval { $rados->mon_command($command); };
 	if ($@) {
 	    print "$@";
 	} else {
-	    delete $param->{$setting};
+	    my $result;
+	    eval { $result = $rados->mon_command($verify); };
+	    if (!$@ && $result->{$setting} eq $value) {
+		delete $param->{$setting};
+	    }
 	}
     }
 
-- 
2.27.0






More information about the pve-devel mailing list