public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Ellmenreich <t.ellmenreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Cc: Thomas Ellmenreich <t.ellmenreich@proxmox.com>
Subject: [PATCH pve-container 1/2] mountpoint: allow changing mountpoint properties at runtime
Date: Wed,  4 Nov 2026 10:29:38 +0100	[thread overview]
Message-ID: <20261104092939.123574-2-t.ellmenreich@proxmox.com> (raw)
In-Reply-To: <20261104092939.123574-1-t.ellmenreich@proxmox.com>

Previously, setting the backup or replicate flags of a running
container would first place them in a pending state before applying
them at a later time. As the flags do not affect the actual mount
point, they are now applied directly.

However, in situations where multiple settings are changed at once
and 'backup' or 'replicate' happen to be among them, the flags are
not applied directly but instead marked as pending alongside the
other changes.

Suggested-by: Filip Schauer <f.schauer@proxmox.com>
Signed-off-by: Thomas Ellmenreich <t.ellmenreich@proxmox.com>
---
 src/PVE/LXC/Config.pm    | 37 ++++++++++++++++++---
 src/test/Makefile        |  6 +++-
 src/test/config_tests.pl | 72 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+), 6 deletions(-)
 create mode 100755 src/test/config_tests.pl

diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 9823d00..60318b4 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -1738,10 +1738,6 @@ sub vmconfig_hotplug_pending {
                     $hotplug_memory->($conf->{pending}->{memory}, $conf->{pending}->{swap});
                 }
             } elsif ($opt =~ m/^mp(\d+)$/) {
-                if (exists($conf->{$opt})) {
-                    die "skip\n"; # don't try to hotplug over existing mp
-                }
-
                 $class->apply_pending_mountpoint($vmid, $conf, $opt, $storecfg, 1);
                 # apply_pending_mountpoint modifies the value if it creates a new disk
                 $value = $conf->{pending}->{$opt};
@@ -1876,11 +1872,43 @@ my $rescan_volume = sub {
     warn "Could not rescan volume size - $@\n" if $@;
 };
 
+my @FAST_PLUG_SAFE_KEYS = qw(backup replicate);
+
+# Checks whether the changed properties can be applied at runtime. It only
+# returns true if all changes can be applied in this way. If even one
+# property cannot be applied, returns false to ensure changes are applied
+# as a unit.
+sub __mountpoint_config_fast_plug_safe {
+    my ($class, $key, $new, $old) = @_;
+
+    my %new = $new->%*;
+    my %old = $old->%*;
+    delete @new{@FAST_PLUG_SAFE_KEYS};
+    delete @old{@FAST_PLUG_SAFE_KEYS};
+
+    my $new_str = $class->print_volume($key, \%new);
+    my $old_str = $class->print_volume($key, \%old);
+
+    return $new_str eq $old_str;
+}
+
 sub apply_pending_mountpoint {
     my ($class, $vmid, $conf, $opt, $storecfg, $running) = @_;
 
     my $mp = $class->parse_volume($opt, $conf->{pending}->{$opt});
     my $old = $conf->{$opt};
+
+    if (defined($old) && $running) {
+        if ($class->__mountpoint_config_fast_plug_safe(
+            $opt,
+            $mp,
+            $class->parse_volume($opt, $old),
+        )) {
+            return;
+        }
+        die "skip\n"; # don't try to hotplug over existing mp
+    }
+
     if ($mp->{type} eq 'volume' && $mp->{volume} =~ $PVE::LXC::NEW_DISK_RE) {
         my $original_value = $conf->{pending}->{$opt};
         my $vollist = PVE::LXC::create_disks(
@@ -1901,7 +1929,6 @@ sub apply_pending_mountpoint {
             }
         }
     } else {
-        die "skip\n" if $running && defined($old); # TODO: "changing" mount points?
         $rescan_volume->($storecfg, $mp) if $mp->{type} eq 'volume';
         if ($running) {
             PVE::LXC::mountpoint_hotplug($vmid, $conf, $opt, $mp, $storecfg);
diff --git a/src/test/Makefile b/src/test/Makefile
index 91ae6ff..a3728b5 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -2,7 +2,7 @@ RUN_USERNS := lxc-usernsexec -m "u:0:`id -u`:1" -m "g:0:`id -g`:1" --
 
 all: test
 
-test: test_setup test_snapshot test_bindmount test_idmap
+test: test_setup test_snapshot test_bindmount test_idmap test_config
 
 test_setup: run_setup_tests.pl
 	if test -e /run/lock/sbuild; then \
@@ -24,5 +24,9 @@ test_bindmount: bindmount_test.pl
 test_idmap: run_idmap_tests.pl
 	./run_idmap_tests.pl
 
+test_config: config_tests.pl
+	./config_tests.pl
+
 clean:
 	rm -rf tmprootfs
+
diff --git a/src/test/config_tests.pl b/src/test/config_tests.pl
new file mode 100755
index 0000000..43935a9
--- /dev/null
+++ b/src/test/config_tests.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib qw(..);
+
+use Test::More;
+
+use PVE::LXC::Config;
+
+my sub create_conf {
+    my ($common, $new, $old) = @_;
+
+    my $new_str = defined($new) ? $common . ',' . $new : $common;
+    my $old_str = defined($old) ? $common . ',' . $old : $common;
+    return (
+        PVE::LXC::Config->parse_volume('mp0', $new_str),
+        PVE::LXC::Config->parse_volume('mp0', $old_str),
+    );
+}
+
+subtest 'same config can be applied' => sub {
+    my ($new, $old) = create_conf("local:100/vm-100-disk-1.raw,mp=/mnt,backup=1");
+    my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("mp0", $new, $old);
+
+    ok($result, "can be hotplugged");
+};
+
+subtest 'config with only backup difference can be applied' => sub {
+    my ($new, $old) =
+        create_conf("local:100/vm-100-disk-1.raw,mp=/mnt", "backup=1", "backup=0");
+    my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("mp0", $new, $old);
+
+    ok($result, "can be hotplugged");
+};
+
+subtest 'fast plug option also ignored if previously not present' => sub {
+    my ($new, $old) = create_conf("local:100/vm-100-disk-1.raw,mp=/mnt", "replicate=1", undef);
+    my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("mp0", $new, $old);
+
+    ok($result, "can be hotplugged");
+};
+
+subtest 'difference in mountpoint cannot be applied' => sub {
+    my ($new, $old) =
+        create_conf("local:100/vm-100-disk-1.raw,replicate=1", "mp=/mnt/one", "mp=/mnt/two");
+    my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("mp0", $new, $old);
+
+    ok(!$result, "cannot be hotplugged");
+};
+
+subtest 'changing fast pluggable and non fast pluggable cannot be applied' => sub {
+    my ($new, $old) =
+        create_conf("local:100/vm-100-disk-1.raw", "mp=/mnt/one", "mp=/mnt/two,replicate=1");
+    my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("mp0", $new, $old);
+
+    ok(!$result, "cannot be hotplugged");
+};
+
+subtest 'idmap array does not throw off comparison' => sub {
+    my ($new, $old) = create_conf(
+        "local:100/vm-100-disk-1.raw,mp=/mnt,idmap=u:0:100000:65536;g:0:100000:65536",
+        "backup=1",
+        undef,
+    );
+    my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("mp0", $new, $old);
+
+    ok($result, "can be hotplugged");
+};
+
+done_testing();
-- 
2.47.3





  reply	other threads:[~2026-11-04  9:30 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04  9:29 [PATCH container 0/2] mountpoint: allow certain options to be hotplugged Thomas Ellmenreich
2026-11-04  9:29 ` Thomas Ellmenreich [this message]
2026-11-04  9:29 ` [PATCH pve-container 2/2] mountpoint: allow changing rootfs properties at runtime Thomas Ellmenreich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261104092939.123574-2-t.ellmenreich@proxmox.com \
    --to=t.ellmenreich@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal