RBD: disable and enable features depending on kernel version

Modern kernel, like 5.3, support all those features ('fast-diff',
'object-map', 'deep-flatten'), so we do not want to disable them
there. 5.0 already supports exclusive-locks, so no need to disable
exclusive locking there.

Further, we also want to profit from new features available, so let's
enable those which can be enabled "live" (i.e., after image creation)
if their available.

While we could also parse the kernel information directly from:
/sys/module/libceph/parameters/supported_features
there's not much advantage to that, features cannot be disabled with
KConfig, their also very dependent of the kernel version booted.
So for us it's enough to check that one.

This only affects container and VMs backed by a storage with KRBD
explicitly enabled. But as the enabling and disabling happens
transparently, it has no effect on the running guest.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht
2019-11-23 15:37:46 +01:00
parent 5102900d50
commit 0ef8fb9d4d

View File

@ -9,6 +9,7 @@ use Net::IP;
use PVE::CephConfig;
use PVE::JSONSchema qw(get_standard_option);
use PVE::ProcFSTools;
use PVE::RADOS;
use PVE::Storage::Plugin;
use PVE::Tools qw(run_command trim);
@ -73,21 +74,52 @@ my $librados_connect = sub {
};
# needed for volumes created using ceph jewel (or higher)
my $krbd_feature_disable = sub {
my $krbd_feature_update = sub {
my ($scfg, $storeid, $name) = @_;
my ($versionparts) = ceph_version();
return 1 if $versionparts->[0] < 10;
my $krbd_feature_blacklist = ['deep-flatten', 'fast-diff', 'object-map', 'exclusive-lock'];
my (undef, undef, undef, undef, $features) = rbd_volume_info($scfg, $storeid, $name);
my (@disable, @enable);
my ($kmajor, $kminor) = PVE::ProcFSTools::kernel_version();
my $active_features = { map { $_ => 1 } @$features };
my $incompatible_features = join(',', grep { %$active_features{$_} } @$krbd_feature_blacklist);
if ($kmajor > 5 || $kmajor == 5 && $kminor >= 3) {
# 'deep-flatten' can only be disabled, not enabled after image creation
push @enable, 'fast-diff', 'object-map';
} else {
push @disable, 'fast-diff', 'object-map', 'deep-flatten';
}
if ($incompatible_features) {
my $feature_cmd = &$rbd_cmd($scfg, $storeid, 'feature', 'disable', $name, $incompatible_features);
run_rbd_command($feature_cmd, errmsg => "could not disable krbd-incompatible image features of rbd volume $name");
if ($kmajor >= 5) {
push @enable, 'exclusive-lock';
} else {
push @disable, 'exclusive-lock';
}
my $active_features_list = (rbd_volume_info($scfg, $storeid, $name))[4];
my $active_features = { map { $_ => 1 } @$active_features_list };
my $to_disable = join(',', grep { $active_features->{$_} } @disable);
my $to_enable = join(',', grep { !$active_features->{$_} } @enable );
if ($to_disable) {
print "disable RBD image features this kernel RBD drivers is not compatible with: $to_disable\n";
my $cmd = $rbd_cmd->($scfg, $storeid, 'feature', 'disable', $name, $to_disable);
run_rbd_command(
$cmd,
errmsg => "could not disable krbd-incompatible image features '$to_disable' for rbd image: $name",
);
}
if ($to_enable) {
print "enable RBD image features this kernel RBD drivers supports: $to_enable\n";
eval {
my $cmd = $rbd_cmd->($scfg, $storeid, 'feature', 'enable', $name, $to_enable);
run_rbd_command(
$cmd,
errmsg => "could not enable krbd-compatible image features '$to_enable' for rbd image: $name",
);
};
warn "$@" if $@;
}
};
@ -557,7 +589,7 @@ sub map_volume {
return $kerneldev if -b $kerneldev; # already mapped
&$krbd_feature_disable($scfg, $storeid, $name);
$krbd_feature_update->($scfg, $storeid, $name);
my $cmd = &$rbd_cmd($scfg, $storeid, 'map', $name);
run_rbd_command($cmd, errmsg => "can't map rbd volume $name");