[pve-devel] [PATCH manager 3/9] api: ceph: create osd: work around udev bug

Fabian Ebner f.ebner at proxmox.com
Tue Sep 28 13:39:55 CEST 2021


There is a udev bug [0] which can ultimately lead to the udev database
for certain devices not being actively updated. The Diskmanage package
relies upon lsblk for certain info, and lsblk queries the udev
database. Ensure the information is updated by manually calling
'udevadm trigger' for the changed devices.

Without the fix, and a bit of bad luck, a cleaned up disk could still
show up as an 'LVM2_member' for example.

[0]: https://github.com/systemd/systemd/issues/18525

Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---
 PVE/API2/Ceph/OSD.pm | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/PVE/API2/Ceph/OSD.pm b/PVE/API2/Ceph/OSD.pm
index 97393912..fbbc2139 100644
--- a/PVE/API2/Ceph/OSD.pm
+++ b/PVE/API2/Ceph/OSD.pm
@@ -371,6 +371,9 @@ __PACKAGE__->register_method ({
 	    file_set_contents($ceph_bootstrap_osd_keyring, $bindata);
 	};
 
+	# See FIXME below
+	my @udev_trigger_devs = ();
+
 	my $create_part_or_lv = sub {
 	    my ($dev, $size, $type) = @_;
 
@@ -393,6 +396,8 @@ __PACKAGE__->register_method ({
 		PVE::Storage::LVMPlugin::lvm_create_volume_group($dev->{devpath}, $vg);
 		PVE::Storage::LVMPlugin::lvcreate($vg, $lv, "${size}k");
 
+		push @udev_trigger_devs, $dev->{devpath};
+
 		return "$vg/$lv";
 
 	    } elsif ($dev->{used} eq 'LVM') {
@@ -423,7 +428,9 @@ __PACKAGE__->register_method ({
 	    } elsif ($dev->{used} eq 'partitions' && $dev->{gpt}) {
 		# create new partition at the end
 
-		return PVE::Diskmanage::append_partition($dev->{devpath}, $size * 1024);
+		my $part = PVE::Diskmanage::append_partition($dev->{devpath}, $size * 1024);
+		push @udev_trigger_devs, $part;
+		return $part;
 	    }
 
 	    die "cannot use '$dev->{devpath}' for '$type'\n";
@@ -445,6 +452,8 @@ __PACKAGE__->register_method ({
 		my $devpath = $disklist->{$devname}->{devpath};
 		print "create OSD on $devpath (bluestore)\n";
 
+		push @udev_trigger_devs, $devpath;
+
 		my $osd_size = $disklist->{$devname}->{size};
 		my $size_map = {
 		    db => int($osd_size / 10), # 10% of OSD
@@ -476,6 +485,12 @@ __PACKAGE__->register_method ({
 		PVE::Diskmanage::wipe_blockdev($devpath);
 
 		run_command($cmd);
+
+		# FIXME: Remove once we depend on systemd >= v249.
+		# Work around udev bug https://github.com/systemd/systemd/issues/18525 to ensure the
+		# udev database is updated.
+		eval { run_command(['udevadm', 'trigger', @udev_trigger_devs]); };
+		warn $@ if $@;
 	    });
 	};
 
@@ -583,6 +598,9 @@ __PACKAGE__->register_method ({
 	    # try to unmount from standard mount point
 	    my $mountpoint = "/var/lib/ceph/osd/ceph-$osdid";
 
+	    # See FIXME below
+	    my $udev_trigger_devs = {};
+
 	    my $remove_partition = sub {
 		my ($part) = @_;
 
@@ -590,6 +608,8 @@ __PACKAGE__->register_method ({
 		my $partnum = PVE::Diskmanage::get_partnum($part);
 		my $devpath = PVE::Diskmanage::get_blockdev($part);
 
+		$udev_trigger_devs->{$devpath} = 1;
+
 		PVE::Diskmanage::wipe_blockdev($part);
 		print "remove partition $part (disk '${devpath}', partnum $partnum)\n";
 		eval { run_command(['/sbin/sgdisk', '-d', $partnum, "${devpath}"]); };
@@ -611,6 +631,8 @@ __PACKAGE__->register_method ({
 
 			    eval { run_command(['/sbin/pvremove', $dev], errfunc => sub {}) };
 			    warn $@ if $@;
+
+			    $udev_trigger_devs->{$dev} = 1;
 			}
 		    }
 		}
@@ -648,6 +670,14 @@ __PACKAGE__->register_method ({
 		    }
 		}
 	    }
+
+	    # FIXME: Remove once we depend on systemd >= v249.
+	    # Work around udev bug https://github.com/systemd/systemd/issues/18525 to ensure the
+	    # udev database is updated.
+	    if ($cleanup) {
+		eval { run_command(['udevadm', 'trigger', keys $udev_trigger_devs->%*]); };
+		warn $@ if $@;
+	    }
 	};
 
 	return $rpcenv->fork_worker('cephdestroyosd', $osdsection,  $authuser, $worker);
-- 
2.30.2






More information about the pve-devel mailing list