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