[pve-devel] [PATCH pve-manager master v1 2/2] fix #6652: d/postinst: enable autoactivation for Ceph OSD LVs
Max R. Carrara
m.carrara at proxmox.com
Wed Aug 13 10:50:28 CEST 2025
On Wed Aug 13, 2025 at 9:52 AM CEST, Fabian Grünbichler wrote:
> On August 12, 2025 6:46 pm, Max R. Carrara wrote:
> > Introduce a new helper command pve-osd-lvm-enable-autoactivation,
> > which gracefully tries to enable autoactivation for all logical
> > volumes used by Ceph OSDs while also activating any LVs that aren't
> > active yet. Afterwards, the helper attempts to bring all OSDs online.
>
> I think this is probably overkill - this only affects a specific non
> standard setup, the breakage is really obvious, and the fix is easy:
> either run lvchange on all those LVs, or recreate the OSDs after the fix
> for creation is rolled out..
>
> i.e., the fallout from some edge cases not being handled correctly in
> the 200 line helper script here is probably worse than the few setups
> that run into the original issue that we can easily help along
> manually..
I mean, this script doesn't really do much, and the LVs themselves are
fetched via `ceph-volume` ... But then again, you're probably right that
it might just break somebody else's arcane setup somewhere.
As an alternative, I wouldn't mind writing something for the release
notes' known issues section (or some other place). Assuming a standard
setup*, all that the user would have to do is identical to what the
script does, so nothing too complicated.
(*OSDs with WAL + DB on disks / partitions without anything else inbetween)
>
> >
> > Fixes: #6652
> > Signed-off-by: Max R. Carrara <m.carrara at proxmox.com>
> > ---
> > bin/Makefile | 3 +-
> > bin/pve-osd-lvm-enable-autoactivation | 195 ++++++++++++++++++++++++++
> > debian/postinst | 16 +++
> > 3 files changed, 213 insertions(+), 1 deletion(-)
> > create mode 100644 bin/pve-osd-lvm-enable-autoactivation
> >
> > diff --git a/bin/Makefile b/bin/Makefile
> > index 777e6759..0a0df34d 100644
> > --- a/bin/Makefile
> > +++ b/bin/Makefile
> > @@ -32,7 +32,8 @@ HELPERS = \
> > pve-startall-delay \
> > pve-init-ceph-crash \
> > pve-firewall-commit \
> > - pve-sdn-commit
> > + pve-sdn-commit \
> > + pve-osd-lvm-enable-autoactivation
> >
> > MIGRATIONS = \
> > pve-lvm-disable-autoactivation \
> > diff --git a/bin/pve-osd-lvm-enable-autoactivation b/bin/pve-osd-lvm-enable-autoactivation
> > new file mode 100644
> > index 00000000..acdc91e8
> > --- /dev/null
> > +++ b/bin/pve-osd-lvm-enable-autoactivation
> > @@ -0,0 +1,195 @@
> > +#!/usr/bin/perl
> > +
> > +use v5.36;
> > +
> > +use JSON qw(decode_json);
> > +
> > +use PVE::Tools;
> > +
> > +my sub ceph_volume_lvm_osd_info : prototype() () {
> > + my $cmd = [
> > + "/usr/sbin/ceph-volume", "lvm", "list", "--format", "json",
> > + ];
> > +
> > + my $stdout = '';
> > + my $outfunc = sub($line) {
> > + $stdout .= "$line\n";
> > + };
> > +
> > + PVE::Tools::run_command($cmd, timeout => 10, outfunc => $outfunc);
> > + my $osd_info = decode_json($stdout);
> > +
> > + return $osd_info;
> > +}
> > +
> > +my sub lvs_from_osd_info : prototype($) ($osd_info) {
> > + my @lvs_for_osds = ();
> > +
> > + for my $osd (keys $osd_info->%*) {
> > + my $osd_lvs = $osd_info->{$osd};
> > +
> > + for my $osd_lv ($osd_lvs->@*) {
> > + my ($lv_name, $vg_name) = $osd_lv->@{qw(lv_name vg_name)};
> > + push(@lvs_for_osds, "$vg_name/$lv_name");
> > + }
> > + }
> > +
> > + return \@lvs_for_osds;
> > +}
> > +
> > +my sub lvs : prototype() () {
> > + my $cmd = [
> > + "/usr/sbin/lvs",
> > + "--noheadings",
> > + "--separator",
> > + ":",
> > + "--options",
> > + "lv_name,vg_name,autoactivation,active",
> > + ];
> > +
> > + my $all_lvs = {};
> > +
> > + my $outfunc = sub($line) {
> > + $line = PVE::Tools::trim($line);
> > +
> > + my ($lv_name, $vg_name, $autoactivation, $active) = split(':', $line, -1);
> > +
> > + return undef if ($lv_name eq '' || $vg_name eq '');
> > +
> > + $all_lvs->{"$vg_name/$lv_name"} = {
> > + autoactivation => $autoactivation,
> > + active => $active,
> > + };
> > + };
> > +
> > + PVE::Tools::run_command(
> > + $cmd,
> > + timeout => 10,
> > + outfunc => $outfunc,
> > + );
> > +
> > + return $all_lvs;
> > +}
> > +
> > +my sub main : prototype() () {
> > + my $osd_info = ceph_volume_lvm_osd_info();
> > + my $all_lvs = lvs();
> > +
> > + my @osd_lvs_no_autoactivation = ();
> > + my @osd_lvs_inactive = ();
> > +
> > + for my $osd (keys $osd_info->%*) {
> > + for my $osd_lv ($osd_info->{$osd}->@*) {
> > + my ($lv_name, $vg_name) = $osd_lv->@{qw(lv_name vg_name)};
> > +
> > + my $osd_lv = "$vg_name/$lv_name";
> > +
> > + push(@osd_lvs_no_autoactivation, $osd_lv) if !$all_lvs->{$osd_lv}->{autoactivation};
> > + push(@osd_lvs_inactive, $osd_lv) if !$all_lvs->{$osd_lv}->{active};
> > + }
> > + }
> > +
> > + my $has_set_autoactivation_err = 0;
> > +
> > + # Logical volumes are formatted as "vg_name/lv_name", which is necessary for lvchange
> > + for my $lv (@osd_lvs_no_autoactivation) {
> > + print("Enabling autoactivation for OSD logical volume '$lv' ...\n");
> > +
> > + eval {
> > + my $cmd = [
> > + '/usr/sbin/lvchange', '--setautoactivation', 'y', $lv,
> > + ];
> > +
> > + PVE::Tools::run_command(
> > + $cmd,
> > + quiet => 1,
> > + timeout => 10,
> > + );
> > + };
> > + if (my $err = $@) {
> > + $has_set_autoactivation_err = 1;
> > +
> > + warn("Error: Failed to enable autoactivation for OSD LV '$lv'\n");
> > + warn("$@\n");
> > +
> > + next;
> > + }
> > +
> > + }
> > +
> > + my $has_activation_err = 0;
> > +
> > + # Activate any inactive OSD LVs so that ceph-volume can later bring up any failed OSDs
> > + for my $lv (@osd_lvs_inactive) {
> > + print("Activating OSD logical volume '$lv' ...\n");
> > +
> > + eval {
> > + my $cmd = [
> > + '/usr/sbin/lvchange', '--activate', 'y', $lv,
> > + ];
> > +
> > + PVE::Tools::run_command(
> > + $cmd,
> > + quiet => 1,
> > + timeout => 10,
> > + );
> > + };
> > + if (my $err = $@) {
> > + $has_activation_err = 1;
> > +
> > + warn("Error: Failed to activate OSD LV '$lv'\n");
> > + warn("$@\n");
> > +
> > + next;
> > + }
> > + }
> > +
> > + # ceph-volume requires all LVs used by OSDs to be active,
> > + # so exit in case there are any we couldn't activate
> > + if ($has_set_autoactivation_err || $has_activation_err) {
> > + if ($has_set_autoactivation_err) {
> > + warn("Couldn't enable autoactivation for all OSD LVs.\n");
> > + }
> > +
> > + if ($has_activation_err) {
> > + warn("Couldn't activate all OSD LVs.\n");
> > + }
> > +
> > + exit 1;
> > + }
> > +
> > + print("Activating OSDs ...\n");
> > + eval {
> > + my $cmd = [
> > + "/usr/sbin/ceph-volume", "lvm", "activate", "--all",
> > + ];
> > +
> > + # ceph-volume prints everything to stderr for whatever reason and prefixes
> > + # what actually goes to stderr with " stderr:", so separate the output here.
> > + # Lines starting with "Running command:" are removed because they're overly
> > + # verbose.
> > + my $logfunc = sub ($line) {
> > + return if $line =~ m/^Running command:/;
> > +
> > + if ($line =~ s/^\s*stderr:\s*//) {
> > + print STDERR "$line\n";
> > + } else {
> > + print STDOUT "$line\n";
> > + }
> > + };
> > +
> > + PVE::Tools::run_command(
> > + $cmd,
> > + logfunc => $logfunc,
> > + timeout => 30,
> > + );
> > + };
> > + if (my $err = $@) {
> > + warn("Error while activating all Ceph LVM volumes: $@\n");
> > + exit 1;
> > + }
> > +
> > + return undef;
> > +}
> > +
> > +main();
> > diff --git a/debian/postinst b/debian/postinst
> > index b6e07fd9..f550e7bb 100755
> > --- a/debian/postinst
> > +++ b/debian/postinst
> > @@ -133,6 +133,18 @@ migrate_apt_auth_conf() {
> > fi
> > }
> >
> > +ceph_osd_lvm_enable_autoactivation() {
> > + if ! test -e /usr/sbin/ceph-volume; then
> > + return
> > + fi
> > +
> > + if ! /usr/share/pve-manager/helpers/pve-osd-lvm-enable-autoactivation; then
> > + printf "\nEnabling autoactivation for logical volumes used by Ceph OSDs failed.";
> > + printf " Check the output above for errors and try to enable autoactivation for OSD LVs";
> > + printf " manually by running '/usr/share/pve-manager/helpers/pve-osd-lvm-enable-autoactivation'";
> > + fi
> > +}
> > +
> > # Copied from dh_installtmpfiles/13.24.2
> > if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
> > if [ -x "$(command -v systemd-tmpfiles)" ]; then
> > @@ -246,6 +258,10 @@ case "$1" in
> > fi
> > fi
> >
> > + if test -n "$2" && dpkg --compare-versions "$2" 'lt' '9.0.5'; then
> > + ceph_osd_lvm_enable_autoactivation
> > + fi
> > +
> > ;;
> >
> > abort-upgrade|abort-remove|abort-deconfigure)
> > --
> > 2.47.2
> >
> >
> >
> > _______________________________________________
> > pve-devel mailing list
> > pve-devel at lists.proxmox.com
> > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> >
> >
> >
>
>
> _______________________________________________
> pve-devel mailing list
> pve-devel at lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
More information about the pve-devel
mailing list