summaryrefslogtreecommitdiffstats
path: root/libnetdata
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-03-31 12:59:21 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-03-31 12:59:21 +0000
commitbb8713bbc1c4594366fc735c04910edbf4c61aab (patch)
treed7da56c0b89aa371dd8ad986995dd145fdf6670a /libnetdata
parentReleasing debian version 1.29.3-4. (diff)
downloadnetdata-bb8713bbc1c4594366fc735c04910edbf4c61aab.tar.xz
netdata-bb8713bbc1c4594366fc735c04910edbf4c61aab.zip
Merging upstream version 1.30.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libnetdata')
-rw-r--r--libnetdata/avl/avl.c56
-rw-r--r--libnetdata/avl/avl.h20
-rw-r--r--libnetdata/config/appconfig.c12
-rw-r--r--libnetdata/config/appconfig.h4
-rw-r--r--libnetdata/dictionary/dictionary.c10
-rw-r--r--libnetdata/dictionary/dictionary.h2
-rw-r--r--libnetdata/ebpf/ebpf.c99
-rw-r--r--libnetdata/ebpf/ebpf.h25
-rw-r--r--libnetdata/eval/eval.c2
-rw-r--r--libnetdata/libnetdata.c59
-rw-r--r--libnetdata/libnetdata.h11
-rw-r--r--libnetdata/tests/test_str2ld.c2
12 files changed, 200 insertions, 102 deletions
diff --git a/libnetdata/avl/avl.c b/libnetdata/avl/avl.c
index 521985189..b05b97acb 100644
--- a/libnetdata/avl/avl.c
+++ b/libnetdata/avl/avl.c
@@ -17,8 +17,8 @@
/* Search |tree| for an item matching |item|, and return it if found.
Otherwise return |NULL|. */
-avl *avl_search(avl_tree_type *tree, avl *item) {
- avl *p;
+avl_t *avl_search(avl_tree_type *tree, avl_t *item) {
+ avl_t *p;
// assert (tree != NULL && item != NULL);
@@ -40,11 +40,11 @@ avl *avl_search(avl_tree_type *tree, avl *item) {
If a duplicate item is found in the tree,
returns a pointer to the duplicate without inserting |item|.
*/
-avl *avl_insert(avl_tree_type *tree, avl *item) {
- avl *y, *z; /* Top node to update balance factor, and parent. */
- avl *p, *q; /* Iterator, and parent. */
- avl *n; /* Newly inserted node. */
- avl *w; /* New root of rebalanced subtree. */
+avl_t *avl_insert(avl_tree_type *tree, avl_t *item) {
+ avl_t *y, *z; /* Top node to update balance factor, and parent. */
+ avl_t *p, *q; /* Iterator, and parent. */
+ avl_t *n; /* Newly inserted node. */
+ avl_t *w; /* New root of rebalanced subtree. */
unsigned char dir; /* Direction to descend. */
unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */
@@ -52,7 +52,7 @@ avl *avl_insert(avl_tree_type *tree, avl *item) {
// assert(tree != NULL && item != NULL);
- z = (avl *) &tree->root;
+ z = (avl_t *) &tree->root;
y = tree->root;
dir = 0;
for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir]) {
@@ -79,7 +79,7 @@ avl *avl_insert(avl_tree_type *tree, avl *item) {
p->avl_balance++;
if (y->avl_balance == -2) {
- avl *x = y->avl_link[0];
+ avl_t *x = y->avl_link[0];
if (x->avl_balance == -1) {
w = x;
y->avl_link[0] = x->avl_link[1];
@@ -103,7 +103,7 @@ avl *avl_insert(avl_tree_type *tree, avl *item) {
}
}
else if (y->avl_balance == +2) {
- avl *x = y->avl_link[1];
+ avl_t *x = y->avl_link[1];
if (x->avl_balance == +1) {
w = x;
y->avl_link[1] = x->avl_link[0];
@@ -136,19 +136,19 @@ avl *avl_insert(avl_tree_type *tree, avl *item) {
/* Deletes from |tree| and returns an item matching |item|.
Returns a null pointer if no matching item found. */
-avl *avl_remove(avl_tree_type *tree, avl *item) {
+avl_t *avl_remove(avl_tree_type *tree, avl_t *item) {
/* Stack of nodes. */
- avl *pa[AVL_MAX_HEIGHT]; /* Nodes. */
+ avl_t *pa[AVL_MAX_HEIGHT]; /* Nodes. */
unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */
int k; /* Stack pointer. */
- avl *p; /* Traverses tree to find node to delete. */
+ avl_t *p; /* Traverses tree to find node to delete. */
int cmp; /* Result of comparison between |item| and |p|. */
// assert (tree != NULL && item != NULL);
k = 0;
- p = (avl *) &tree->root;
+ p = (avl_t *) &tree->root;
for(cmp = -1; cmp != 0; cmp = tree->compar(item, p)) {
unsigned char dir = (unsigned char)(cmp > 0);
@@ -164,7 +164,7 @@ avl *avl_remove(avl_tree_type *tree, avl *item) {
if (p->avl_link[1] == NULL)
pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];
else {
- avl *r = p->avl_link[1];
+ avl_t *r = p->avl_link[1];
if (r->avl_link[0] == NULL) {
r->avl_link[0] = p->avl_link[0];
r->avl_balance = p->avl_balance;
@@ -173,7 +173,7 @@ avl *avl_remove(avl_tree_type *tree, avl *item) {
pa[k++] = r;
}
else {
- avl *s;
+ avl_t *s;
int j = k++;
for (;;) {
@@ -198,15 +198,15 @@ avl *avl_remove(avl_tree_type *tree, avl *item) {
// assert (k > 0);
while (--k > 0) {
- avl *y = pa[k];
+ avl_t *y = pa[k];
if (da[k] == 0) {
y->avl_balance++;
if (y->avl_balance == +1) break;
else if (y->avl_balance == +2) {
- avl *x = y->avl_link[1];
+ avl_t *x = y->avl_link[1];
if (x->avl_balance == -1) {
- avl *w;
+ avl_t *w;
// assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
@@ -240,9 +240,9 @@ avl *avl_remove(avl_tree_type *tree, avl *item) {
y->avl_balance--;
if (y->avl_balance == -1) break;
else if (y->avl_balance == -2) {
- avl *x = y->avl_link[0];
+ avl_t *x = y->avl_link[0];
if (x->avl_balance == +1) {
- avl *w;
+ avl_t *w;
// assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
@@ -284,7 +284,7 @@ avl *avl_remove(avl_tree_type *tree, avl *item) {
// ---------------------------
// traversing
-int avl_walker(avl *node, int (*callback)(void * /*entry*/, void * /*data*/), void *data) {
+int avl_walker(avl_t *node, int (*callback)(void * /*entry*/, void * /*data*/), void *data) {
int total = 0, ret = 0;
if(node->avl_link[0]) {
@@ -383,23 +383,23 @@ void avl_destroy_lock(avl_tree_lock *tree) {
#endif /* AVL_WITHOUT_PTHREADS */
}
-avl *avl_search_lock(avl_tree_lock *tree, avl *item) {
+avl_t *avl_search_lock(avl_tree_lock *tree, avl_t *item) {
avl_read_lock(tree);
- avl *ret = avl_search(&tree->avl_tree, item);
+ avl_t *ret = avl_search(&tree->avl_tree, item);
avl_unlock(tree);
return ret;
}
-avl * avl_remove_lock(avl_tree_lock *tree, avl *item) {
+avl_t * avl_remove_lock(avl_tree_lock *tree, avl_t *item) {
avl_write_lock(tree);
- avl *ret = avl_remove(&tree->avl_tree, item);
+ avl_t *ret = avl_remove(&tree->avl_tree, item);
avl_unlock(tree);
return ret;
}
-avl *avl_insert_lock(avl_tree_lock *tree, avl *item) {
+avl_t *avl_insert_lock(avl_tree_lock *tree, avl_t *item) {
avl_write_lock(tree);
- avl * ret = avl_insert(&tree->avl_tree, item);
+ avl_t * ret = avl_insert(&tree->avl_tree, item);
avl_unlock(tree);
return ret;
}
diff --git a/libnetdata/avl/avl.h b/libnetdata/avl/avl.h
index 32e3f27a8..eba967fd0 100644
--- a/libnetdata/avl/avl.h
+++ b/libnetdata/avl/avl.h
@@ -28,14 +28,14 @@
/* Data structures */
/* One element of the AVL tree */
-typedef struct avl {
- struct avl *avl_link[2]; /* Subtrees. */
+typedef struct avl_element {
+ struct avl_element *avl_link[2]; /* Subtrees. */
signed char avl_balance; /* Balance factor. */
-} avl;
+} avl_t;
/* An AVL tree */
typedef struct avl_tree_type {
- avl *root;
+ avl_t *root;
int (*compar)(void *a, void *b);
} avl_tree_type;
@@ -59,23 +59,23 @@ typedef struct avl_tree_lock {
* a is linked directly to the tree, so it has to
* be properly allocated by the caller.
*/
-avl *avl_insert_lock(avl_tree_lock *tree, avl *item) NEVERNULL WARNUNUSED;
-avl *avl_insert(avl_tree_type *tree, avl *item) NEVERNULL WARNUNUSED;
+avl_t *avl_insert_lock(avl_tree_lock *tree, avl_t *item) NEVERNULL WARNUNUSED;
+avl_t *avl_insert(avl_tree_type *tree, avl_t *item) NEVERNULL WARNUNUSED;
/* Remove an element a from the AVL tree t
* returns a pointer to the removed element
* or NULL if an element equal to a is not found
* (equal as returned by t->compar())
*/
-avl *avl_remove_lock(avl_tree_lock *tree, avl *item) WARNUNUSED;
-avl *avl_remove(avl_tree_type *tree, avl *item) WARNUNUSED;
+avl_t *avl_remove_lock(avl_tree_lock *tree, avl_t *item) WARNUNUSED;
+avl_t *avl_remove(avl_tree_type *tree, avl_t *item) WARNUNUSED;
/* Find the element into the tree that equal to a
* (equal as returned by t->compar())
* returns NULL is no element is equal to a
*/
-avl *avl_search_lock(avl_tree_lock *tree, avl *item);
-avl *avl_search(avl_tree_type *tree, avl *item);
+avl_t *avl_search_lock(avl_tree_lock *tree, avl_t *item);
+avl_t *avl_search(avl_tree_type *tree, avl_t *item);
/* Initialize the avl_tree_lock
*/
diff --git a/libnetdata/config/appconfig.c b/libnetdata/config/appconfig.c
index d9dcde71a..f570f32d7 100644
--- a/libnetdata/config/appconfig.c
+++ b/libnetdata/config/appconfig.c
@@ -123,15 +123,15 @@ static int appconfig_option_compare(void *a, void *b) {
else return strcmp(((struct config_option *)a)->name, ((struct config_option *)b)->name);
}
-#define appconfig_option_index_add(co, cv) (struct config_option *)avl_insert_lock(&((co)->values_index), (avl *)(cv))
-#define appconfig_option_index_del(co, cv) (struct config_option *)avl_remove_lock(&((co)->values_index), (avl *)(cv))
+#define appconfig_option_index_add(co, cv) (struct config_option *)avl_insert_lock(&((co)->values_index), (avl_t *)(cv))
+#define appconfig_option_index_del(co, cv) (struct config_option *)avl_remove_lock(&((co)->values_index), (avl_t *)(cv))
static struct config_option *appconfig_option_index_find(struct section *co, const char *name, uint32_t hash) {
struct config_option tmp;
tmp.hash = (hash)?hash:simple_hash(name);
tmp.name = (char *)name;
- return (struct config_option *)avl_search_lock(&(co->values_index), (avl *) &tmp);
+ return (struct config_option *)avl_search_lock(&(co->values_index), (avl_t *) &tmp);
}
@@ -144,15 +144,15 @@ int appconfig_section_compare(void *a, void *b) {
else return strcmp(((struct section *)a)->name, ((struct section *)b)->name);
}
-#define appconfig_index_add(root, cfg) (struct section *)avl_insert_lock(&(root)->index, (avl *)(cfg))
-#define appconfig_index_del(root, cfg) (struct section *)avl_remove_lock(&(root)->index, (avl *)(cfg))
+#define appconfig_index_add(root, cfg) (struct section *)avl_insert_lock(&(root)->index, (avl_t *)(cfg))
+#define appconfig_index_del(root, cfg) (struct section *)avl_remove_lock(&(root)->index, (avl_t *)(cfg))
static struct section *appconfig_index_find(struct config *root, const char *name, uint32_t hash) {
struct section tmp;
tmp.hash = (hash)?hash:simple_hash(name);
tmp.name = (char *)name;
- return (struct section *)avl_search_lock(&root->index, (avl *) &tmp);
+ return (struct section *)avl_search_lock(&root->index, (avl_t *) &tmp);
}
diff --git a/libnetdata/config/appconfig.h b/libnetdata/config/appconfig.h
index 9d02e4ada..f405eeb09 100644
--- a/libnetdata/config/appconfig.h
+++ b/libnetdata/config/appconfig.h
@@ -111,7 +111,7 @@
#define CONFIG_VALUE_CHECKED 0x08 // has been checked if the value is different from the default
struct config_option {
- avl avl_node; // the index entry of this entry - this has to be first!
+ avl_t avl_node; // the index entry of this entry - this has to be first!
uint8_t flags;
uint32_t hash; // a simple hash to speed up searching
@@ -124,7 +124,7 @@ struct config_option {
};
struct section {
- avl avl_node; // the index entry of this section - this has to be first!
+ avl_t avl_node; // the index entry of this section - this has to be first!
uint32_t hash; // a simple hash to speed up searching
// we first compare hashes, and only if the hashes are equal we do string comparisons
diff --git a/libnetdata/dictionary/dictionary.c b/libnetdata/dictionary/dictionary.c
index cfcf1fbab..b3dc3f371 100644
--- a/libnetdata/dictionary/dictionary.c
+++ b/libnetdata/dictionary/dictionary.c
@@ -67,7 +67,7 @@ static inline NAME_VALUE *dictionary_name_value_index_find_nolock(DICTIONARY *di
tmp.name = (char *)name;
NETDATA_DICTIONARY_STATS_SEARCHES_PLUS1(dict);
- return (NAME_VALUE *)avl_search(&(dict->values_index), (avl *) &tmp);
+ return (NAME_VALUE *)avl_search(&(dict->values_index), (avl_t *) &tmp);
}
// ----------------------------------------------------------------------------
@@ -95,7 +95,7 @@ static NAME_VALUE *dictionary_name_value_create_nolock(DICTIONARY *dict, const c
// index it
NETDATA_DICTIONARY_STATS_INSERTS_PLUS1(dict);
- if(unlikely(avl_insert(&((dict)->values_index), (avl *)(nv)) != (avl *)nv))
+ if(unlikely(avl_insert(&((dict)->values_index), (avl_t *)(nv)) != (avl_t *)nv))
error("dictionary: INTERNAL ERROR: duplicate insertion to dictionary.");
NETDATA_DICTIONARY_STATS_ENTRIES_PLUS1(dict);
@@ -107,7 +107,7 @@ static void dictionary_name_value_destroy_nolock(DICTIONARY *dict, NAME_VALUE *n
debug(D_DICTIONARY, "Destroying name value entry for name '%s'.", nv->name);
NETDATA_DICTIONARY_STATS_DELETES_PLUS1(dict);
- if(unlikely(avl_remove(&(dict->values_index), (avl *)(nv)) != (avl *)nv))
+ if(unlikely(avl_remove(&(dict->values_index), (avl_t *)(nv)) != (avl_t *)nv))
error("dictionary: INTERNAL ERROR: dictionary invalid removal of node.");
NETDATA_DICTIONARY_STATS_ENTRIES_MINUS1(dict);
@@ -258,7 +258,7 @@ int dictionary_del(DICTIONARY *dict, const char *name) {
// the dictionary is locked for reading while this happens
// do not user other dictionary calls while walking the dictionary - deadlock!
-static int dictionary_walker(avl *a, int (*callback)(void *entry, void *data), void *data) {
+static int dictionary_walker(avl_t *a, int (*callback)(void *entry, void *data), void *data) {
int total = 0, ret = 0;
if(a->avl_link[0]) {
@@ -293,7 +293,7 @@ int dictionary_get_all(DICTIONARY *dict, int (*callback)(void *entry, void *data
return ret;
}
-static int dictionary_walker_name_value(avl *a, int (*callback)(char *name, void *entry, void *data), void *data) {
+static int dictionary_walker_name_value(avl_t *a, int (*callback)(char *name, void *entry, void *data), void *data) {
int total = 0, ret = 0;
if(a->avl_link[0]) {
diff --git a/libnetdata/dictionary/dictionary.h b/libnetdata/dictionary/dictionary.h
index fc24ec2ec..76213887e 100644
--- a/libnetdata/dictionary/dictionary.h
+++ b/libnetdata/dictionary/dictionary.h
@@ -13,7 +13,7 @@ struct dictionary_stats {
};
typedef struct name_value {
- avl avl_node; // the index - this has to be first!
+ avl_t avl_node; // the index - this has to be first!
uint32_t hash; // a simple hash to speed up searching
// we first compare hashes, and only if the hashes are equal we do string comparisons
diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c
index a9ff21f69..8619ae26f 100644
--- a/libnetdata/ebpf/ebpf.c
+++ b/libnetdata/ebpf/ebpf.c
@@ -8,6 +8,9 @@
#include "../libnetdata.h"
+char *ebpf_user_config_dir = CONFIG_DIR;
+char *ebpf_stock_config_dir = LIBCONFIG_DIR;
+
/*
static int clean_kprobe_event(FILE *out, char *filename, char *father_pid, netdata_ebpf_events_t *ptr)
{
@@ -97,7 +100,7 @@ int get_kernel_version(char *out, int size)
return -1;
move = patch;
- while (*version && *version != '\n')
+ while (*version && *version != '\n' && *version != '-')
*move++ = *version++;
*move = '\0';
@@ -182,20 +185,26 @@ static int kernel_is_rejected()
}
char filename[FILENAME_MAX + 1];
- snprintfz(filename, FILENAME_MAX, "%s/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE);
+ snprintfz(filename, FILENAME_MAX, "%s/ebpf.d/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE);
FILE *kernel_reject_list = fopen(filename, "r");
if (!kernel_reject_list) {
- config_dir = getenv("NETDATA_STOCK_CONFIG_DIR");
- if (config_dir == NULL) {
- config_dir = LIBCONFIG_DIR;
- }
-
+ // Keep this to have compatibility with old versions
snprintfz(filename, FILENAME_MAX, "%s/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE);
kernel_reject_list = fopen(filename, "r");
- if (!kernel_reject_list)
- return 0;
+ if (!kernel_reject_list) {
+ config_dir = getenv("NETDATA_STOCK_CONFIG_DIR");
+ if (config_dir == NULL) {
+ config_dir = LIBCONFIG_DIR;
+ }
+
+ snprintfz(filename, FILENAME_MAX, "%s/ebpf.d/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE);
+ kernel_reject_list = fopen(filename, "r");
+
+ if (!kernel_reject_list)
+ return 0;
+ }
}
// Find if the kernel is in the reject list
@@ -246,7 +255,9 @@ char *ebpf_kernel_suffix(int version, int isrh)
else
return "3.10";
} else {
- if (version >= NETDATA_EBPF_KERNEL_5_10)
+ if (version >= NETDATA_EBPF_KERNEL_5_11)
+ return "5.11";
+ else if (version >= NETDATA_EBPF_KERNEL_5_10)
return "5.10";
else if (version >= NETDATA_EBPF_KERNEL_4_17)
return "5.4";
@@ -294,8 +305,10 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char *
if (test < 0 || test > 127)
return NULL;
- snprintf(lpath, 4096, "%s/%s", plugins_dir, lname);
- if (bpf_prog_load(lpath, BPF_PROG_TYPE_KPROBE, obj, &prog_fd)) {
+ snprintf(lpath, 4096, "%s/ebpf.d/%s", plugins_dir, lname);
+ // We are using BPF_PROG_TYPE_UNSPEC instead a specific type for bpf_prog_load to define the type
+ // according the eBPF program loaded
+ if (bpf_prog_load(lpath, BPF_PROG_TYPE_UNSPEC, obj, &prog_fd)) {
em->enabled = CONFIG_BOOLEAN_NO;
info("Cannot load program: %s", lpath);
return NULL;
@@ -322,3 +335,65 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char *
return links;
}
+
+//----------------------------------------------------------------------------------------------------------------------
+
+void ebpf_mount_config_name(char *filename, size_t length, char *path, char *config)
+{
+ snprintf(filename, length, "%s/ebpf.d/%s", path, config);
+}
+
+int ebpf_load_config(struct config *config, char *filename)
+{
+ return appconfig_load(config, filename, 0, NULL);
+}
+
+
+static netdata_run_mode_t ebpf_select_mode(char *mode)
+{
+ if (!strcasecmp(mode, "return"))
+ return MODE_RETURN;
+ else if (!strcasecmp(mode, "dev"))
+ return MODE_DEVMODE;
+
+ return MODE_ENTRY;
+}
+
+void ebpf_update_module_using_config(ebpf_module_t *modules, struct config *cfg)
+{
+ char *mode = appconfig_get(cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_LOAD_MODE, EBPF_CFG_LOAD_MODE_DEFAULT);
+ modules->mode = ebpf_select_mode(mode);
+
+ modules->update_time = (int)appconfig_get_number(cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_UPDATE_EVERY, 1);
+
+ modules->apps_charts = appconfig_get_boolean(cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_APPLICATION,
+ CONFIG_BOOLEAN_YES);
+}
+
+
+/**
+ * Update module
+ *
+ * When this function is called, it will load the configuration file and after this
+ * it updates the global information of ebpf_module.
+ * If the module has specific configuration, this function will load it, but it will not
+ * update the variables.
+ *
+ * @param em the module structure
+ * @param cfg the configuration structure
+ * @param cfg_file the filename to load
+ */
+void ebpf_update_module(ebpf_module_t *em, struct config *cfg, char *cfg_file)
+{
+ char filename[FILENAME_MAX+1];
+ ebpf_mount_config_name(filename, FILENAME_MAX, ebpf_user_config_dir, cfg_file);
+ if (!ebpf_load_config(cfg, filename)) {
+ ebpf_mount_config_name(filename, FILENAME_MAX, ebpf_stock_config_dir, cfg_file);
+ if (!ebpf_load_config(cfg, filename)) {
+ error("Cannot load the ebpf configuration file %s", cfg_file);
+ return;
+ }
+ }
+
+ ebpf_update_module_using_config(em, cfg);
+}
diff --git a/libnetdata/ebpf/ebpf.h b/libnetdata/ebpf/ebpf.h
index d4faccffd..ac3a1a2fc 100644
--- a/libnetdata/ebpf/ebpf.h
+++ b/libnetdata/ebpf/ebpf.h
@@ -8,6 +8,15 @@
#define NETDATA_DEBUGFS "/sys/kernel/debug/tracing/"
+// Config files
+#define EBPF_GLOBAL_SECTION "global"
+#define EBPF_CFG_LOAD_MODE "ebpf load mode"
+#define EBPF_CFG_LOAD_MODE_DEFAULT "entry"
+#define EBPF_CFG_LOAD_MODE_RETURN "return"
+
+#define EBPF_CFG_UPDATE_EVERY "update every"
+#define EBPF_CFG_APPLICATION "apps"
+
/**
* The next magic number is got doing the following math:
* 294960 = 4*65536 + 11*256 + 0
@@ -32,6 +41,13 @@
#define NETDATA_RH_8 2048
/**
+ * Kernel 5.11
+ *
+ * 330240 = 5*65536 + 11*256
+ */
+#define NETDATA_EBPF_KERNEL_5_11 330496
+
+/**
* Kernel 5.10
*
* 330240 = 5*65536 + 10*256
@@ -62,6 +78,9 @@
#define VERSION_STRING_LEN 256
#define EBPF_KERNEL_REJECT_LIST_FILE "ebpf_kernel_reject_list.txt"
+extern char *ebpf_user_config_dir;
+extern char *ebpf_stock_config_dir;
+
typedef struct ebpf_data {
int *map_fd;
@@ -87,6 +106,7 @@ typedef struct ebpf_module {
netdata_run_mode_t mode;
uint32_t thread_id;
int optional;
+ void (*apps_routine)(struct ebpf_module *em, void *ptr);
} ebpf_module_t;
#define NETDATA_MAX_PROBES 64
@@ -102,4 +122,9 @@ extern struct bpf_link **ebpf_load_program(char *plugins_dir,
struct bpf_object **obj,
int *map_fd);
+extern void ebpf_mount_config_name(char *filename, size_t length, char *path, char *config);
+extern int ebpf_load_config(struct config *config, char *filename);
+extern void ebpf_update_module_using_config(ebpf_module_t *modules, struct config *cfg);
+extern void ebpf_update_module(ebpf_module_t *em, struct config *cfg, char *cfg_file);
+
#endif /* NETDATA_EBPF_H */
diff --git a/libnetdata/eval/eval.c b/libnetdata/eval/eval.c
index b53b07039..7ca45882f 100644
--- a/libnetdata/eval/eval.c
+++ b/libnetdata/eval/eval.c
@@ -296,7 +296,7 @@ calculated_number eval_abs(EVAL_EXPRESSION *exp, EVAL_NODE *op, int *error) {
calculated_number n1 = eval_value(exp, &op->ops[0], error);
if(isnan(n1)) return NAN;
if(isinf(n1)) return INFINITY;
- return abs(n1);
+ return ABS(n1);
}
calculated_number eval_if_then_else(EVAL_EXPRESSION *exp, EVAL_NODE *op, int *error) {
if(is_true(eval_value(exp, &op->ops[0], error)))
diff --git a/libnetdata/libnetdata.c b/libnetdata/libnetdata.c
index 325df3f76..6ccb61ede 100644
--- a/libnetdata/libnetdata.c
+++ b/libnetdata/libnetdata.c
@@ -1406,45 +1406,46 @@ void recursive_config_double_dir_load(const char *user_path, const char *stock_p
if (!dir) {
error("CONFIG cannot open stock config directory '%s'.", sdir);
}
- else if (strcmp(udir, sdir)) {
- struct dirent *de = NULL;
- while((de = readdir(dir))) {
- if(de->d_type == DT_DIR || de->d_type == DT_LNK) {
- if( !de->d_name[0] ||
- (de->d_name[0] == '.' && de->d_name[1] == '\0') ||
- (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')
+ else {
+ if (strcmp(udir, sdir)) {
+ struct dirent *de = NULL;
+ while((de = readdir(dir))) {
+ if(de->d_type == DT_DIR || de->d_type == DT_LNK) {
+ if( !de->d_name[0] ||
+ (de->d_name[0] == '.' && de->d_name[1] == '\0') ||
+ (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')
) {
- debug(D_HEALTH, "CONFIG ignoring stock config directory '%s/%s'", sdir, de->d_name);
- continue;
- }
+ debug(D_HEALTH, "CONFIG ignoring stock config directory '%s/%s'", sdir, de->d_name);
+ continue;
+ }
- if(path_is_dir(sdir, de->d_name)) {
- // we recurse in stock subdirectory, only when there is no corresponding
- // user subdirectory - to avoid reading the files twice
+ if(path_is_dir(sdir, de->d_name)) {
+ // we recurse in stock subdirectory, only when there is no corresponding
+ // user subdirectory - to avoid reading the files twice
- if(!path_is_dir(udir, de->d_name))
- recursive_config_double_dir_load(udir, sdir, de->d_name, callback, data, depth + 1);
+ if(!path_is_dir(udir, de->d_name))
+ recursive_config_double_dir_load(udir, sdir, de->d_name, callback, data, depth + 1);
- continue;
+ continue;
+ }
}
- }
- if(de->d_type == DT_UNKNOWN || de->d_type == DT_REG || de->d_type == DT_LNK) {
- size_t len = strlen(de->d_name);
- if(path_is_file(sdir, de->d_name) && !path_is_file(udir, de->d_name) &&
- len > 5 && !strcmp(&de->d_name[len - 5], ".conf")) {
- char *filename = strdupz_path_subpath(sdir, de->d_name);
- debug(D_HEALTH, "CONFIG calling callback for stock file '%s'", filename);
- callback(filename, data);
- freez(filename);
- continue;
+ if(de->d_type == DT_UNKNOWN || de->d_type == DT_REG || de->d_type == DT_LNK) {
+ size_t len = strlen(de->d_name);
+ if(path_is_file(sdir, de->d_name) && !path_is_file(udir, de->d_name) &&
+ len > 5 && !strcmp(&de->d_name[len - 5], ".conf")) {
+ char *filename = strdupz_path_subpath(sdir, de->d_name);
+ debug(D_HEALTH, "CONFIG calling callback for stock file '%s'", filename);
+ callback(filename, data);
+ freez(filename);
+ continue;
+ }
+
}
+ debug(D_HEALTH, "CONFIG ignoring stock-config file '%s/%s' of type %d", udir, de->d_name, (int)de->d_type);
}
-
- debug(D_HEALTH, "CONFIG ignoring stock-config file '%s/%s' of type %d", udir, de->d_name, (int)de->d_type);
}
-
closedir(dir);
}
diff --git a/libnetdata/libnetdata.h b/libnetdata/libnetdata.h
index 50568b5bc..212273870 100644
--- a/libnetdata/libnetdata.h
+++ b/libnetdata/libnetdata.h
@@ -205,11 +205,7 @@ extern "C" {
#define WARNUNUSED
#endif
-#ifdef abs
-#undef abs
-#endif
-#define abs(x) (((x) < 0)? (-(x)) : (x))
-
+#define ABS(x) (((x) < 0)? (-(x)) : (x))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
@@ -291,7 +287,8 @@ extern char *read_by_filename(char *filename, long *file_size);
#endif
#endif
-#define BITS_IN_A_KILOBIT 1000
+#define BITS_IN_A_KILOBIT 1000
+#define KILOBITS_IN_A_MEGABIT 1000
/* misc. */
#define UNUSED(x) (void)(x)
@@ -319,7 +316,7 @@ extern char *netdata_configured_host_prefix;
#include "log/log.h"
#include "procfile/procfile.h"
#include "dictionary/dictionary.h"
-#ifdef HAVE_LIBBPF
+#if defined(HAVE_LIBBPF) && !defined(__cplusplus)
#include "ebpf/ebpf.h"
#endif
#include "eval/eval.h"
diff --git a/libnetdata/tests/test_str2ld.c b/libnetdata/tests/test_str2ld.c
index 9d59f6c0e..01d8677f0 100644
--- a/libnetdata/tests/test_str2ld.c
+++ b/libnetdata/tests/test_str2ld.c
@@ -32,7 +32,7 @@ static void test_str2ld(void **state)
else if (isinf(mine))
assert_true(isinf(sys));
else if (mine != sys)
- assert_false(abs(mine - sys) > 0.000001);
+ assert_false(ABS(mine - sys) > 0.000001);
assert_ptr_equal(e_mine, e_sys);
}