[pve-devel] [PATCH container 0/1] deal with disabled cgroup subsystems

Wolfgang Bumiller w.bumiller at proxmox.com
Thu Jun 21 10:07:40 CEST 2018


The patch causes a lot of reindentation so here's the `-w` version of
it for easier reviewing.

Note that I use `-d /sys/fs/cgroup/<name>` in cases where we access the
files (since that's where we expect them to be mounted), and a new
get_cgroup_subsystems() during vm_start() to guard the addition of
lxc.cgroup.* entries to the lxc guest config: lxc uses
/proc/self/mountinfo to find the cgroup hierarchy so in theory they'd
also be dealing with cgroups mounted elsewhere...

commit 350dec1b9b834d28c7888c33a82d1367bad84e91 (HEAD -> refs/heads/master)
Author: Wolfgang Bumiller <w.bumiller at proxmox.com>
Date:   Thu Jun 21 09:36:29 2018 +0200

    deal with disabled cgroup subsystems
    
    When a user disables a cgroup subsystem via eg. a kernel
    command line we shouldn't try to generate lxc.cgroup.*
    entries for it.
    
    Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>

diff --git a/src/PVE/CLI/pct.pm b/src/PVE/CLI/pct.pm
index 897d595..9eb4ac0 100755
--- a/src/PVE/CLI/pct.pm
+++ b/src/PVE/CLI/pct.pm
@@ -669,6 +669,12 @@ __PACKAGE__->register_method ({
     code => sub {
 	my ($param) = @_;
 
+	my $cgv1 = PVE::LXC::get_cgroup_subsystems();
+	if (!$cgv1->{cpuset}) {
+	    print "cpuset cgroup not available\n";
+	    return undef;
+	}
+
 	my $ctlist = PVE::LXC::config_list();
 
 	my $len = 0;
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 4be1579..bc03792 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -195,12 +195,18 @@ sub vmstatus {
 
 	my $unpriv = $unprivileged->{$vmid};
 
+	if (-d '/sys/fs/cgroup/memory') {
 	    my $memory_stat = read_cgroup_list('memory', $vmid, $unpriv, 'memory.stat');
 	    my $mem_usage_in_bytes = read_cgroup_value('memory', $vmid, $unpriv, 'memory.usage_in_bytes');
 
 	    $d->{mem} = $mem_usage_in_bytes - $memory_stat->{total_cache};
 	    $d->{swap} = read_cgroup_value('memory', $vmid, $unpriv, 'memory.memsw.usage_in_bytes') - $mem_usage_in_bytes;
+	} else {
+	    $d->{mem} = 0;
+	    $d->{swap} = 0;
+	}
 
+	if (-d '/sys/fs/cgroup/blkio') {
 	    my $blkio_bytes = read_cgroup_value('blkio', $vmid, $unpriv, 'blkio.throttle.io_service_bytes', 1);
 	    my @bytes = split(/\n/, $blkio_bytes);
 	    foreach my $byte (@bytes) {
@@ -209,7 +215,12 @@ sub vmstatus {
 		    $d->{diskwrite} += $2 if $key eq 'Write';
 		}
 	    }
+	} else {
+	    $d->{diskread} = 0;
+	    $d->{diskwrite} = 0;
+	}
 
+	if (-d '/sys/fs/cgroup/cpuacct') {
 	    my $pstat = $parse_cpuacct_stat->($vmid, $unpriv);
 
 	    my $used = $pstat->{utime} + $pstat->{stime};
@@ -238,6 +249,9 @@ sub vmstatus {
 	    } else {
 		$d->{cpu} = $old->{cpu};
 	    }
+	} else {
+	    $d->{cpu} = 0;
+	}
     }
 
     my $netdev = PVE::ProcFSTools::read_proc_net_dev();
@@ -339,6 +353,20 @@ sub parse_ipv4_cidr {
     die "unable to parse ipv4 address/mask\n";
 }
 
+sub get_cgroup_subsystems {
+	my $v1 = {};
+	my $v2 = 0;
+	my $data = PVE::Tools::file_get_contents('/proc/self/cgroup');
+	while ($data =~ /^\d+:([^:\n]*):.*$/gm) {
+		my $type = $1;
+		if (length($type)) {
+			$v1->{$_} = 1 foreach split(/,/, $type);
+		} else {
+			$v2 = 1;
+		}
+	}
+	return wantarray ? ($v1, $v2) : $v1;
+}
 
 sub update_lxc_config {
     my ($vmid, $conf) = @_;
@@ -380,6 +408,8 @@ sub update_lxc_config {
     # files while the container is running!
     $raw .= "lxc.monitor.unshare = 1\n";
 
+    my $cgv1 = get_cgroup_subsystems();
+
     # Should we read them from /etc/subuid?
     if ($unprivileged && !$custom_idmap) {
 	$raw .= "lxc.idmap = u 0 100000 65536\n";
@@ -388,7 +418,7 @@ sub update_lxc_config {
 
     if (!PVE::LXC::Config->has_dev_console($conf)) {
 	$raw .= "lxc.console.path = none\n";
-	$raw .= "lxc.cgroup.devices.deny = c 5:1 rwm\n";
+	$raw .= "lxc.cgroup.devices.deny = c 5:1 rwm\n" if $cgv1->{devices};
     }
 
     my $ttycount = PVE::LXC::Config->get_tty_count($conf);
@@ -400,6 +430,7 @@ sub update_lxc_config {
     my $utsname = $conf->{hostname} || "CT$vmid";
     $raw .= "lxc.uts.name = $utsname\n";
 
+    if ($cgv1->{memory}) {
 	my $memory = $conf->{memory} || 512;
 	my $swap = $conf->{swap} // 0;
 
@@ -408,7 +439,9 @@ sub update_lxc_config {
 
 	my $lxcswap = int(($memory + $swap)*1024*1024);
 	$raw .= "lxc.cgroup.memory.memsw.limit_in_bytes = $lxcswap\n";
+    }
 
+    if ($cgv1->{cpu}) {
 	if (my $cpulimit = $conf->{cpulimit}) {
 	    $raw .= "lxc.cgroup.cpu.cfs_period_us = 100000\n";
 	    my $value = int(100000*$cpulimit);
@@ -417,6 +450,7 @@ sub update_lxc_config {
 
 	my $shares = $conf->{cpuunits} || 1024;
 	$raw .= "lxc.cgroup.cpu.shares = $shares\n";
+    }
 
     die "missing 'rootfs' configuration\n"
 	if !defined($conf->{rootfs});
@@ -436,6 +470,7 @@ sub update_lxc_config {
 	$raw .= "lxc.net.$ind.mtu = $d->{mtu}\n" if defined($d->{mtu});
     }
 
+    if ($cgv1->{cpuset}) {
 	my $had_cpuset = 0;
 	if (my $lxcconf = $conf->{lxc}) {
 	    foreach my $entry (@$lxcconf) {
@@ -457,6 +492,7 @@ sub update_lxc_config {
 	    }
 	    $raw .= "lxc.cgroup.cpuset.cpus = ".$cpuset->short_string()."\n";
 	}
+    }
 
     File::Path::mkpath("$dir/rootfs");
 



More information about the pve-devel mailing list