* [PATCH container 0/2] mountpoint: allow certain options to be hotplugged
@ 2026-11-04 9:29 Thomas Ellmenreich
2026-11-04 9:29 ` [PATCH pve-container 1/2] mountpoint: allow changing mountpoint properties at runtime Thomas Ellmenreich
2026-11-04 9:29 ` [PATCH pve-container 2/2] mountpoint: allow changing rootfs " Thomas Ellmenreich
0 siblings, 2 replies; 3+ messages in thread
From: Thomas Ellmenreich @ 2026-11-04 9:29 UTC (permalink / raw)
To: pve-devel; +Cc: Thomas Ellmenreich
Ticking the backup or replicate flag on a container mountpoint and the
replicate flag on the containers rootfs can be applied directly even if
the container is running. This should be possible because it does not
affect the actual mountpoint/disk.
This functionality is already present for VMs, but not for containers.
With this implementation a list of "fast pluggable" options is created,
and any change that only affects any of these options will be fast plugged.
Should a "fast pluggable" option change be accompanied by a
non-"fast pluggable" option change, then the whole change will be set as
pending so that it may be applied as a single unit.
Testing
-------
- Only changing the `backup`/`replicate` setting does precisely that,
skipping the pending state.
- When combining `backup`/`replicate` with changing a different setting,
they are both marked as pending.
Questions
---------
- I have rewritten the check for the fast pluggable option to use
`print_volume` since that makes it a lot easier. `print_volume` calls
`print_property_string` which has a 'skip' parameter that can only
be used if I also change `print_ct_mountpoint`. For this reason I
decided to not make the change and delete the keys instead. That said
using this skip parameter is an option.
- The tests for the __mountpoint_config_fast_plug_safe can now be found
in the src/test/ folder. I'm not sure if that is the correct spot or
if I should have created a src/PVE/LXC/test subdirectory and placed the
tests in there.
- I have added the option to also fast plug the rootfs options, as replicate
applies there as well, although I am somewhat unsure if that is a good
idea. Because of that I have placed it in a separate commit so that it may
be skipped or reverted in the future.
Changelog
---------
RFC -> v1 (thanks @Wolfgang, @Filip)
* Instead of comparing the configs key by key, I now delete the
fast pluggable options, convert the config to a string with
print_volume and then compare those strings.
* Added replicate to the fast plug options.
* Moved the list of fast pluggable keys out of the
__mountpoint_config_fast_plug_safe subroutine.
* The __mountpoint_config_fast_plug_safe helper, it not private
anymore so that it may be called in tests, but it has gained
the __ prefix, indicating that it should not be used.
* Added tests for the __mountpoint_config_fast_plug_safe subroutine.
* Removed an early return that has become unreachable due to the changes.
* Added the option to also fast plug the rootfs disk.
pve-container:
Thomas Ellmenreich (2):
mountpoint: allow changing mountpoint properties at runtime
mountpoint: allow changing rootfs properties at runtime
src/PVE/LXC/Config.pm | 39 ++++++++++--
src/test/Makefile | 6 +-
src/test/config_tests.pl | 131 +++++++++++++++++++++++++++++++++++++++
3 files changed, 169 insertions(+), 7 deletions(-)
create mode 100755 src/test/config_tests.pl
Summary over all repositories:
3 files changed, 169 insertions(+), 7 deletions(-)
--
Generated by murpp 0.12.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH pve-container 1/2] mountpoint: allow changing mountpoint properties at runtime
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
2026-11-04 9:29 ` [PATCH pve-container 2/2] mountpoint: allow changing rootfs " Thomas Ellmenreich
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Ellmenreich @ 2026-11-04 9:29 UTC (permalink / raw)
To: pve-devel; +Cc: Thomas Ellmenreich
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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH pve-container 2/2] mountpoint: allow changing rootfs properties at runtime
2026-11-04 9:29 [PATCH container 0/2] mountpoint: allow certain options to be hotplugged Thomas Ellmenreich
2026-11-04 9:29 ` [PATCH pve-container 1/2] mountpoint: allow changing mountpoint properties at runtime Thomas Ellmenreich
@ 2026-11-04 9:29 ` Thomas Ellmenreich
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Ellmenreich @ 2026-11-04 9:29 UTC (permalink / raw)
To: pve-devel; +Cc: Thomas Ellmenreich
Just as has been implemented for mountpoints, properties like replicate
can now be applied at runtime for rootfs disks. If the change is
performed with any other non hot pluggable options, the whole changeset
is added as pending instead of mixing the two states.
Signed-off-by: Thomas Ellmenreich <t.ellmenreich@proxmox.com>
---
src/PVE/LXC/Config.pm | 2 +-
src/test/config_tests.pl | 65 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 60318b4..5c35750 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -1737,7 +1737,7 @@ sub vmconfig_hotplug_pending {
if (!$hotplug_memory_done) { # don't call twice if both opts are passed
$hotplug_memory->($conf->{pending}->{memory}, $conf->{pending}->{swap});
}
- } elsif ($opt =~ m/^mp(\d+)$/) {
+ } elsif ($opt =~ m/^mp(\d+)$/ || $opt eq 'rootfs') {
$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};
diff --git a/src/test/config_tests.pl b/src/test/config_tests.pl
index 43935a9..5c5e868 100755
--- a/src/test/config_tests.pl
+++ b/src/test/config_tests.pl
@@ -9,14 +9,19 @@ use Test::More;
use PVE::LXC::Config;
+# Creates new and old configurations based on the common core and just
+# the changes. The fourth parameter can change the kind of mountpoint it
+# is, instead of always using mp0.
my sub create_conf {
- my ($common, $new, $old) = @_;
+ my ($common, $new, $old, $mountpoint_name) = @_;
+
+ $mountpoint_name //= 'mp0';
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),
+ PVE::LXC::Config->parse_volume($mountpoint_name, $new_str),
+ PVE::LXC::Config->parse_volume($mountpoint_name, $old_str),
);
}
@@ -27,6 +32,14 @@ subtest 'same config can be applied' => sub {
ok($result, "can be hotplugged");
};
+subtest 'rootfs same config can be applied' => sub {
+ my ($new, $old) =
+ create_conf("local:100/vm-100-disk-1.raw,replicate=1", undef, undef, "rootfs");
+ my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("rootfs", $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");
@@ -35,6 +48,14 @@ subtest 'config with only backup difference can be applied' => sub {
ok($result, "can be hotplugged");
};
+subtest 'rootfs config with only backup difference can be applied' => sub {
+ my ($new, $old) =
+ create_conf("local:100/vm-100-disk-1.raw", "replicate=1", "replicate=0", "rootfs");
+ my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("rootfs", $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);
@@ -42,6 +63,14 @@ subtest 'fast plug option also ignored if previously not present' => sub {
ok($result, "can be hotplugged");
};
+subtest 'rootfs fast plug option also ignored if previously not present' => sub {
+ my ($new, $old) =
+ create_conf("local:100/vm-100-disk-1.raw", "replicate=1", undef, "rootfs");
+ my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("rootfs", $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");
@@ -50,6 +79,15 @@ subtest 'difference in mountpoint cannot be applied' => sub {
ok(!$result, "cannot be hotplugged");
};
+subtest 'rootfs difference in acl cannot be applied' => sub {
+ my ($new, $old) = create_conf(
+ "local:100/vm-100-disk-1.raw,replicate=1", "acl=0", "acl=1", "rootfs",
+ );
+ my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("rootfs", $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");
@@ -58,6 +96,15 @@ subtest 'changing fast pluggable and non fast pluggable cannot be applied' => su
ok(!$result, "cannot be hotplugged");
};
+subtest 'rootfs changing fast pluggable and non fast pluggable cannot be applied' => sub {
+ my ($new, $old) = create_conf(
+ "local:100/vm-100-disk-1.raw", "acl=0", "acl=1,replicate=1", "rootfs",
+ );
+ my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("rootfs", $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",
@@ -69,4 +116,16 @@ subtest 'idmap array does not throw off comparison' => sub {
ok($result, "can be hotplugged");
};
+subtest 'rootfs idmap array does not throw off comparison' => sub {
+ my ($new, $old) = create_conf(
+ "local:100/vm-100-disk-1.raw,idmap=u:0:100000:65536;g:0:100000:65536",
+ "replicate=1",
+ undef,
+ "rootfs",
+ );
+ my $result = PVE::LXC::Config->__mountpoint_config_fast_plug_safe("rootfs", $new, $old);
+
+ ok($result, "can be hotplugged");
+};
+
done_testing();
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-04 9:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 9:29 [PATCH container 0/2] mountpoint: allow certain options to be hotplugged Thomas Ellmenreich
2026-11-04 9:29 ` [PATCH pve-container 1/2] mountpoint: allow changing mountpoint properties at runtime Thomas Ellmenreich
2026-11-04 9:29 ` [PATCH pve-container 2/2] mountpoint: allow changing rootfs " Thomas Ellmenreich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.