]> git.proxmox.com Git - pve-container.git/blobdiff - src/PVE/LXC.pm
cleanup unused functions
[pve-container.git] / src / PVE / LXC.pm
index 0245dfb1375754b70473e4f37d785dfd2ad7c9ca..9033322e0a7f1c93b0394f89225da5156bebc09c 100644 (file)
@@ -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 {