@cryptotaxi247 / netdata-1 / commits / a14a21f90

fix(pacakging): fix cpu/memory metrics when running inside LXC container as systemd service (#14255)

Fixes https://github.com/netdata/netdata/issues/14238

Ilya Mashchenko committed Jan 16, 2023 at 15:02 UTC a14a21f90f7f38ff2b71eb3bc0b442d240c09fd6
5 files changed +51 -4
collectors/proc.plugin/plugin_proc.c
+37
@@ -98,6 +98,41 @@ static void proc_main_cleanup(void *ptr)
98 worker_unregister();
99 }
100
101 +bool inside_lxc_container = false;
102 +
103 +static bool is_lxcfs_proc_mounted() {
104 + procfile *ff = NULL;
105 +
106 + if (unlikely(!ff)) {
107 + char filename[FILENAME_MAX + 1];
108 + snprintfz(filename, FILENAME_MAX, "/proc/self/mounts");
109 + ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
110 + if (unlikely(!ff))
111 + return false;
112 + }
113 +
114 + ff = procfile_readall(ff);
115 + if (unlikely(!ff))
116 + return false;
117 +
118 + unsigned long l, lines = procfile_lines(ff);
119 +
120 + for (l = 0; l < lines; l++) {
121 + size_t words = procfile_linewords(ff, l);
122 + if (words < 2) {
123 + continue;
124 + }
125 + if (!strcmp(procfile_lineword(ff, l, 0), "lxcfs") && !strncmp(procfile_lineword(ff, l, 1), "/proc", 5)) {
126 + procfile_close(ff);
127 + return true;
128 + }
129 + }
130 +
131 + procfile_close(ff);
132 +
133 + return false;
134 +}
135 +
136 void *proc_main(void *ptr)
137 {
138 worker_register("PROC");
@@ -128,6 +163,8 @@ void *proc_main(void *ptr)
163 heartbeat_t hb;
164 heartbeat_init(&hb);
165
166 + inside_lxc_container = is_lxcfs_proc_mounted();
167 +
168 while (service_running(SERVICE_COLLECTORS)) {
169 worker_is_idle();
170 usec_t hb_dt = heartbeat_next(&hb, step);
collectors/proc.plugin/plugin_proc.h
+1
@@ -48,6 +48,7 @@ int get_numa_node_count(void);
48
49 // metrics that need to be shared among data collectors
50 extern unsigned long long zfs_arcstats_shrinkable_cache_size_bytes;
51 +extern bool inside_lxc_container;
52
53 // netdev renames
54 void netdev_rename_device_add(
collectors/proc.plugin/proc_meminfo.c
+5 -3
@@ -158,9 +158,11 @@ int do_proc_meminfo(int update_every, usec_t dt) {
158 unsigned long long MemCached = Cached + SReclaimable - Shmem;
159 unsigned long long MemUsed = MemTotal - MemFree - MemCached - Buffers;
160 // The Linux kernel doesn't report ZFS ARC usage as cache memory (the ARC is included in the total used system memory)
161 - MemCached += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
162 - MemUsed -= (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
163 - MemAvailable += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
161 + if (!inside_lxc_container) {
162 + MemCached += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
163 + MemUsed -= (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
164 + MemAvailable += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
165 + }
166
167 if(do_ram) {
168 {
daemon/system-info.sh
+4 -1
@@ -217,6 +217,9 @@ if [ -n "${lscpu}" ] && lscpu > /dev/null 2>&1; then
217 LCPU_COUNT="$(echo "${lscpu_output}" | grep "^CPU(s):" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
218 CPU_VENDOR="$(echo "${lscpu_output}" | grep "^Vendor ID:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
219 CPU_MODEL="$(echo "${lscpu_output}" | grep "^Model name:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
220 + if grep -q "^lxcfs /proc" /proc/self/mounts 2>/dev/null && count=$(grep -c ^processor /proc/cpuinfo 2>/dev/null); then
221 + LCPU_COUNT="$count"
222 + fi
223 possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU max MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*')"
224 if [ -z "$possible_cpu_freq" ]; then
225 possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*')"
@@ -437,7 +440,7 @@ CLOUD_INSTANCE_TYPE="unknown"
440 CLOUD_INSTANCE_REGION="unknown"
441
442 if [ "${VIRTUALIZATION}" != "none" ] && command -v curl > /dev/null 2>&1; then
440 - # Returned HTTP status codes: GCP is 200, AWS is 200, DO is 404.
443 + # Returned HTTP status codes: GCP is 200, AWS is 200, DO is 404.
444 curl --fail -s -m 1 --noproxy "*" http://169.254.169.254 >/dev/null 2>&1
445 ret=$?
446 # anything but operation timeout.
system/netdata.service.in
+4
@@ -71,6 +71,10 @@ ProtectControlGroups=on
71 ReadWriteDirectories=/run/netdata
72 # This is needed to make email-based alert deliver work if Postfix is the email provider on the system.
73 ReadWriteDirectories=-/var/spool/postfix/maildrop
74 +# LXCFS directories (https://github.com/lxc/lxcfs#lxcfs)
75 +# If we don't set them explicitly, systemd mounts procfs from the host. See https://github.com/netdata/netdata/issues/14238.
76 +BindReadOnlyPaths=-/proc/cpuinfo -/proc/diskstats -/proc/loadavg -/proc/meminfo
77 +BindReadOnlyPaths=-/proc/stat -/proc/swaps -/proc/uptime -/proc/slabinfo
78
79 [Install]
80 WantedBy=multi-user.target