[pve-devel] applied: [PATCH storage] RBD: disable and enable features depending on kernel version

Thomas Lamprecht t.lamprecht at proxmox.com
Sat Nov 23 16:26:41 CET 2019


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 at proxmox.com>
---

Tested live-migration, of VM on KRDB enforced storage, CT restart-migrations,
on hosts with different kernel booted (5.0.21-5 and 5.3.10-1) while monitoring
`rbd -p <pool> info <image>` commands.

 PVE/Storage/RBDPlugin.pm | 50 ++++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/PVE/Storage/RBDPlugin.pm b/PVE/Storage/RBDPlugin.pm
index cddad02..eb1f9a0 100644
--- a/PVE/Storage/RBDPlugin.pm
+++ b/PVE/Storage/RBDPlugin.pm
@@ -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");
-- 
2.20.1





More information about the pve-devel mailing list