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;
}
my $set_pool_setting = sub {
- my ($pool, $setting, $value) = @_;
+ my ($pool, $setting, $value, $rados) = @_;
my $command;
if ($setting eq 'application') {
};
}
- my $rados = PVE::RADOS->new();
+ $rados = PVE::RADOS->new() if !$rados;
eval { $rados->mon_command($command); };
return $@ ? $@ : undef;
};
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 ];
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};
}
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);
}
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 };
}
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;
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,
}
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,
}
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,