summaryrefslogtreecommitdiffstats
path: root/collectors/cgroups.plugin
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/cgroups.plugin')
-rw-r--r--collectors/cgroups.plugin/README.md12
-rw-r--r--collectors/cgroups.plugin/cgroup-network.c81
-rw-r--r--collectors/cgroups.plugin/sys_fs_cgroup.c184
3 files changed, 128 insertions, 149 deletions
diff --git a/collectors/cgroups.plugin/README.md b/collectors/cgroups.plugin/README.md
index d0f822e66..e58f1ba04 100644
--- a/collectors/cgroups.plugin/README.md
+++ b/collectors/cgroups.plugin/README.md
@@ -1,6 +1,10 @@
<!--
-title: "cgroups.plugin"
-custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/cgroups.plugin/README.md
+title: "Monitor Cgroups (cgroups.plugin)"
+custom_edit_url: "https://github.com/netdata/netdata/edit/master/collectors/cgroups.plugin/README.md"
+sidebar_label: "Monitor Cgroups"
+learn_status: "Published"
+learn_topic_type: "References"
+learn_rel_path: "References/Collectors references/Virtualized environments/Containers"
-->
# cgroups.plugin
@@ -74,7 +78,7 @@ currently unsupported when using unified cgroups.
### enabled cgroups
To provide a sane default, Netdata uses the
-following [pattern list](https://learn.netdata.cloud/docs/agent/libnetdata/simple_pattern):
+following [pattern list](https://github.com/netdata/netdata/blob/master/libnetdata/simple_pattern/README.md):
- checks the pattern against the path of the cgroup
@@ -305,4 +309,4 @@ cannot find, but immediately:
- I/O full pressure
Network interfaces are monitored by means of
-the [proc plugin](/collectors/proc.plugin/README.md#monitored-network-interface-metrics).
+the [proc plugin](https://github.com/netdata/netdata/blob/master/collectors/proc.plugin/README.md#monitored-network-interface-metrics).
diff --git a/collectors/cgroups.plugin/cgroup-network.c b/collectors/cgroups.plugin/cgroup-network.c
index 0b66ea475..a490df394 100644
--- a/collectors/cgroups.plugin/cgroup-network.c
+++ b/collectors/cgroups.plugin/cgroup-network.c
@@ -43,7 +43,7 @@ unsigned int read_iface_iflink(const char *prefix, const char *iface) {
unsigned long long iflink = 0;
int ret = read_single_number_file(filename, &iflink);
- if(ret) error("Cannot read '%s'.", filename);
+ if(ret) collector_error("Cannot read '%s'.", filename);
return (unsigned int)iflink;
}
@@ -56,7 +56,7 @@ unsigned int read_iface_ifindex(const char *prefix, const char *iface) {
unsigned long long ifindex = 0;
int ret = read_single_number_file(filename, &ifindex);
- if(ret) error("Cannot read '%s'.", filename);
+ if(ret) collector_error("Cannot read '%s'.", filename);
return (unsigned int)ifindex;
}
@@ -70,18 +70,18 @@ struct iface *read_proc_net_dev(const char *scope __maybe_unused, const char *pr
snprintfz(filename, FILENAME_MAX, "%s%s", prefix, (*prefix)?"/proc/1/net/dev":"/proc/net/dev");
#ifdef NETDATA_INTERNAL_CHECKS
- info("parsing '%s'", filename);
+ collector_info("parsing '%s'", filename);
#endif
ff = procfile_open(filename, " \t,:|", PROCFILE_FLAG_DEFAULT);
if(unlikely(!ff)) {
- error("Cannot open file '%s'", filename);
+ collector_error("Cannot open file '%s'", filename);
return NULL;
}
ff = procfile_readall(ff);
if(unlikely(!ff)) {
- error("Cannot read file '%s'", filename);
+ collector_error("Cannot read file '%s'", filename);
return NULL;
}
@@ -99,7 +99,7 @@ struct iface *read_proc_net_dev(const char *scope __maybe_unused, const char *pr
root = t;
#ifdef NETDATA_INTERNAL_CHECKS
- info("added %s interface '%s', ifindex %u, iflink %u", scope, t->device, t->ifindex, t->iflink);
+ collector_info("added %s interface '%s', ifindex %u, iflink %u", scope, t->device, t->ifindex, t->iflink);
#endif
}
@@ -145,7 +145,7 @@ static void continue_as_child(void) {
pid_t ret;
if (child < 0)
- error("fork() failed");
+ collector_error("fork() failed");
/* Only the child returns */
if (child == 0)
@@ -180,7 +180,7 @@ int proc_pid_fd(const char *prefix, const char *ns, pid_t pid) {
int fd = open(filename, O_RDONLY);
if(fd == -1)
- error("Cannot open proc_pid_fd() file '%s'", filename);
+ collector_error("Cannot open proc_pid_fd() file '%s'", filename);
return fd;
}
@@ -230,7 +230,7 @@ int switch_namespace(const char *prefix, pid_t pid) {
if(setns(all_ns[i].fd, all_ns[i].nstype) == -1) {
if(pass == 1) {
all_ns[i].status = 0;
- error("Cannot switch to %s namespace of pid %d", all_ns[i].name, (int) pid);
+ collector_error("Cannot switch to %s namespace of pid %d", all_ns[i].name, (int) pid);
}
}
else
@@ -243,17 +243,17 @@ int switch_namespace(const char *prefix, pid_t pid) {
if(root_fd != -1) {
if(fchdir(root_fd) < 0)
- error("Cannot fchdir() to pid %d root directory", (int)pid);
+ collector_error("Cannot fchdir() to pid %d root directory", (int)pid);
if(chroot(".") < 0)
- error("Cannot chroot() to pid %d root directory", (int)pid);
+ collector_error("Cannot chroot() to pid %d root directory", (int)pid);
close(root_fd);
}
if(cwd_fd != -1) {
if(fchdir(cwd_fd) < 0)
- error("Cannot fchdir() to pid %d current working directory", (int)pid);
+ collector_error("Cannot fchdir() to pid %d current working directory", (int)pid);
close(cwd_fd);
}
@@ -277,7 +277,7 @@ int switch_namespace(const char *prefix, pid_t pid) {
#else
errno = ENOSYS;
- error("setns() is missing on this system.");
+ collector_error("setns() is missing on this system.");
return 1;
#endif
@@ -286,13 +286,13 @@ int switch_namespace(const char *prefix, pid_t pid) {
pid_t read_pid_from_cgroup_file(const char *filename) {
int fd = open(filename, procfile_open_flags);
if(fd == -1) {
- error("Cannot open pid_from_cgroup() file '%s'.", filename);
+ collector_error("Cannot open pid_from_cgroup() file '%s'.", filename);
return 0;
}
FILE *fp = fdopen(fd, "r");
if(!fp) {
- error("Cannot upgrade fd to fp for file '%s'.", filename);
+ collector_error("Cannot upgrade fd to fp for file '%s'.", filename);
return 0;
}
@@ -308,7 +308,7 @@ pid_t read_pid_from_cgroup_file(const char *filename) {
fclose(fp);
#ifdef NETDATA_INTERNAL_CHECKS
- if(pid > 0) info("found pid %d on file '%s'", pid, filename);
+ if(pid > 0) collector_info("found pid %d on file '%s'", pid, filename);
#endif
return pid;
@@ -331,7 +331,7 @@ pid_t read_pid_from_cgroup(const char *path) {
DIR *dir = opendir(path);
if (!dir) {
- error("cannot read directory '%s'", path);
+ collector_error("cannot read directory '%s'", path);
return 0;
}
@@ -369,7 +369,7 @@ struct found_device {
void add_device(const char *host, const char *guest) {
#ifdef NETDATA_INTERNAL_CHECKS
- info("adding device with host '%s', guest '%s'", host, guest);
+ collector_info("adding device with host '%s', guest '%s'", host, guest);
#endif
uint32_t hash = simple_hash(host);
@@ -422,36 +422,36 @@ void detect_veth_interfaces(pid_t pid) {
host = read_proc_net_dev("host", netdata_configured_host_prefix);
if(!host) {
errno = 0;
- error("cannot read host interface list.");
+ collector_error("cannot read host interface list.");
goto cleanup;
}
if(!eligible_ifaces(host)) {
errno = 0;
- info("there are no double-linked host interfaces available.");
+ collector_info("there are no double-linked host interfaces available.");
goto cleanup;
}
if(switch_namespace(netdata_configured_host_prefix, pid)) {
errno = 0;
- error("cannot switch to the namespace of pid %u", (unsigned int) pid);
+ collector_error("cannot switch to the namespace of pid %u", (unsigned int) pid);
goto cleanup;
}
#ifdef NETDATA_INTERNAL_CHECKS
- info("switched to namespaces of pid %d", pid);
+ collector_info("switched to namespaces of pid %d", pid);
#endif
cgroup = read_proc_net_dev("cgroup", NULL);
if(!cgroup) {
errno = 0;
- error("cannot read cgroup interface list.");
+ collector_error("cannot read cgroup interface list.");
goto cleanup;
}
if(!eligible_ifaces(cgroup)) {
errno = 0;
- error("there are not double-linked cgroup interfaces available.");
+ collector_error("there are not double-linked cgroup interfaces available.");
goto cleanup;
}
@@ -495,7 +495,7 @@ cleanup:
#define CGROUP_NETWORK_INTERFACE_MAX_LINE 2048
void call_the_helper(pid_t pid, const char *cgroup) {
if(setresuid(0, 0, 0) == -1)
- error("setresuid(0, 0, 0) failed.");
+ collector_error("setresuid(0, 0, 0) failed.");
char command[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
if(cgroup)
@@ -503,7 +503,7 @@ void call_the_helper(pid_t pid, const char *cgroup) {
else
snprintfz(command, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec " PLUGINS_DIR "/cgroup-network-helper.sh --pid %d", pid);
- info("running: %s", command);
+ collector_info("running: %s", command);
pid_t cgroup_pid;
FILE *fp_child_input, *fp_child_output;
@@ -539,7 +539,7 @@ void call_the_helper(pid_t pid, const char *cgroup) {
netdata_pclose(fp_child_input, fp_child_output, cgroup_pid);
}
else
- error("cannot execute cgroup-network helper script: %s", command);
+ collector_error("cannot execute cgroup-network helper script: %s", command);
}
int is_valid_path_symbol(char c) {
@@ -570,33 +570,33 @@ int verify_path(const char *path) {
const char *s = path;
while((c = *s++)) {
if(!( isalnum(c) || is_valid_path_symbol(c) )) {
- error("invalid character in path '%s'", path);
+ collector_error("invalid character in path '%s'", path);
return -1;
}
}
if(strstr(path, "\\") && !strstr(path, "\\x")) {
- error("invalid escape sequence in path '%s'", path);
+ collector_error("invalid escape sequence in path '%s'", path);
return 1;
}
if(strstr(path, "/../")) {
- error("invalid parent path sequence detected in '%s'", path);
+ collector_error("invalid parent path sequence detected in '%s'", path);
return 1;
}
if(path[0] != '/') {
- error("only absolute path names are supported - invalid path '%s'", path);
+ collector_error("only absolute path names are supported - invalid path '%s'", path);
return -1;
}
if (stat(path, &sb) == -1) {
- error("cannot stat() path '%s'", path);
+ collector_error("cannot stat() path '%s'", path);
return -1;
}
if((sb.st_mode & S_IFMT) != S_IFDIR) {
- error("path '%s' is not a directory", path);
+ collector_error("path '%s' is not a directory", path);
return -1;
}
@@ -618,10 +618,10 @@ char *fix_path_variable(void) {
char *s = strsep(&ptr, ":");
if(s && *s) {
if(verify_path(s) == -1) {
- error("the PATH variable includes an invalid path '%s' - removed it.", s);
+ collector_error("the PATH variable includes an invalid path '%s' - removed it.", s);
}
else {
- info("the PATH variable includes a valid path '%s'.", s);
+ collector_info("the PATH variable includes a valid path '%s'.", s);
if(added) strcat(safe_path, ":");
strcat(safe_path, s);
added++;
@@ -629,8 +629,8 @@ char *fix_path_variable(void) {
}
}
- info("unsafe PATH: '%s'.", path);
- info(" safe PATH: '%s'.", safe_path);
+ collector_info("unsafe PATH: '%s'.", path);
+ collector_info(" safe PATH: '%s'.", safe_path);
freez(p);
return safe_path;
@@ -646,6 +646,7 @@ void usage(void) {
}
int main(int argc, char **argv) {
+ stderror = stderr;
pid_t pid = 0;
program_name = argv[0];
@@ -690,7 +691,7 @@ int main(int argc, char **argv) {
if(pid <= 0) {
errno = 0;
- error("Invalid pid %d given", (int) pid);
+ collector_error("Invalid pid %d given", (int) pid);
return 2;
}
@@ -699,7 +700,7 @@ int main(int argc, char **argv) {
else if(!strcmp(argv[arg], "--cgroup")) {
char *cgroup = argv[arg+1];
if(verify_path(cgroup) == -1) {
- error("cgroup '%s' does not exist or is not valid.", cgroup);
+ collector_error("cgroup '%s' does not exist or is not valid.", cgroup);
return 1;
}
@@ -708,7 +709,7 @@ int main(int argc, char **argv) {
if(pid <= 0 && !detected_devices) {
errno = 0;
- error("Cannot find a cgroup PID from cgroup '%s'", cgroup);
+ collector_error("Cannot find a cgroup PID from cgroup '%s'", cgroup);
}
}
else
diff --git a/collectors/cgroups.plugin/sys_fs_cgroup.c b/collectors/cgroups.plugin/sys_fs_cgroup.c
index 8f7548286..66db0b728 100644
--- a/collectors/cgroups.plugin/sys_fs_cgroup.c
+++ b/collectors/cgroups.plugin/sys_fs_cgroup.c
@@ -174,9 +174,9 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec)
}
if (ret == -1) {
- error("Failed to get the output of \"%s\"", exec);
+ collector_error("Failed to get the output of \"%s\"", exec);
} else if (ret == 0) {
- info("Cannot get the output of \"%s\" within %"PRId64" seconds", exec, (int64_t)timeout.tv_sec);
+ collector_info("Cannot get the output of \"%s\" within %"PRId64" seconds", exec, (int64_t)timeout.tv_sec);
} else {
while (fgets(buf, MAXSIZE_PROC_CMDLINE, fp_child_output) != NULL) {
if ((begin = strstr(buf, SYSTEMD_HIERARCHY_STRING))) {
@@ -214,7 +214,7 @@ static enum cgroups_type cgroups_try_detect_version()
FILE *fp_child_input;
FILE *fp_child_output = netdata_popen("grep cgroup /proc/filesystems", &command_pid, &fp_child_input);
if (!fp_child_output) {
- error("popen failed");
+ collector_error("popen failed");
return CGROUPS_AUTODETECT_FAIL;
}
while (fgets(buf, MAXSIZE_PROC_CMDLINE, fp_child_output) != NULL) {
@@ -258,12 +258,12 @@ static enum cgroups_type cgroups_try_detect_version()
// check kernel command line flag that can override that setting
FILE *fp = fopen("/proc/cmdline", "r");
if (!fp) {
- error("Error reading kernel boot commandline parameters");
+ collector_error("Error reading kernel boot commandline parameters");
return CGROUPS_AUTODETECT_FAIL;
}
if (!fgets(buf, MAXSIZE_PROC_CMDLINE, fp)) {
- error("couldn't read all cmdline params into buffer");
+ collector_error("couldn't read all cmdline params into buffer");
fclose(fp);
return CGROUPS_AUTODETECT_FAIL;
}
@@ -271,7 +271,7 @@ static enum cgroups_type cgroups_try_detect_version()
fclose(fp);
if (strstr(buf, "systemd.unified_cgroup_hierarchy=0")) {
- info("cgroups v2 (unified cgroups) is available but are disabled on this system.");
+ collector_info("cgroups v2 (unified cgroups) is available but are disabled on this system.");
return CGROUPS_V1;
}
return CGROUPS_V2;
@@ -311,7 +311,7 @@ void read_cgroup_plugin_configuration() {
if(cgroup_use_unified_cgroups == CONFIG_BOOLEAN_AUTO)
cgroup_use_unified_cgroups = (cgroups_try_detect_version() == CGROUPS_V2);
- info("use unified cgroups %s", cgroup_use_unified_cgroups ? "true" : "false");
+ collector_info("use unified cgroups %s", cgroup_use_unified_cgroups ? "true" : "false");
cgroup_containers_chart_priority = (int)config_get_number("plugin:cgroups", "containers priority", cgroup_containers_chart_priority);
if(cgroup_containers_chart_priority < 1)
@@ -361,7 +361,7 @@ void read_cgroup_plugin_configuration() {
mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuacct");
if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "cpuacct");
if(!mi) {
- error("CGROUP: cannot find cpuacct mountinfo. Assuming default: /sys/fs/cgroup/cpuacct");
+ collector_error("CGROUP: cannot find cpuacct mountinfo. Assuming default: /sys/fs/cgroup/cpuacct");
s = "/sys/fs/cgroup/cpuacct";
}
else s = mi->mount_point;
@@ -371,7 +371,7 @@ void read_cgroup_plugin_configuration() {
mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "cpuset");
if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "cpuset");
if(!mi) {
- error("CGROUP: cannot find cpuset mountinfo. Assuming default: /sys/fs/cgroup/cpuset");
+ collector_error("CGROUP: cannot find cpuset mountinfo. Assuming default: /sys/fs/cgroup/cpuset");
s = "/sys/fs/cgroup/cpuset";
}
else s = mi->mount_point;
@@ -381,7 +381,7 @@ void read_cgroup_plugin_configuration() {
mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "blkio");
if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "blkio");
if(!mi) {
- error("CGROUP: cannot find blkio mountinfo. Assuming default: /sys/fs/cgroup/blkio");
+ collector_error("CGROUP: cannot find blkio mountinfo. Assuming default: /sys/fs/cgroup/blkio");
s = "/sys/fs/cgroup/blkio";
}
else s = mi->mount_point;
@@ -391,7 +391,7 @@ void read_cgroup_plugin_configuration() {
mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "memory");
if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "memory");
if(!mi) {
- error("CGROUP: cannot find memory mountinfo. Assuming default: /sys/fs/cgroup/memory");
+ collector_error("CGROUP: cannot find memory mountinfo. Assuming default: /sys/fs/cgroup/memory");
s = "/sys/fs/cgroup/memory";
}
else s = mi->mount_point;
@@ -401,7 +401,7 @@ void read_cgroup_plugin_configuration() {
mi = mountinfo_find_by_filesystem_super_option(root, "cgroup", "devices");
if(!mi) mi = mountinfo_find_by_filesystem_mount_source(root, "cgroup", "devices");
if(!mi) {
- error("CGROUP: cannot find devices mountinfo. Assuming default: /sys/fs/cgroup/devices");
+ collector_error("CGROUP: cannot find devices mountinfo. Assuming default: /sys/fs/cgroup/devices");
s = "/sys/fs/cgroup/devices";
}
else s = mi->mount_point;
@@ -433,7 +433,7 @@ void read_cgroup_plugin_configuration() {
if(mi) debug(D_CGROUP, "found unified cgroup root using mountsource info, with path: '%s'", mi->mount_point);
}
if(!mi) {
- error("CGROUP: cannot find cgroup2 mountinfo. Assuming default: /sys/fs/cgroup");
+ collector_error("CGROUP: cannot find cgroup2 mountinfo. Assuming default: /sys/fs/cgroup");
s = "/sys/fs/cgroup";
}
else s = mi->mount_point;
@@ -575,13 +575,13 @@ void netdata_cgroup_ebpf_initialize_shm()
{
shm_fd_cgroup_ebpf = shm_open(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME, O_CREAT | O_RDWR, 0660);
if (shm_fd_cgroup_ebpf < 0) {
- error("Cannot initialize shared memory used by cgroup and eBPF, integration won't happen.");
+ collector_error("Cannot initialize shared memory used by cgroup and eBPF, integration won't happen.");
return;
}
size_t length = sizeof(netdata_ebpf_cgroup_shm_header_t) + cgroup_root_max * sizeof(netdata_ebpf_cgroup_shm_body_t);
if (ftruncate(shm_fd_cgroup_ebpf, length)) {
- error("Cannot set size for shared memory.");
+ collector_error("Cannot set size for shared memory.");
goto end_init_shm;
}
@@ -590,7 +590,7 @@ void netdata_cgroup_ebpf_initialize_shm()
shm_fd_cgroup_ebpf, 0);
if (!shm_cgroup_ebpf.header) {
- error("Cannot map shared memory used between cgroup and eBPF, integration won't happen");
+ collector_error("Cannot map shared memory used between cgroup and eBPF, integration won't happen");
goto end_init_shm;
}
shm_cgroup_ebpf.body = (netdata_ebpf_cgroup_shm_body_t *) ((char *)shm_cgroup_ebpf.header +
@@ -604,7 +604,7 @@ void netdata_cgroup_ebpf_initialize_shm()
return;
}
- error("Cannot create semaphore, integration between eBPF and cgroup won't happen");
+ collector_error("Cannot create semaphore, integration between eBPF and cgroup won't happen");
munmap(shm_cgroup_ebpf.header, length);
end_init_shm:
@@ -1077,7 +1077,7 @@ static inline void cgroup_read_cpuacct_stat(struct cpuacct_stat *cp) {
unsigned long i, lines = procfile_lines(ff);
if(unlikely(lines < 1)) {
- error("CGROUP: file '%s' should have 1+ lines.", cp->filename);
+ collector_error("CGROUP: file '%s' should have 1+ lines.", cp->filename);
cp->updated = 0;
return;
}
@@ -1123,7 +1123,7 @@ static inline void cgroup_read_cpuacct_cpu_stat(struct cpuacct_cpu_throttling *c
unsigned long lines = procfile_lines(ff);
if (unlikely(lines < 3)) {
- error("CGROUP: file '%s' should have 3 lines.", cp->filename);
+ collector_error("CGROUP: file '%s' should have 3 lines.", cp->filename);
cp->updated = 0;
return;
}
@@ -1180,7 +1180,7 @@ static inline void cgroup2_read_cpuacct_cpu_stat(struct cpuacct_stat *cp, struct
unsigned long lines = procfile_lines(ff);
if (unlikely(lines < 3)) {
- error("CGROUP: file '%s' should have at least 3 lines.", cp->filename);
+ collector_error("CGROUP: file '%s' should have at least 3 lines.", cp->filename);
cp->updated = 0;
return;
}
@@ -1261,7 +1261,7 @@ static inline void cgroup_read_cpuacct_usage(struct cpuacct_usage *ca) {
}
if(unlikely(procfile_lines(ff) < 1)) {
- error("CGROUP: file '%s' should have 1+ lines but has %zu.", ca->filename, procfile_lines(ff));
+ collector_error("CGROUP: file '%s' should have 1+ lines but has %zu.", ca->filename, procfile_lines(ff));
ca->updated = 0;
return;
}
@@ -1326,7 +1326,7 @@ static inline void cgroup_read_blkio(struct blkio *io) {
unsigned long i, lines = procfile_lines(ff);
if(unlikely(lines < 1)) {
- error("CGROUP: file '%s' should have 1+ lines.", io->filename);
+ collector_error("CGROUP: file '%s' should have 1+ lines.", io->filename);
io->updated = 0;
return;
}
@@ -1398,7 +1398,7 @@ static inline void cgroup2_read_blkio(struct blkio *io, unsigned int word_offset
unsigned long i, lines = procfile_lines(ff);
if (unlikely(lines < 1)) {
- error("CGROUP: file '%s' should have 1+ lines.", io->filename);
+ collector_error("CGROUP: file '%s' should have 1+ lines.", io->filename);
io->updated = 0;
return;
}
@@ -1442,7 +1442,7 @@ static inline void cgroup2_read_pressure(struct pressure *res) {
size_t lines = procfile_lines(ff);
if (lines < 1) {
- error("CGROUP: file '%s' should have 1+ lines.", res->filename);
+ collector_error("CGROUP: file '%s' should have 1+ lines.", res->filename);
res->updated = 0;
return;
}
@@ -1456,7 +1456,7 @@ static inline void cgroup2_read_pressure(struct pressure *res) {
res->full.share_time.value10 = strtod(procfile_lineword(ff, 1, 2), NULL);
res->full.share_time.value60 = strtod(procfile_lineword(ff, 1, 4), NULL);
res->full.share_time.value300 = strtod(procfile_lineword(ff, 1, 6), NULL);
- res->full.total_time.value_total = str2ull(procfile_lineword(ff, 0, 8)) / 1000; // us->ms
+ res->full.total_time.value_total = str2ull(procfile_lineword(ff, 1, 8)) / 1000; // us->ms
}
res->updated = 1;
@@ -1499,7 +1499,7 @@ static inline void cgroup_read_memory(struct memory *mem, char parent_cg_is_unif
unsigned long i, lines = procfile_lines(ff);
if(unlikely(lines < 1)) {
- error("CGROUP: file '%s' should have 1+ lines.", mem->filename_detailed);
+ collector_error("CGROUP: file '%s' should have 1+ lines.", mem->filename_detailed);
mem->updated_detailed = 0;
goto memory_next;
}
@@ -1669,7 +1669,7 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
FILE *fp_child_input, *fp_child_output;
(void)netdata_popen_raw_default_flags_and_environment(&cgroup_pid, &fp_child_input, &fp_child_output, cgroups_network_interface_script, "--cgroup", cgroup_identifier);
if(!fp_child_output) {
- error("CGROUP: cannot popen(%s --cgroup \"%s\", \"r\").", cgroups_network_interface_script, cgroup_identifier);
+ collector_error("CGROUP: cannot popen(%s --cgroup \"%s\", \"r\").", cgroups_network_interface_script, cgroup_identifier);
return;
}
@@ -1687,12 +1687,12 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
}
if(!*s) {
- error("CGROUP: empty host interface returned by script");
+ collector_error("CGROUP: empty host interface returned by script");
continue;
}
if(!*t) {
- error("CGROUP: empty guest interface returned by script");
+ collector_error("CGROUP: empty guest interface returned by script");
continue;
}
@@ -1702,7 +1702,7 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
i->next = cg->interfaces;
cg->interfaces = i;
- info("CGROUP: cgroup '%s' has network interface '%s' as '%s'", cg->id, i->host_device, i->container_device);
+ collector_info("CGROUP: cgroup '%s' has network interface '%s' as '%s'", cg->id, i->host_device, i->container_device);
// register a device rename to proc_net_dev.c
netdev_rename_device_add(
@@ -1875,7 +1875,7 @@ static inline void discovery_rename_cgroup(struct cgroup *cg) {
FILE *fp_child_input, *fp_child_output;
(void)netdata_popen_raw_default_flags_and_environment(&cgroup_pid, &fp_child_input, &fp_child_output, cgroups_rename_script, cg->id, cg->intermediate_id);
if (!fp_child_output) {
- error("CGROUP: cannot popen(%s \"%s\", \"r\").", cgroups_rename_script, cg->intermediate_id);
+ collector_error("CGROUP: cannot popen(%s \"%s\", \"r\").", cgroups_rename_script, cg->intermediate_id);
cg->pending_renames = 0;
cg->processed = 1;
return;
@@ -2034,14 +2034,14 @@ static inline void discovery_find_cgroup_in_dir_callback(const char *dir) {
}
if (cgroup_root_count >= cgroup_root_max) {
- info("CGROUP: maximum number of cgroups reached (%d). Not adding cgroup '%s'", cgroup_root_count, dir);
+ collector_info("CGROUP: maximum number of cgroups reached (%d). Not adding cgroup '%s'", cgroup_root_count, dir);
return;
}
if (cgroup_max_depth > 0) {
int depth = calc_cgroup_depth(dir);
if (depth > cgroup_max_depth) {
- info("CGROUP: '%s' is too deep (%d, while max is %d)", dir, depth, cgroup_max_depth);
+ collector_info("CGROUP: '%s' is too deep (%d, while max is %d)", dir, depth, cgroup_max_depth);
return;
}
}
@@ -2066,7 +2066,7 @@ static inline int discovery_find_dir_in_subdirs(const char *base, const char *th
DIR *dir = opendir(this);
if(!dir) {
- error("CGROUP: cannot read directory '%s'", base);
+ collector_error("CGROUP: cannot read directory '%s'", base);
return ret;
}
ret = 1;
@@ -2550,7 +2550,7 @@ static inline void discovery_find_all_cgroups_v1() {
if (cgroup_enable_cpuacct_stat || cgroup_enable_cpuacct_usage) {
if (discovery_find_dir_in_subdirs(cgroup_cpuacct_base, NULL, discovery_find_cgroup_in_dir_callback) == -1) {
cgroup_enable_cpuacct_stat = cgroup_enable_cpuacct_usage = CONFIG_BOOLEAN_NO;
- error("CGROUP: disabled cpu statistics.");
+ collector_error("CGROUP: disabled cpu statistics.");
}
}
@@ -2560,7 +2560,7 @@ static inline void discovery_find_all_cgroups_v1() {
cgroup_enable_blkio_io = cgroup_enable_blkio_ops = cgroup_enable_blkio_throttle_io =
cgroup_enable_blkio_throttle_ops = cgroup_enable_blkio_merged_ops = cgroup_enable_blkio_queued_ops =
CONFIG_BOOLEAN_NO;
- error("CGROUP: disabled blkio statistics.");
+ collector_error("CGROUP: disabled blkio statistics.");
}
}
@@ -2568,14 +2568,14 @@ static inline void discovery_find_all_cgroups_v1() {
if (discovery_find_dir_in_subdirs(cgroup_memory_base, NULL, discovery_find_cgroup_in_dir_callback) == -1) {
cgroup_enable_memory = cgroup_enable_detailed_memory = cgroup_enable_swap = cgroup_enable_memory_failcnt =
CONFIG_BOOLEAN_NO;
- error("CGROUP: disabled memory statistics.");
+ collector_error("CGROUP: disabled memory statistics.");
}
}
if (cgroup_search_in_devices) {
if (discovery_find_dir_in_subdirs(cgroup_devices_base, NULL, discovery_find_cgroup_in_dir_callback) == -1) {
cgroup_search_in_devices = 0;
- error("CGROUP: disabled devices statistics.");
+ collector_error("CGROUP: disabled devices statistics.");
}
}
}
@@ -2583,7 +2583,7 @@ static inline void discovery_find_all_cgroups_v1() {
static inline void discovery_find_all_cgroups_v2() {
if (discovery_find_dir_in_subdirs(cgroup_unified_base, NULL, discovery_find_cgroup_in_dir_callback) == -1) {
cgroup_unified_exist = CONFIG_BOOLEAN_NO;
- error("CGROUP: disabled unified cgroups statistics.");
+ collector_error("CGROUP: disabled unified cgroups statistics.");
}
}
@@ -2651,7 +2651,7 @@ static int discovery_is_cgroup_duplicate(struct cgroup *cg) {
struct cgroup *c;
for (c = discovered_cgroup_root; c; c = c->discovered_next) {
if (c != cg && c->enabled && c->hash_chart == cg->hash_chart && !strcmp(c->chart_id, cg->chart_id)) {
- error("CGROUP: chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.", cg->chart_id, c->id, cg->id);
+ collector_error("CGROUP: chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.", cg->chart_id, c->id, cg->id);
return 1;
}
}
@@ -2686,7 +2686,7 @@ static inline void discovery_process_cgroup(struct cgroup *cg) {
cg->processed = 1;
if ((strlen(cg->chart_id) + strlen(cgroup_chart_id_prefix)) >= RRD_ID_LENGTH_MAX) {
- info("cgroup '%s' (chart id '%s') disabled because chart_id exceeds the limit (RRD_ID_LENGTH_MAX)", cg->id, cg->chart_id);
+ collector_info("cgroup '%s' (chart id '%s') disabled because chart_id exceeds the limit (RRD_ID_LENGTH_MAX)", cg->id, cg->chart_id);
return;
}
@@ -2754,10 +2754,20 @@ static inline void discovery_find_all_cgroups() {
debug(D_CGROUP, "done searching for cgroups");
}
+static void cgroup_discovery_cleanup(void *ptr) {
+ UNUSED(ptr);
+
+ discovery_thread.exited = 1;
+ worker_unregister();
+ service_exits();
+}
+
void cgroup_discovery_worker(void *ptr)
{
UNUSED(ptr);
+ netdata_thread_cleanup_push(cgroup_discovery_cleanup, ptr);
+
worker_register("CGROUPSDISC");
worker_register_job_name(WORKER_DISCOVERY_INIT, "init");
worker_register_job_name(WORKER_DISCOVERY_FIND, "find");
@@ -2777,24 +2787,23 @@ void cgroup_discovery_worker(void *ptr)
NULL,
SIMPLE_PATTERN_EXACT);
- while (!netdata_exit) {
+ while (service_running(SERVICE_COLLECTORS)) {
worker_is_idle();
uv_mutex_lock(&discovery_thread.mutex);
- while (!discovery_thread.start_discovery)
+ while (!discovery_thread.start_discovery && service_running(SERVICE_COLLECTORS))
uv_cond_wait(&discovery_thread.cond_var, &discovery_thread.mutex);
discovery_thread.start_discovery = 0;
uv_mutex_unlock(&discovery_thread.mutex);
- if (unlikely(netdata_exit))
+ if (unlikely(!service_running(SERVICE_COLLECTORS)))
break;
discovery_find_all_cgroups();
}
- discovery_thread.exited = 1;
- worker_unregister();
-}
+ netdata_thread_cleanup_pop(1);
+}
// ----------------------------------------------------------------------------
// generate charts
@@ -3507,52 +3516,15 @@ static inline char *cgroup_chart_type(char *buffer, const char *id, size_t len)
return buffer;
}
-static inline unsigned long long cpuset_str2ull(char **s) {
- unsigned long long n = 0;
- char c;
- for(c = **s; c >= '0' && c <= '9' ; c = *(++*s)) {
- n *= 10;
- n += c - '0';
- }
- return n;
-}
-
static inline void update_cpu_limits(char **filename, unsigned long long *value, struct cgroup *cg) {
if(*filename) {
int ret = -1;
if(value == &cg->cpuset_cpus) {
- static char *buf = NULL;
- static size_t buf_size = 0;
-
- if(!buf) {
- buf_size = 100U + 6 * get_system_cpus(); // taken from kernel/cgroup/cpuset.c
- buf = mallocz(buf_size + 1);
- }
-
- ret = read_file(*filename, buf, buf_size);
-
- if(!ret) {
- char *s = buf;
- unsigned long long ncpus = 0;
-
- // parse the cpuset string and calculate the number of cpus the cgroup is allowed to use
- while(*s) {
- unsigned long long n = cpuset_str2ull(&s);
- ncpus++;
- if(*s == ',') {
- s++;
- continue;
- }
- if(*s == '-') {
- s++;
- unsigned long long m = cpuset_str2ull(&s);
- ncpus += m - n; // calculate the number of cpus in the region
- }
- s++;
- }
-
- if(likely(ncpus)) *value = ncpus;
+ unsigned long ncpus = read_cpuset_cpus(*filename, get_system_cpus());
+ if(ncpus) {
+ *value = ncpus;
+ ret = 0;
}
}
else if(value == &cg->cpu_cfs_period) {
@@ -3564,7 +3536,7 @@ static inline void update_cpu_limits(char **filename, unsigned long long *value,
else ret = -1;
if(ret) {
- error("Cannot refresh cgroup %s cpu limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
+ collector_error("Cannot refresh cgroup %s cpu limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
freez(*filename);
*filename = NULL;
}
@@ -3588,7 +3560,7 @@ static inline void update_cpu_limits2(struct cgroup *cg) {
unsigned long lines = procfile_lines(ff);
if (unlikely(lines < 1)) {
- error("CGROUP: file '%s' should have 1 lines.", cg->filename_cpu_cfs_quota);
+ collector_error("CGROUP: file '%s' should have 1 lines.", cg->filename_cpu_cfs_quota);
return;
}
@@ -3605,7 +3577,7 @@ static inline void update_cpu_limits2(struct cgroup *cg) {
return;
cpu_limits2_err:
- error("Cannot refresh cgroup %s cpu limit by reading '%s'. Will not update its limit anymore.", cg->id, cg->filename_cpu_cfs_quota);
+ collector_error("Cannot refresh cgroup %s cpu limit by reading '%s'. Will not update its limit anymore.", cg->id, cg->filename_cpu_cfs_quota);
freez(cg->filename_cpu_cfs_quota);
cg->filename_cpu_cfs_quota = NULL;
@@ -3617,7 +3589,7 @@ static inline int update_memory_limits(char **filename, const RRDSETVAR_ACQUIRED
if(unlikely(!*chart_var)) {
*chart_var = rrdsetvar_custom_chart_variable_add_and_acquire(cg->st_mem_usage, chart_var_name);
if(!*chart_var) {
- error("Cannot create cgroup %s chart variable '%s'. Will not update its limit anymore.", cg->id, chart_var_name);
+ collector_error("Cannot create cgroup %s chart variable '%s'. Will not update its limit anymore.", cg->id, chart_var_name);
freez(*filename);
*filename = NULL;
}
@@ -3626,7 +3598,7 @@ static inline int update_memory_limits(char **filename, const RRDSETVAR_ACQUIRED
if(*filename && *chart_var) {
if(!(cg->options & CGROUP_OPTIONS_IS_UNIFIED)) {
if(read_single_number_file(*filename, value)) {
- error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
+ collector_error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
freez(*filename);
*filename = NULL;
}
@@ -3638,7 +3610,7 @@ static inline int update_memory_limits(char **filename, const RRDSETVAR_ACQUIRED
char buffer[30 + 1];
int ret = read_file(*filename, buffer, 30);
if(ret) {
- error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
+ collector_error("Cannot refresh cgroup %s memory limit by reading '%s'. Will not update its limit anymore.", cg->id, *filename);
freez(*filename);
*filename = NULL;
return 0;
@@ -3747,7 +3719,7 @@ void update_cgroup_charts(int update_every) {
if(unlikely(!cg->chart_var_cpu_limit)) {
cg->chart_var_cpu_limit = rrdsetvar_custom_chart_variable_add_and_acquire(cg->st_cpu, "cpu_limit");
if(!cg->chart_var_cpu_limit) {
- error("Cannot create cgroup %s chart variable 'cpu_limit'. Will not update its limit anymore.", cg->id);
+ collector_error("Cannot create cgroup %s chart variable 'cpu_limit'. Will not update its limit anymore.", cg->id);
if(cg->filename_cpuset_cpus) freez(cg->filename_cpuset_cpus);
cg->filename_cpuset_cpus = NULL;
if(cg->filename_cpu_cfs_period) freez(cg->filename_cpu_cfs_period);
@@ -4139,7 +4111,7 @@ void update_cgroup_charts(int update_every) {
if(likely(ff && procfile_lines(ff) && !strncmp(procfile_word(ff, 0), "MemTotal", 8)))
ram_total = str2ull(procfile_word(ff, 1)) * 1024;
else {
- error("Cannot read file %s. Will not update cgroup %s RAM limit anymore.", filename, cg->id);
+ collector_error("Cannot read file %s. Will not update cgroup %s RAM limit anymore.", filename, cg->id);
freez(cg->filename_memory_limit);
cg->filename_memory_limit = NULL;
}
@@ -4773,19 +4745,19 @@ static void cgroup_main_cleanup(void *ptr) {
struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
- info("cleaning up...");
+ collector_info("cleaning up...");
usec_t max = 2 * USEC_PER_SEC, step = 50000;
if (!discovery_thread.exited) {
- info("stopping discovery thread worker");
+ collector_info("stopping discovery thread worker");
uv_mutex_lock(&discovery_thread.mutex);
discovery_thread.start_discovery = 1;
uv_cond_signal(&discovery_thread.cond_var);
uv_mutex_unlock(&discovery_thread.mutex);
}
- info("waiting for discovery thread to finish...");
+ collector_info("waiting for discovery thread to finish...");
while (!discovery_thread.exited && max > 0) {
max -= step;
@@ -4824,7 +4796,7 @@ void *cgroups_main(void *ptr) {
netdata_cgroup_ebpf_initialize_shm();
if (uv_mutex_init(&cgroup_root_mutex)) {
- error("CGROUP: cannot initialize mutex for the main cgroup list");
+ collector_error("CGROUP: cannot initialize mutex for the main cgroup list");
goto exit;
}
@@ -4833,17 +4805,17 @@ void *cgroups_main(void *ptr) {
discovery_thread.exited = 0;
if (uv_mutex_init(&discovery_thread.mutex)) {
- error("CGROUP: cannot initialize mutex for discovery thread");
+ collector_error("CGROUP: cannot initialize mutex for discovery thread");
goto exit;
}
if (uv_cond_init(&discovery_thread.cond_var)) {
- error("CGROUP: cannot initialize conditional variable for discovery thread");
+ collector_error("CGROUP: cannot initialize conditional variable for discovery thread");
goto exit;
}
int error = uv_thread_create(&discovery_thread.thread, cgroup_discovery_worker, NULL);
if (error) {
- error("CGROUP: cannot create thread worker. uv_thread_create(): %s", uv_strerror(error));
+ collector_error("CGROUP: cannot create thread worker. uv_thread_create(): %s", uv_strerror(error));
goto exit;
}
uv_thread_set_name_np(discovery_thread.thread, "PLUGIN[cgroups]");
@@ -4853,11 +4825,11 @@ void *cgroups_main(void *ptr) {
usec_t step = cgroup_update_every * USEC_PER_SEC;
usec_t find_every = cgroup_check_for_new_every * USEC_PER_SEC, find_dt = 0;
- while(!netdata_exit) {
+ while(service_running(SERVICE_COLLECTORS)) {
worker_is_idle();
usec_t hb_dt = heartbeat_next(&hb, step);
- if(unlikely(netdata_exit)) break;
+ if(unlikely(!service_running(SERVICE_COLLECTORS))) break;
find_dt += hb_dt;
if (unlikely(find_dt >= find_every || (!is_inside_k8s && cgroups_check))) {
@@ -4872,9 +4844,11 @@ void *cgroups_main(void *ptr) {
worker_is_busy(WORKER_CGROUPS_READ);
read_all_discovered_cgroups(cgroup_root);
+ if(unlikely(!service_running(SERVICE_COLLECTORS))) break;
worker_is_busy(WORKER_CGROUPS_CHART);
update_cgroup_charts(cgroup_update_every);
+ if(unlikely(!service_running(SERVICE_COLLECTORS))) break;
worker_is_idle();
uv_mutex_unlock(&cgroup_root_mutex);