summaryrefslogtreecommitdiffstats
path: root/collectors/cgroups.plugin/sys_fs_cgroup.c
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@netdata.cloud>2022-10-05 14:13:46 +0300
committerGitHub <noreply@github.com>2022-10-05 14:13:46 +0300
commit8fc3b351a2e7fc96eced8f924de2e9cec9842128 (patch)
treebde41c66573ccaf8876c280e00742cc6096b587c /collectors/cgroups.plugin/sys_fs_cgroup.c
parent6850878e697d66dc90b9af1e750b22238c63c292 (diff)
Allow netdata plugins to expose functions for querying more information about specific charts (#13720)
* function renames and code cleanup in popen.c; no actual code changes * netdata popen() now opens both child process stdin and stdout and returns FILE * for both * pass both input and output to parser structures * updated rrdset to call custom functions * RRDSET FUNCTION leading calls for both sync and async operation * put RRDSET functions to a separate file * added format and timeout at function definition * support for synchronous (internal plugins) and asynchronous (external plugins and children) functions * /api/v1/function endpoint * functions are now attached to the host and there is a dictionary view per chart * functions implemented at plugins.d * remove the defer until keyword hook from plugins.d when it is done * stream sender implementation of functions * sanitization of all functions so that certain characters are only allowed * strictier sanitization * common max size * 1st working plugins.d example * always init inflight dictionary * properly destroy dictionaries to avoid parallel insertion of items * add more debugging on disconnection reasons * add more debugging on disconnection reasons again * streaming receiver respects newlines * dont use the same fp for both streaming receive and send * dont free dbengine memory with internal checks * make sender proceed in the buffer * added timing info and garbage collection at plugins.d * added info about routing nodes * added info about routing nodes with delay * added more info about delays * added more info about delays again * signal sending thread to wake up * streaming version labeling and commented code to support capabilities * added functions to /api/v1/data, /api/v1/charts, /api/v1/chart, /api/v1/info * redirect top output to stdout * address coverity findings * fix resource leaks of popen * log attempts to connect to individual destinations * better messages * properly parse destinations * try to find a function from the most matching to the least matching * log added streaming destinations * rotate destinations bypassing a node in the middle that does not accept our connection * break the loops properly * use typedef to define callbacks * capabilities negotiation during streaming * functions exposed upstream based on capabilities; compression disabled per node persisting reconnects; always try to connect with all capabilities * restore functionality to lookup functions * better logging of capabilities * remove old versions from capabilities when a newer version is there * fix formatting * optimization for plugins.d rrdlabels to avoid creating and destructing dictionaries all the time * delayed health initialization for rrddim and rrdset * cleanup health initialization * fix for popen() not returning the right value * add health worker jobs for initializing rrdset and rrddim * added content type support for functions; apps.plugin permanent function to display all the processes * fixes for functions parameters parsing in apps.plugin * fix for process matching in apps.plugiin * first working function for apps.plugin * Dashboard ACL is disabled for functions; Function errors are all in JSON format * apps.plugin function processes returns json table * use json_escape_string() to escape message * fix formatting * apps.plugin exposes all its metrics to function processes * fix json formatting when filtering out some rows * reopen the internal pipe of rrdpush in case of errors * misplaced statement * do not use buffer->len * support for GLOBAL functions (functions that are not linked to a chart * added /api/v1/functions endpoint; removed format from the FUNCTIONS api; * swagger documentation about the new api end points * added plugins.d documentation about functions * never re-close a file * remove uncessesary ifdef * fixed issues identified by codacy * fix for null label value * make edit-config copy-and-paste friendly * Revert "make edit-config copy-and-paste friendly" This reverts commit 54500c0e0a97f65a0c66c4d34e966f6a9056698e. * reworked sender handshake to fix coverity findings * timeout is zero, for both send_timeout() and recv_timeout() * properly detect that parent closed the socket * support caching of function responses; limit function response to 10MB; added protection from malformed function responses * disabled excessive logging * added units to apps.plugin function processes and normalized all values to be human readable * shorter field names * fixed issues reported * fixed apps.plugin error response; tested that pluginsd can properly handle faulty responses * use double linked list macros for double linked list management * faster apps.plugin function printing by minimizing file operations * added memory percentage * fix compatibility issues with older compilers and FreeBSD * rrdpush sender code cleanup; rrhost structure cleanup from sender flags and variables; * fix letftover variable in ifdef * apps.plugin: do not call detach from the thread; exit immediately when input is broken * exclude AR charts from health * flush cleaner; prefer sender output * clarity * do not fill the cbuffer if not connected * fix * dont enabled host->sender if streaming is not enabled; send host label updates to parent; * functions are only available through ACLK * Prepared statement reports only in dev mode * fix AR chart detection * fix for streaming not being enabling itself * more cleanup of sender and receiver structures * moved read-only flags and configuration options to rrdhost->options * fixed merge with master * fix for incomplete rename * prevent service thread from working on charts that are being collected Co-authored-by: Stelios Fragkakis <52996999+stelfrag@users.noreply.github.com>
Diffstat (limited to 'collectors/cgroups.plugin/sys_fs_cgroup.c')
-rw-r--r--collectors/cgroups.plugin/sys_fs_cgroup.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/collectors/cgroups.plugin/sys_fs_cgroup.c b/collectors/cgroups.plugin/sys_fs_cgroup.c
index 74aedf2b52..3bee46dcf4 100644
--- a/collectors/cgroups.plugin/sys_fs_cgroup.c
+++ b/collectors/cgroups.plugin/sys_fs_cgroup.c
@@ -153,14 +153,15 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec)
char buf[MAXSIZE_PROC_CMDLINE];
char *begin, *end;
- FILE *f = mypopen(exec, &command_pid);
+ FILE *fp_child_input;
+ FILE *fp_child_output = netdata_popen(exec, &command_pid, &fp_child_input);
- if (!f)
+ if (!fp_child_output)
return retval;
fd_set rfds;
struct timeval timeout;
- int fd = fileno(f);
+ int fd = fileno(fp_child_output);
int ret = -1;
FD_ZERO(&rfds);
@@ -177,7 +178,7 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec)
} else if (ret == 0) {
info("Cannot get the output of \"%s\" within %"PRId64" seconds", exec, (int64_t)timeout.tv_sec);
} else {
- while (fgets(buf, MAXSIZE_PROC_CMDLINE, f) != NULL) {
+ while (fgets(buf, MAXSIZE_PROC_CMDLINE, fp_child_output) != NULL) {
if ((begin = strstr(buf, SYSTEMD_HIERARCHY_STRING))) {
end = begin = begin + strlen(SYSTEMD_HIERARCHY_STRING);
if (!*begin)
@@ -196,7 +197,7 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec)
}
}
- if (mypclose(f, command_pid))
+ if (netdata_pclose(fp_child_input, fp_child_output, command_pid))
return SYSTEMD_CGROUP_ERR;
return retval;
@@ -210,18 +211,19 @@ static enum cgroups_type cgroups_try_detect_version()
int cgroups2_available = 0;
// 1. check if cgroups2 available on system at all
- FILE *f = mypopen("grep cgroup /proc/filesystems", &command_pid);
- if (!f) {
+ 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");
return CGROUPS_AUTODETECT_FAIL;
}
- while (fgets(buf, MAXSIZE_PROC_CMDLINE, f) != NULL) {
+ while (fgets(buf, MAXSIZE_PROC_CMDLINE, fp_child_output) != NULL) {
if (strstr(buf, "cgroup2")) {
cgroups2_available = 1;
break;
}
}
- if(mypclose(f, command_pid))
+ if(netdata_pclose(fp_child_input, fp_child_output, command_pid))
return CGROUPS_AUTODETECT_FAIL;
if(!cgroups2_available)
@@ -254,19 +256,19 @@ static enum cgroups_type cgroups_try_detect_version()
// 4. if we are unified as on Fedora (default cgroups2 only mode)
// check kernel command line flag that can override that setting
- f = fopen("/proc/cmdline", "r");
- if (!f) {
+ FILE *fp = fopen("/proc/cmdline", "r");
+ if (!fp) {
error("Error reading kernel boot commandline parameters");
return CGROUPS_AUTODETECT_FAIL;
}
- if (!fgets(buf, MAXSIZE_PROC_CMDLINE, f)) {
+ if (!fgets(buf, MAXSIZE_PROC_CMDLINE, fp)) {
error("couldn't read all cmdline params into buffer");
- fclose(f);
+ fclose(fp);
return CGROUPS_AUTODETECT_FAIL;
}
- fclose(f);
+ fclose(fp);
if (strstr(buf, "systemd.unified_cgroup_hierarchy=0")) {
info("cgroups v2 (unified cgroups) is available but are disabled on this system.");
@@ -1665,16 +1667,16 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
}
debug(D_CGROUP, "executing cgroup_identifier %s --cgroup '%s' for cgroup '%s'", cgroups_network_interface_script, cgroup_identifier, cg->id);
- FILE *fp;
- (void)mypopen_raw_default_flags_and_environment(&cgroup_pid, &fp, cgroups_network_interface_script, "--cgroup", cgroup_identifier);
- if(!fp) {
+ 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);
return;
}
char *s;
char buffer[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
- while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, fp))) {
+ while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, fp_child_output))) {
trim(s);
if(*s && *s != '\n') {
@@ -1709,7 +1711,7 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) {
}
}
- mypclose(fp, cgroup_pid);
+ netdata_pclose(fp_child_input, fp_child_output, cgroup_pid);
// debug(D_CGROUP, "closed cgroup_identifier for cgroup '%s'", cg->id);
}
@@ -1871,9 +1873,9 @@ static inline void discovery_rename_cgroup(struct cgroup *cg) {
debug(D_CGROUP, "executing command %s \"%s\" for cgroup '%s'", cgroups_rename_script, cg->intermediate_id, cg->chart_id);
pid_t cgroup_pid;
- FILE *fp;
- (void)mypopen_raw_default_flags_and_environment(&cgroup_pid, &fp, cgroups_rename_script, cg->id, cg->intermediate_id);
- if (!fp) {
+ 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);
cg->pending_renames = 0;
cg->processed = 1;
@@ -1881,8 +1883,8 @@ static inline void discovery_rename_cgroup(struct cgroup *cg) {
}
char buffer[CGROUP_CHARTID_LINE_MAX + 1];
- char *new_name = fgets(buffer, CGROUP_CHARTID_LINE_MAX, fp);
- int exit_code = mypclose(fp, cgroup_pid);
+ char *new_name = fgets(buffer, CGROUP_CHARTID_LINE_MAX, fp_child_output);
+ int exit_code = netdata_pclose(fp_child_input, fp_child_output, cgroup_pid);
switch (exit_code) {
case 0: