From: Wolfgang Bumiller <w.bumil...@proxmox.com>

Though I wish perl had an fdopendir equivalent...

Signed-off-by: Wolfgang Bumiller <w.bumil...@proxmox.com>
---
 src/lxc-pve-prestart-hook | 49 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/src/lxc-pve-prestart-hook b/src/lxc-pve-prestart-hook
index 1d62f3b..be0063d 100755
--- a/src/lxc-pve-prestart-hook
+++ b/src/lxc-pve-prestart-hook
@@ -34,6 +34,8 @@ PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub {
        PVE::LXC::Config->check_lock($conf);
     }
 
+    cleanup_cgroups($vmid);
+
     my $storage_cfg = PVE::Storage::config();
 
     my $vollist = PVE::LXC::Config->get_vm_volumes($conf);
@@ -140,3 +142,50 @@ PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub {
        PVE::Tools::file_set_contents($devlist_file, $devlist);
     }
 });
+
+# Leftover cgroups prevent lxc from starting without any useful information
+# showing up in the journal, it is also often unable to properly clean them up
+# at shutdown, so we do this here.
+sub cleanup_cgroups($) {
+    my ($vmid) = @_;
+
+    if (PVE::LXC::CGroup::cgroup_mode() == 2) {
+       rmdir_recursive("/sys/fs/cgroup/lxc/$vmid");
+       rmdir_recursive("/sys/fs/cgroup/lxc.monitor/$vmid");
+    } else {
+       my ($v1, $v2) = PVE::LXC::get_cgroup_subsystems();
+
+       my @controllers_cgv1 = keys %$v1;
+       foreach my $controller (@controllers_cgv1) {
+           $controller =~ s/^name=//; # `name=systemd` is mounted just as 
`systemd`
+           my $cgpath = "/sys/fs/cgroup/$controller/lxc/$vmid";
+           rmdir_recursive($cgpath);
+       }
+
+       if ($v2) {
+           rmdir_recursive("/sys/fs/cgroup/unified/lxc/$vmid");
+           rmdir_recursive("/sys/fs/cgroup/unified/lxc.monitor/$vmid");
+       }
+    }
+}
+
+# FIXME: This is an ugly version without openat() because perl has no 
equivalent
+# of fdopendir() so we cannot readdir from an openat() opened handle.
+sub rmdir_recursive {
+    my ($path) = @_;
+
+    my $dh;
+    if (!opendir($dh, $path)) {
+       return if $!{ENOENT};
+       die "failed to open directory '$path': $!\n";
+    }
+
+    while (defined(my $entry = readdir($dh))) {
+       next if $entry eq '.' || $entry eq '..';
+       my $next = "$path/$entry";
+       next if ! -d $next;
+       rmdir_recursive($next);
+    }
+
+    rmdir($path) or die "failed to remove directory '$path': $!\n";
+}
-- 
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