Some container OS (e.g. CentOS 7, Ubuntu 16.04) are booted with systemd, in a version which is not able to run with a pure cgroupv2 (a.k.a unified hierarchy) environment.
Detect those in the lxc-pve-prestart-hook, because there we already have all mount-points set up. This approach only leaves syslog/journal as place for notifying the user since starting a container eventually runs `systemctl start pve-container@VMID.service`, where we lose the prints to stdout and stderr. The alternative of shortly mounting all container mounts just to obtain the systemd-version, before starting the container seems prohibitively expensive. The heuristic of /sbin/init needing to be a link to something ending in systemd is taken from the systemd documentation[0] and was verified on a few of our container-templates. [0] https://www.freedesktop.org/software/systemd/man/systemd.html Signed-off-by: Stoiko Ivanov <s.iva...@proxmox.com> --- unchanged from v1 src/PVE/LXC/Setup.pm | 8 ++++++++ src/PVE/LXC/Setup/Base.pm | 36 ++++++++++++++++++++++++++++++++++++ src/lxc-pve-prestart-hook | 7 +++++++ 3 files changed, 51 insertions(+) diff --git a/src/PVE/LXC/Setup.pm b/src/PVE/LXC/Setup.pm index cf72b03..9abdc85 100644 --- a/src/PVE/LXC/Setup.pm +++ b/src/PVE/LXC/Setup.pm @@ -421,4 +421,12 @@ sub get_ct_os_release { return &$parse_os_release($data); } +sub unified_cgroupv2_support { + my ($self) = @_; + + $self->protected_call(sub { + $self->{plugin}->unified_cgroupv2_support(); + }); +} + 1; diff --git a/src/PVE/LXC/Setup/Base.pm b/src/PVE/LXC/Setup/Base.pm index 663df73..a5b77d3 100644 --- a/src/PVE/LXC/Setup/Base.pm +++ b/src/PVE/LXC/Setup/Base.pm @@ -503,6 +503,42 @@ sub clear_machine_id { } } +# tries to guess the systemd version based on the existence of +# (/usr)?/lib/systemd/libsystemd-shared<version>.so. It was introduced in v231. +sub get_systemd_version { + my ($self) = @_; + + my $sd_lib_dir = $self->ct_is_directory("/lib/systemd") ? + "/lib/systemd" : "/usr/lib/systemd"; + my $libsd = PVE::Tools::dir_glob_regex($sd_lib_dir, "libsystemd-shared-.+\.so"); + if (defined($libsd) && $libsd =~ /libsystemd-shared-(\d+)\.so/) { + return $1; + } + + return undef; +} + +sub unified_cgroupv2_support { + my ($self) = @_; + + # https://www.freedesktop.org/software/systemd/man/systemd.html + # systemd is installed as symlink to /sbin/init + my $systemd = $self->ct_readlink('/sbin/init'); + + # assume non-systemd init will run with unified cgroupv2 + if (!defined($systemd) || $systemd !~ m@/systemd$@) { + return 1; + } + + # systemd version 232 (e.g. debian stretch) supports the unified hierarchy + my $sdver = $self->get_systemd_version(); + if (!defined($sdver) || $sdver < 232) { + return 0; + } + + return 1 +} + sub pre_start_hook { my ($self, $conf) = @_; diff --git a/src/lxc-pve-prestart-hook b/src/lxc-pve-prestart-hook index 8d876a8..fac587e 100755 --- a/src/lxc-pve-prestart-hook +++ b/src/lxc-pve-prestart-hook @@ -15,6 +15,7 @@ use PVE::LXC::Config; use PVE::LXC::Setup; use PVE::LXC::Tools; use PVE::LXC; +use PVE::SafeSyslog; use PVE::Storage; use PVE::Syscall qw(:fsmount); use PVE::Tools qw(AT_FDCWD O_PATH); @@ -126,6 +127,12 @@ PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub { my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir); $lxc_setup->pre_start_hook(); + if (PVE::CGroup::cgroup_mode() == 2) { + if(!$lxc_setup->unified_cgroupv2_support()) { + syslog('err', "CT $vmid does not support running in a pure cgroupv2 environment\n"); + } + } + if (@$devices) { my $devlist = ''; foreach my $dev (@$devices) { -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel