[pve-devel] [PATCH container 2/3] add freeze/thaw compatibilty implementation

Wolfgang Bumiller w.bumiller at proxmox.com
Thu May 14 15:22:30 CEST 2020


lxc-freeze from lxc 4 fails with lxc 3 containers, and our
lxc 3 has an api extension to get the namespaced/inner
cgroup path

Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
 src/PVE/LXC.pm | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index e079208..ed309b6 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -32,6 +32,7 @@ use PVE::LXC::Config;
 use PVE::GuestHelpers qw(safe_string_ne safe_num_ne safe_boolean_ne);
 use PVE::LXC::Tools;
 use PVE::LXC::CGroup;
+use PVE::LXC::Command;
 
 use Time::HiRes qw (gettimeofday);
 my $have_sdn;
@@ -2376,4 +2377,54 @@ sub get_lxc_version() {
     return $version->@*;
 }
 
+# Freeze a container the way `lxc-freeze` would do it, while supporting containers started with an
+# older lxc version.
+sub freeze_thaw($$) {
+    my ($vmid, $freeze) = @_;
+
+    if (PVE::LXC::CGroup::cgroup_mode() == 2) {
+	return PVE::LXC::Command::freeze($vmid, -1);
+    }
+
+    my ($controller_path, $ver) = PVE::LXC::CGroup::find_cgroup_controller('freezer');
+
+    # lxc's logic is to do it by itself in a cgv1/hybrid environment
+    my $path = eval { PVE::LXC::Command::get_cgroup_path($vmid, 'freezer', 1) };
+
+    # If the container was started with an older lxc the above command failed as it does not have
+    # an LXC_CMD_GET_LIMITING_CGROUP command yet. Instead, we had this as an additional parameter
+    # in the subsystem name.
+    if (!defined($path)) {
+	(undef, $path) = PVE::LXC::Command::simple_command(
+	    $vmid,
+	    PVE::LXC::Command::LXC_CMD_GET_CGROUP,
+	    pack('Z*C', 'freezer', 1),
+	);
+    }
+
+    die "failed to get freezer cgroup path\n"
+	if !defined $path;
+
+    # Note that we get a zero-terminated string from lxc, so chop off that byte.
+    $path = unpack('Z*', $path);
+
+    # untaint:
+    if ($path =~ /\.\./) {
+	die "lxc returned suspicious path: '$path'\n";
+    }
+    ($path) = ($path =~ /^(.*)$/s);
+
+    $path = "$controller_path/$path";
+
+    if ($ver == 2) {
+	my $data = $freeze ? '1' : '0';
+	PVE::ProcFSTools::write_proc_entry("$path/cgroup.freeze", $data);
+    } elsif ($ver == 1) {
+	my $data = $freeze ? 'FROZEN' : 'THAWED';
+	PVE::ProcFSTools::write_proc_entry("$path/freezer.state", $data);
+    } else {
+	die "bad cgroup version: $ver\n";
+    }
+}
+
 1;
-- 
2.20.1





More information about the pve-devel mailing list