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.bumil...@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


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to