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.antre...@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



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

Reply via email to