]> git.proxmox.com Git - pve-manager.git/blobdiff - PVE/Ceph/Tools.pm
ceph tools: set_pools: filter settings for erasure code pools
[pve-manager.git] / PVE / Ceph / Tools.pm
index 2459e882a5347c573110be48c53cbd9bf131c60f..a1458b40547487f9c37fb65a0c6c81e7cf398eb9 100644 (file)
@@ -8,7 +8,7 @@ use File::Basename;
 use IO::File;
 use JSON;
 
-use PVE::Tools qw(run_command dir_glob_foreach);
+use PVE::Tools qw(run_command dir_glob_foreach extract_param);
 use PVE::Cluster qw(cfs_read_file);
 use PVE::RADOS;
 use PVE::Ceph::Services;
@@ -205,7 +205,7 @@ sub check_ceph_enabled {
 }
 
 my $set_pool_setting = sub {
-    my ($pool, $setting, $value) = @_;
+    my ($pool, $setting, $value, $rados) = @_;
 
     my $command;
     if ($setting eq 'application') {
@@ -224,7 +224,7 @@ my $set_pool_setting = sub {
        };
     }
 
-    my $rados = PVE::RADOS->new();
+    $rados = PVE::RADOS->new() if !$rados;
     eval { $rados->mon_command($command); };
     return $@ ? $@ : undef;
 };
@@ -232,6 +232,18 @@ my $set_pool_setting = sub {
 sub set_pool {
     my ($pool, $param) = @_;
 
+    my $rados = PVE::RADOS->new();
+
+    if (get_pool_type($pool, $rados) eq 'erasure') {
+       #remove parameters that cannot be changed for erasure coded pools
+       my $ignore_params = ['size', 'crush_rule'];
+       for my $setting (@$ignore_params) {
+           if ($param->{$setting}) {
+               print "cannot set '${setting}' for erasure coded pool\n";
+               delete $param->{$setting};
+           }
+       }
+    }
     # by default, pool size always resets min_size, so set it as first item
     # https://tracker.ceph.com/issues/44862
     my $keys = [ grep { $_ ne 'size' } sort keys %$param ];
@@ -241,7 +253,7 @@ sub set_pool {
        my $value = $param->{$setting};
 
        print "pool $pool: applying $setting = $value\n";
-       if (my $err = $set_pool_setting->($pool, $setting, $value)) {
+       if (my $err = $set_pool_setting->($pool, $setting, $value, $rados)) {
            print "$err";
        } else {
            delete $param->{$setting};
@@ -256,30 +268,41 @@ sub set_pool {
 }
 
 sub get_pool_properties {
-    my ($pool) = @_;
+    my ($pool, $rados) = @_;
+    $rados = PVE::RADOS->new() if !defined($rados);
     my $command = {
        prefix => "osd pool get",
        pool   => "$pool",
        var    => "all",
        format => 'json',
     };
-
-    my $rados = PVE::RADOS->new();
     return $rados->mon_command($command);
 }
 
+sub get_pool_type {
+    my ($pool, $rados) = @_;
+    $rados = PVE::RADOS->new() if !defined($rados);
+    return 'erasure' if get_pool_properties($pool, $rados)->{erasure_code_profile};
+    return 'replicated';
+}
+
 sub create_pool {
     my ($pool, $param, $rados) = @_;
     $rados = PVE::RADOS->new() if !defined($rados);
 
     my $pg_num = $param->{pg_num} || 128;
 
-    $rados->mon_command({
+    my $mon_params = {
        prefix => "osd pool create",
        pool => $pool,
        pg_num => int($pg_num),
        format => 'plain',
-    });
+    };
+    $mon_params->{pool_type} = extract_param($param, 'pool_type') if $param->{pool_type};
+    $mon_params->{erasure_code_profile} = extract_param($param, 'erasure_code_profile')
+       if $param->{erasure_code_profile};
+
+    $rados->mon_command($mon_params);
 
     set_pool($pool, $param);
 
@@ -530,9 +553,9 @@ sub ceph_cluster_status {
 }
 
 sub ecprofile_exists {
-    my ($name) = @_;
+    my ($name, $rados) = @_;
+    $rados = PVE::RADOS->new() if !$rados;
 
-    my $rados = PVE::RADOS->new();
     my $res = $rados->mon_command({ prefix => 'osd erasure-code-profile ls' });
 
     my $profiles = { map { $_ => 1 } @$res };
@@ -540,7 +563,8 @@ sub ecprofile_exists {
 }
 
 sub create_ecprofile {
-    my ($name, $k, $m, $failure_domain, $device_class) = @_;
+    my ($name, $k, $m, $failure_domain, $device_class, $rados) = @_;
+    $rados = PVE::RADOS->new() if !$rados;
 
     $failure_domain = 'host' if !$failure_domain;
 
@@ -552,7 +576,6 @@ sub create_ecprofile {
 
     push(@$profile, "crush-device-class=${device_class}") if $device_class;
 
-    my $rados = PVE::RADOS->new();
     $rados->mon_command({
        prefix => 'osd erasure-code-profile set',
        name => $name,
@@ -561,9 +584,9 @@ sub create_ecprofile {
 }
 
 sub destroy_ecprofile {
-    my ($profile) = @_;
+    my ($profile, $rados) = @_;
+    $rados = PVE::RADOS->new() if !$rados;
 
-    my $rados = PVE::RADOS->new();
     my $command = {
        prefix => 'osd erasure-code-profile rm',
        name => $profile,
@@ -578,8 +601,9 @@ sub get_ecprofile_name {
 }
 
 sub destroy_crush_rule {
-    my ($rule) = @_;
-    my $rados = PVE::RADOS->new();
+    my ($rule, $rados) = @_;
+    $rados = PVE::RADOS->new() if !$rados;
+
     my $command = {
        prefix => 'osd crush rule rm',
        name => $rule,