X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=src%2FPVE%2FLXC.pm;h=9033322e0a7f1c93b0394f89225da5156bebc09c;hb=f8cc2ebc93c1541e054f95350f06be47da2d592e;hp=0245dfb1375754b70473e4f37d785dfd2ad7c9ca;hpb=ab2ec461f8e1d002636219c1d13a0e75e3bd0839;p=pve-container.git diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm index 0245dfb..9033322 100644 --- a/src/PVE/LXC.pm +++ b/src/PVE/LXC.pm @@ -31,6 +31,7 @@ use PVE::Syscall qw(:fsmount); 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 Time::HiRes qw (gettimeofday); my $have_sdn; @@ -106,23 +107,6 @@ sub get_container_disk_usage { my $last_proc_vmid_stat; -my $parse_cpuacct_stat = sub { - my ($vmid, $unprivileged) = @_; - - my $raw = read_cgroup_value('cpuacct', $vmid, $unprivileged, 'cpuacct.stat', 1); - - my $stat = {}; - - if ($raw =~ m/^user (\d+)\nsystem (\d+)\n/) { - - $stat->{utime} = $1; - $stat->{stime} = $2; - - } - - return $stat; -}; - our $vmstatus_return_properties = { vmid => get_standard_option('pve-vmid'), status => { @@ -258,55 +242,45 @@ 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'); + my $cgroups = PVE::LXC::CGroup->new($vmid); - $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; + if (defined(my $mem = $cgroups->get_memory_stat())) { + $d->{mem} = $mem->{mem}; + $d->{swap} = $mem->{swap}; } else { $d->{mem} = 0; $d->{swap} = 0; } - if (-d '/sys/fs/cgroup/blkio') { - my $blkio_bytes = read_cgroup_value('blkio', $vmid, 0, 'blkio.throttle.io_service_bytes', 1); # don't check if unpriv - my @bytes = split(/\n/, $blkio_bytes); - foreach my $byte (@bytes) { - if (my ($key, $value) = $byte =~ /(Read|Write)\s+(\d+)/) { - $d->{diskread} += $2 if $key eq 'Read'; - $d->{diskwrite} += $2 if $key eq 'Write'; - } - } + if (defined(my $blkio = $cgroups->get_io_stats())) { + $d->{diskread} = $blkio->{diskread}; + $d->{diskwrite} = $blkio->{diskwrite}; } 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}; + if (defined(my $cpu = $cgroups->get_cpu_stat())) { + # Total time (in milliseconds) used up by the cpu. + my $used_ms = $cpu->{utime} + $cpu->{stime}; my $old = $last_proc_vmid_stat->{$vmid}; if (!$old) { $last_proc_vmid_stat->{$vmid} = { time => $cdtime, - used => $used, + used => $used_ms, cpu => 0, }; next; } - my $dtime = ($cdtime - $old->{time}) * $cpucount * $cpuinfo->{user_hz}; - - if ($dtime > 1000) { - my $dutime = $used - $old->{used}; - - $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus}; + my $delta_ms = ($cdtime - $old->{time}) * $cpucount * 1000.0; + if ($delta_ms > 1000.0) { + my $delta_used_ms = $used_ms - $old->{used}; + $d->{cpu} = (($delta_used_ms / $delta_ms) * $cpucount) / $d->{cpus}; $last_proc_vmid_stat->{$vmid} = { time => $cdtime, - used => $used, + used => $used_ms, cpu => $d->{cpu}, }; } else { @@ -334,33 +308,6 @@ sub vmstatus { return $list; } -sub read_cgroup_list($$$$) { - my ($group, $vmid, $unprivileged, $name) = @_; - - my $content = read_cgroup_value($group, $vmid, $unprivileged, $name, 1); - - return { split(/\s+/, $content) }; -} - -sub read_cgroup_value($$$$$) { - my ($group, $vmid, $unprivileged, $name, $full) = @_; - - my $nsdir = $unprivileged ? '' : 'ns/'; - my $path = "/sys/fs/cgroup/$group/lxc/$vmid/${nsdir}$name"; - - return PVE::Tools::file_get_contents($path) if $full; - - return PVE::Tools::file_read_firstline($path); -} - -sub write_cgroup_value { - my ($group, $vmid, $name, $value) = @_; - - my $path = "/sys/fs/cgroup/$group/lxc/$vmid/$name"; - PVE::ProcFSTools::write_proc_entry($path, $value) if -e $path; - -} - sub find_lxc_console_pids { my $res = {}; @@ -662,6 +609,12 @@ sub update_lxc_config { $raw .= "lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file 0 0\n"; } + if ($unprivileged && !$features->{force_rw_sys}) { + # unpriv. CT default to sys:rw, but that doesn't always plays well with + # systemd, e.g., systemd-networkd https://systemd.io/CONTAINER_INTERFACE/ + $raw .= "lxc.mount.auto = sys:mixed\n"; + } + # WARNING: DO NOT REMOVE this without making sure that loop device nodes # cannot be exposed to the container with r/w access (cgroup perms). # When this is enabled mounts will still remain in the monitor's namespace @@ -731,28 +684,30 @@ 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) { - my ($k, $v) = @$entry; - $had_cpuset = 1 if $k eq 'lxc.cgroup.cpuset.cpus'; - $raw .= "$k = $v\n"; - } + my $had_cpuset = 0; + if (my $lxcconf = $conf->{lxc}) { + foreach my $entry (@$lxcconf) { + my ($k, $v) = @$entry; + $had_cpuset = 1 if $k eq 'lxc.cgroup.cpuset.cpus'; + $raw .= "$k = $v\n"; } + } - my $cores = $conf->{cores}; - if (!$had_cpuset && $cores) { - my $cpuset = eval { PVE::CpuSet->new_from_cgroup('lxc', 'effective_cpus') }; - $cpuset = PVE::CpuSet->new_from_cgroup('', 'effective_cpus') if !$cpuset; - my @members = $cpuset->members(); - while (scalar(@members) > $cores) { - my $randidx = int(rand(scalar(@members))); - $cpuset->delete($members[$randidx]); - splice(@members, $randidx, 1); # keep track of the changes - } - $raw .= "lxc.cgroup.cpuset.cpus = ".$cpuset->short_string()."\n"; + my $cpuset; + my $cpuset_cgroup = eval { PVE::LXC::CGroup::cpuset_controller_path() }; + if (defined($cpuset_cgroup)) { + $cpuset = eval { PVE::CpuSet->new_from_path("$cpuset_cgroup/lxc", 1) } + || PVE::CpuSet->new_from_path($cpuset_cgroup, 1); + } + my $cores = $conf->{cores}; + if (!$had_cpuset && $cores && $cpuset) { + my @members = $cpuset->members(); + while (scalar(@members) > $cores) { + my $randidx = int(rand(scalar(@members))); + $cpuset->delete($members[$randidx]); + splice(@members, $randidx, 1); # keep track of the changes } + $raw .= "lxc.cgroup.cpuset.cpus = ".$cpuset->short_string()."\n"; } File::Path::mkpath("$dir/rootfs"); @@ -918,7 +873,7 @@ sub update_net { PVE::LXC::Config->write_config($vmid, $conf); } - if($have_sdn) { + if ($have_sdn) { PVE::Network::SDN::Zones::tap_plug($veth, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall}, $newnet->{trunks}, $newnet->{rate}); } else { PVE::Network::tap_plug($veth, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall}, $newnet->{trunks}, $newnet->{rate}); @@ -951,7 +906,7 @@ sub hotplug_net { my $vethpeer = $veth . "p"; my $eth = $newnet->{name}; - if($have_sdn) { + if ($have_sdn) { PVE::Network::SDN::Zones::veth_create($veth, $vethpeer, $newnet->{bridge}, $newnet->{hwaddr}); PVE::Network::SDN::Zones::tap_plug($veth, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall}, $newnet->{trunks}, $newnet->{rate}); } else {