diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-01-26 18:05:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-01-26 18:05:10 +0000 |
commit | 34a0b66bc2d48223748ed1cf5bc1b305c396bd74 (patch) | |
tree | fbd36be86cc6bc4288fe627f2b5beada569848bb /libnetdata | |
parent | Adding upstream version 1.32.1. (diff) | |
download | netdata-34a0b66bc2d48223748ed1cf5bc1b305c396bd74.tar.xz netdata-34a0b66bc2d48223748ed1cf5bc1b305c396bd74.zip |
Adding upstream version 1.33.0.upstream/1.33.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libnetdata')
-rw-r--r-- | libnetdata/Makefile.am | 1 | ||||
-rw-r--r-- | libnetdata/completion/Makefile.am | 4 | ||||
-rw-r--r-- | libnetdata/completion/completion.c | 34 | ||||
-rw-r--r-- | libnetdata/completion/completion.h | 22 | ||||
-rw-r--r-- | libnetdata/ebpf/ebpf.c | 273 | ||||
-rw-r--r-- | libnetdata/ebpf/ebpf.h | 132 | ||||
-rw-r--r-- | libnetdata/libnetdata.c | 1 | ||||
-rw-r--r-- | libnetdata/libnetdata.h | 7 | ||||
-rw-r--r-- | libnetdata/log/log.c | 677 | ||||
-rw-r--r-- | libnetdata/os.c | 19 | ||||
-rw-r--r-- | libnetdata/os.h | 22 |
11 files changed, 734 insertions, 458 deletions
diff --git a/libnetdata/Makefile.am b/libnetdata/Makefile.am index 598b72f5b..e787801c2 100644 --- a/libnetdata/Makefile.am +++ b/libnetdata/Makefile.am @@ -8,6 +8,7 @@ SUBDIRS = \ avl \ buffer \ clocks \ + completion \ config \ dictionary \ ebpf \ diff --git a/libnetdata/completion/Makefile.am b/libnetdata/completion/Makefile.am new file mode 100644 index 000000000..babdcf0df --- /dev/null +++ b/libnetdata/completion/Makefile.am @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +AUTOMAKE_OPTIONS = subdir-objects +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/libnetdata/completion/completion.c b/libnetdata/completion/completion.c new file mode 100644 index 000000000..77818f40d --- /dev/null +++ b/libnetdata/completion/completion.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "completion.h" + +void completion_init(struct completion *p) +{ + p->completed = 0; + fatal_assert(0 == uv_cond_init(&p->cond)); + fatal_assert(0 == uv_mutex_init(&p->mutex)); +} + +void completion_destroy(struct completion *p) +{ + uv_cond_destroy(&p->cond); + uv_mutex_destroy(&p->mutex); +} + +void completion_wait_for(struct completion *p) +{ + uv_mutex_lock(&p->mutex); + while (0 == p->completed) { + uv_cond_wait(&p->cond, &p->mutex); + } + fatal_assert(1 == p->completed); + uv_mutex_unlock(&p->mutex); +} + +void completion_mark_complete(struct completion *p) +{ + uv_mutex_lock(&p->mutex); + p->completed = 1; + uv_mutex_unlock(&p->mutex); + uv_cond_broadcast(&p->cond); +} diff --git a/libnetdata/completion/completion.h b/libnetdata/completion/completion.h new file mode 100644 index 000000000..667360a42 --- /dev/null +++ b/libnetdata/completion/completion.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef NETDATA_COMPLETION_H +#define NETDATA_COMPLETION_H + +#include "../libnetdata.h" + +struct completion { + uv_mutex_t mutex; + uv_cond_t cond; + volatile unsigned completed; +}; + +void completion_init(struct completion *p); + +void completion_destroy(struct completion *p); + +void completion_wait_for(struct completion *p); + +void completion_mark_complete(struct completion *p); + +#endif /* NETDATA_COMPLETION_H */ diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c index 1ccaa7b41..ca40492f1 100644 --- a/libnetdata/ebpf/ebpf.c +++ b/libnetdata/ebpf/ebpf.c @@ -110,9 +110,23 @@ int ebpf_get_kernel_version() *move++ = *version++; *move = '\0'; - return ((int)(str2l(major) * 65536) + (int)(str2l(minor) * 256) + (int)str2l(patch)); + // This new rule is fixing kernel version according the formula: + // KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c))) + // that was extracted from /usr/include/linux/version.h + int ipatch = (int)str2l(patch); + if (ipatch > 255) + ipatch = 255; + + return ((int)(str2l(major) * 65536) + (int)(str2l(minor) * 256) + ipatch); } +/** + * Get RH release + * + * Read Red Hat release from /etc/redhat-release + * + * @return It returns RH release on success and -1 otherwise + */ int get_redhat_release() { char buffer[VERSION_STRING_LEN + 1]; @@ -249,64 +263,189 @@ int has_condition_to_run(int version) //---------------------------------------------------------------------------------------------------------------------- -char *ebpf_kernel_suffix(int version, int isrh) +/** + * Kernel Name + * + * Select kernel name used by eBPF programs + * + * Netdata delivers for users eBPF programs with specific suffixes that represent the kernels they were + * compiled, when we load the eBPF program, the suffix must be the nereast possible of the kernel running. + * + * @param selector select the kernel version. + * + * @return It returns the string to load kernel. + */ +static char *ebpf_select_kernel_name(uint32_t selector) { - if (isrh) { - if (version >= NETDATA_EBPF_KERNEL_4_11) - return "4.18"; - else - return "3.10"; - } else { - 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"; - else if (version >= NETDATA_EBPF_KERNEL_4_15) - return "4.16"; - else if (version >= NETDATA_EBPF_KERNEL_4_11) - return "4.14"; + static char *kernel_names[] = { NETDATA_IDX_STR_V3_10, NETDATA_IDX_STR_V4_14, NETDATA_IDX_STR_V4_16, + NETDATA_IDX_STR_V4_18, NETDATA_IDX_STR_V5_4, NETDATA_IDX_STR_V5_10, + NETDATA_IDX_STR_V5_11, NETDATA_IDX_STR_V5_15 + }; + + return kernel_names[selector]; +} + +/** + * Select Max Index + * + * Select last index that will be tested on host. + * + * @param is_rhf is Red Hat fammily? + * @param kver the kernel version + * + * @return it returns the index to access kernel string. + */ +static int ebpf_select_max_index(int is_rhf, uint32_t kver) +{ + if (is_rhf > 0) { // Is Red Hat family + if (kver >= NETDATA_EBPF_KERNEL_4_11) + return NETDATA_IDX_V4_18; + } else { // Kernels from kernel.org + if (kver >= NETDATA_EBPF_KERNEL_5_15) + return NETDATA_IDX_V5_15; + else if (kver >= NETDATA_EBPF_KERNEL_5_11) + return NETDATA_IDX_V5_11; + else if (kver >= NETDATA_EBPF_KERNEL_5_10) + return NETDATA_IDX_V5_10; + else if (kver >= NETDATA_EBPF_KERNEL_4_17) + return NETDATA_IDX_V5_4; + else if (kver >= NETDATA_EBPF_KERNEL_4_15) + return NETDATA_IDX_V4_16; + else if (kver >= NETDATA_EBPF_KERNEL_4_11) + return NETDATA_IDX_V4_14; } - return NULL; + return NETDATA_IDX_V3_10; +} + +/** + * Select Index + * + * Select index to load data. + * + * @param kernels is the variable with kernel versions. + * @param is_rhf is Red Hat fammily? + * param kver the kernel version + */ +static uint32_t ebpf_select_index(uint32_t kernels, int is_rhf, uint32_t kver) +{ + uint32_t start = ebpf_select_max_index(is_rhf, kver); + uint32_t idx; + + for (idx = start; idx; idx--) { + if (kernels & 1 << idx) + break; + } + + return idx; +} + +/** + * Mount Name + * + * Mount name of eBPF program to be loaded. + * + * Netdata eBPF programs has the following format: + * + * Tnetdata_ebpf_N.V.o + * + * where: + * T - Is the eBPF type. When starts with 'p', this means we are only adding probes, + * and when they start with 'r' we are using retprobes. + * N - The eBPF program name. + * V - The kernel version in string format. + * + * @param out the vector where the name will be stored + * @param path + * @param len the size of the out vector. + * @param kver the kernel version + * @param name the eBPF program name. + * @param is_return is return or entry ? + */ +static void ebpf_mount_name(char *out, size_t len, char *path, uint32_t kver, const char *name, int is_return) +{ + char *version = ebpf_select_kernel_name(kver); + snprintfz(out, len, "%s/ebpf.d/%cnetdata_ebpf_%s.%s.o", + path, + (is_return) ? 'r' : 'p', + name, + version); } //---------------------------------------------------------------------------------------------------------------------- /** - * Update Kernel + * Statistics from targets * - * Update string used to load eBPF programs + * Count the information from targets. * - * @param ks vector to store the value - * @param length available length to store kernel - * @param isrh Is a Red Hat distribution? - * @param version the kernel version + * @param report the output structure + * @param targets vector with information about the eBPF plugin. */ -void ebpf_update_kernel(char *ks, size_t length, int isrh, int version) +static void ebpf_stats_targets(ebpf_plugin_stats_t *report, netdata_ebpf_targets_t *targets) { - char *kernel = ebpf_kernel_suffix(version, (isrh < 0) ? 0 : 1); - size_t len = strlen(kernel); - if (len > length) - len = length - 1; - strncpyz(ks, kernel, len); - ks[len] = '\0'; + if (!targets) { + report->probes = report->tracepoints = report->trampolines = 0; + return; + } + + int i = 0; + while (targets[i].name) { + switch (targets[i].mode) { + case EBPF_LOAD_PROBE: { + report->probes++; + break; + } + case EBPF_LOAD_RETPROBE: { + report->retprobes++; + break; + } + case EBPF_LOAD_TRACEPOINT: { + report->tracepoints++; + break; + } + case EBPF_LOAD_TRAMPOLINE: { + report->trampolines++; + break; + } + } + + i++; + } } -static int select_file(char *name, const char *program, size_t length, int mode, char *kernel_string) +/** + * Update General stats + * + * Update eBPF plugin statistics that has relationship with the thread. + * + * This function must be called with mutex associated to charts is locked. + * + * @param report the output structure + * @param em the structure with information about how the module/thread is working. + */ +void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em) { - int ret = -1; - if (!mode) - ret = snprintf(name, length, "rnetdata_ebpf_%s.%s.o", program, kernel_string); - else if (mode == 1) - ret = snprintf(name, length, "dnetdata_ebpf_%s.%s.o", program, kernel_string); - else if (mode == 2) - ret = snprintf(name, length, "pnetdata_ebpf_%s.%s.o", program, kernel_string); + report->threads++; - return ret; + // It is not necessary to report more information. + if (!em->enabled) + return; + + report->running++; + + // In theory the `else if` is useless, because when this function is called, the module should not stay in + // EBPF_LOAD_PLAY_DICE. We have this additional condition to detect errors from developers. + if (em->load == EBPF_LOAD_LEGACY) + report->legacy++; + else if (em->load == EBPF_LOAD_CORE) + report->core++; + + ebpf_stats_targets(report, em->targets); } +//---------------------------------------------------------------------------------------------------------------------- + void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em) { pid->user_input = em->pid_map_size; @@ -375,18 +514,21 @@ static struct bpf_link **ebpf_attach_programs(struct bpf_object *obj, size_t len struct bpf_link **links = callocz(length , sizeof(struct bpf_link *)); size_t i = 0; struct bpf_program *prog; + ebpf_specify_name_t *w; bpf_object__for_each_program(prog, obj) { - links[i] = bpf_program__attach(prog); - if (libbpf_get_error(links[i]) && names) { + if (names) { const char *name = bpf_program__name(prog); - ebpf_specify_name_t *w = ebpf_find_names(names, name); - if (w) { - enum bpf_prog_type type = bpf_program__get_type(prog); - if (type == BPF_PROG_TYPE_KPROBE) - links[i] = bpf_program__attach_kprobe(prog, w->retprobe, w->optional); - } - } + w = ebpf_find_names(names, name); + } else + w = NULL; + + if (w) { + enum bpf_prog_type type = bpf_program__get_type(prog); + if (type == BPF_PROG_TYPE_KPROBE) + links[i] = bpf_program__attach_kprobe(prog, w->retprobe, w->optional); + } else + links[i] = bpf_program__attach(prog); if (libbpf_get_error(links[i])) { links[i] = NULL; @@ -449,17 +591,28 @@ static void ebpf_update_controller(ebpf_module_t *em, struct bpf_object *obj) } } -struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char *kernel_string, +/** + * Load Program + * + * Load eBPF program into kernel + * + * @param plugins_dir directory where binary are stored + * @param em structure with information about eBPF program we will load. + * @param kver the kernel version according /usr/include/linux/version.h + * @param is_rhf is a kernel from Red Hat Family? + * @param obj structure where we will store object loaded. + * + * @return it returns a link for each target we associated an eBPF program. + */ +struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kver, int is_rhf, struct bpf_object **obj) { char lpath[4096]; - char lname[128]; - int test = select_file(lname, em->thread_name, (size_t)127, em->mode, kernel_string); - if (test < 0 || test > 127) - return NULL; + uint32_t idx = ebpf_select_index(em->kernels, is_rhf, kver); + + ebpf_mount_name(lpath, 4095, plugins_dir, idx, em->thread_name, em->mode); - snprintf(lpath, 4096, "%s/ebpf.d/%s", plugins_dir, lname); *obj = bpf_object__open_file(lpath, NULL); if (libbpf_get_error(obj)) { error("Cannot open BPF object %s", lpath); @@ -480,10 +633,14 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char * size_t count_programs = ebpf_count_programs(*obj); +#ifdef NETDATA_INTERNAL_CHECKS + info("eBPF program %s loaded with success!", lpath); +#endif + return ebpf_attach_programs(*obj, count_programs, em->names); } -static char *ebpf_update_name(char *search) +char *ebpf_find_symbol(char *search) { char filename[FILENAME_MAX + 1]; char *ret = NULL; @@ -521,7 +678,7 @@ void ebpf_update_names(ebpf_specify_name_t *opt, ebpf_module_t *em) size_t i = 0; while (opt[i].program_name) { opt[i].retprobe = (mode == MODE_RETURN); - opt[i].optional = ebpf_update_name(opt[i].function_to_attach); + opt[i].optional = ebpf_find_symbol(opt[i].function_to_attach); i++; } diff --git a/libnetdata/ebpf/ebpf.h b/libnetdata/ebpf/ebpf.h index 73128f529..125299672 100644 --- a/libnetdata/ebpf/ebpf.h +++ b/libnetdata/ebpf/ebpf.h @@ -23,14 +23,6 @@ #define EBPF_CFG_CGROUP "cgroups" /** - * The next magic number is got doing the following math: - * 294960 = 4*65536 + 11*256 + 0 - * - * For more details, please, read /usr/include/linux/version.h - */ -#define NETDATA_MINIMUM_EBPF_KERNEL 264960 - -/** * The RedHat magic number was got doing: * * 1797 = 7*256 + 5 @@ -46,46 +38,63 @@ #define NETDATA_RH_8 2048 /** - * Kernel 5.11 + * Kernel Version * - * 330240 = 5*65536 + 11*256 - */ -#define NETDATA_EBPF_KERNEL_5_11 330496 - -/** - * Kernel 5.10 + * Kernel versions are calculated using the following formula: * - * 330240 = 5*65536 + 10*256 - */ -#define NETDATA_EBPF_KERNEL_5_10 330240 - -/** - * Kernel 5.0 + * VERSION = LINUX_VERSION_MAJOR*65536 + LINUX_VERSION_PATCHLEVEL*256 + LINUX_VERSION_SUBLEVEL * - * 327680 = 5*65536 +256*0 - */ -#define NETDATA_EBPF_KERNEL_5_0 327680 - -/** - * Kernel 4.17 + * Where LINUX_VERSION_MAJOR, LINUX_VERSION_PATCHLEVEL, and LINUX_VERSION_SUBLEVEL are extracted + * from /usr/include/linux/version.h. * - * 266496 = 4*65536 + 17*256 - */ -#define NETDATA_EBPF_KERNEL_4_17 266496 - -/** - * Kernel 4.15 + * LINUX_VERSION_SUBLEVEL has the maximum value 255, but linux can have more SUBLEVELS. * - * 265984 = 4*65536 + 15*256 */ -#define NETDATA_EBPF_KERNEL_4_15 265984 +enum netdata_ebpf_kernel_versions { + NETDATA_EBPF_KERNEL_4_11 = 264960, // 264960 = 4 * 65536 + 15 * 256 + NETDATA_EBPF_KERNEL_4_15 = 265984, // 265984 = 4 * 65536 + 15 * 256 + NETDATA_EBPF_KERNEL_4_17 = 266496, // 266496 = 4 * 65536 + 17 * 256 + NETDATA_EBPF_KERNEL_5_0 = 327680, // 327680 = 5 * 65536 + 0 * 256 + NETDATA_EBPF_KERNEL_5_10 = 330240, // 330240 = 5 * 65536 + 10 * 256 + NETDATA_EBPF_KERNEL_5_11 = 330496, // 330240 = 5 * 65536 + 11 * 256 + NETDATA_EBPF_KERNEL_5_15 = 331520 // 331520 = 5 * 65536 + 15 * 256 +}; + +enum netdata_kernel_flag { + NETDATA_V3_10 = 1 << 0, + NETDATA_V4_14 = 1 << 1, + NETDATA_V4_16 = 1 << 2, + NETDATA_V4_18 = 1 << 3, + NETDATA_V5_4 = 1 << 4, + NETDATA_V5_10 = 1 << 5, + NETDATA_V5_11 = 1 << 6, + NETDATA_V5_15 = 1 << 7 +}; + +enum netdata_kernel_idx { + NETDATA_IDX_V3_10, + NETDATA_IDX_V4_14, + NETDATA_IDX_V4_16, + NETDATA_IDX_V4_18, + NETDATA_IDX_V5_4 , + NETDATA_IDX_V5_10, + NETDATA_IDX_V5_11, + NETDATA_IDX_V5_15 +}; + +#define NETDATA_IDX_STR_V3_10 "3.10" +#define NETDATA_IDX_STR_V4_14 "4.14" +#define NETDATA_IDX_STR_V4_16 "4.16" +#define NETDATA_IDX_STR_V4_18 "4.18" +#define NETDATA_IDX_STR_V5_4 "5.4" +#define NETDATA_IDX_STR_V5_10 "5.10" +#define NETDATA_IDX_STR_V5_11 "5.11" +#define NETDATA_IDX_STR_V5_15 "5.15" /** - * Kernel 4.11 - * - * 264960 = 4*65536 + 15*256 + * Minimum value has relationship with libbpf support. */ -#define NETDATA_EBPF_KERNEL_4_11 264960 +#define NETDATA_MINIMUM_EBPF_KERNEL NETDATA_EBPF_KERNEL_4_11 #define VERSION_STRING_LEN 256 #define EBPF_KERNEL_REJECT_LIST_FILE "ebpf_kernel_reject_list.txt" @@ -148,6 +157,39 @@ typedef struct ebpf_specify_name { bool retprobe; } ebpf_specify_name_t; +typedef enum netdata_ebpf_load_mode { + EBPF_LOAD_LEGACY, // Select legacy mode, this means we will load binaries + EBPF_LOAD_CORE, // When CO-RE is used, it is necessary to use the souce code + + EBPF_LOAD_PLAY_DICE // Take a look on environment and choose the best option +} netdata_ebpf_load_mode_t; + +typedef enum netdata_ebpf_program_loaded { + EBPF_LOAD_PROBE, // Attach probes on targets + EBPF_LOAD_RETPROBE, // Attach retprobes on targets + EBPF_LOAD_TRACEPOINT, // This stores log given description about the errors raised + EBPF_LOAD_TRAMPOLINE, // This attaches kprobe when the function is called +} netdata_ebpf_program_loaded_t; + +typedef struct netdata_ebpf_targets { + char *name; + netdata_ebpf_program_loaded_t mode; +} netdata_ebpf_targets_t; + +typedef struct ebpf_plugin_stats { + // Load options + uint32_t legacy; // Legacy codes + uint32_t core; // CO-RE codes, this means we are using source code compiled. + + uint32_t threads; // Total number of threads + uint32_t running; // total number of threads running + + uint32_t probes; // Number of kprobes loaded + uint32_t retprobes; // Number of kretprobes loaded + uint32_t tracepoints; // Number of tracepoints used + uint32_t trampolines; // Number of trampolines used +} ebpf_plugin_stats_t; + typedef struct ebpf_module { const char *thread_name; const char *config_name; @@ -166,25 +208,27 @@ typedef struct ebpf_module { uint32_t pid_map_size; struct config *cfg; const char *config_file; + uint64_t kernels; + netdata_ebpf_load_mode_t load; + netdata_ebpf_targets_t *targets; } ebpf_module_t; extern int ebpf_get_kernel_version(); extern int get_redhat_release(); extern int has_condition_to_run(int version); extern char *ebpf_kernel_suffix(int version, int isrh); -extern void ebpf_update_kernel(char *ks, size_t length, int isrh, int version); -extern struct bpf_link **ebpf_load_program(char *plugins_dir, - ebpf_module_t *em, - char *kernel_string, - struct bpf_object **obj); +extern struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kver, int is_rhf, + struct bpf_object **obj); extern void ebpf_mount_config_name(char *filename, size_t length, char *path, const char *config); extern int ebpf_load_config(struct config *config, char *filename); extern void ebpf_update_module(ebpf_module_t *em); extern void ebpf_update_names(ebpf_specify_name_t *opt, ebpf_module_t *em); +extern char *ebpf_find_symbol(char *search); extern void ebpf_load_addresses(ebpf_addresses_t *fa, int fd); extern void ebpf_fill_algorithms(int *algorithms, size_t length, int algorithm); extern char **ebpf_fill_histogram_dimension(size_t maximum); +extern void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em); // Histogram #define NETDATA_EBPF_HIST_MAX_BINS 24UL diff --git a/libnetdata/libnetdata.c b/libnetdata/libnetdata.c index eb6fce74f..18d022407 100644 --- a/libnetdata/libnetdata.c +++ b/libnetdata/libnetdata.c @@ -14,7 +14,6 @@ struct rlimit rlimit_nofile = { .rlim_cur = 1024, .rlim_max = 1024 }; int enable_ksm = 1; volatile sig_atomic_t netdata_exit = 0; -const char *os_type = NETDATA_OS_TYPE; const char *program_version = VERSION; // ---------------------------------------------------------------------------- diff --git a/libnetdata/libnetdata.h b/libnetdata/libnetdata.h index b49ab21a0..809cefa01 100644 --- a/libnetdata/libnetdata.h +++ b/libnetdata/libnetdata.h @@ -274,7 +274,6 @@ extern int verify_netdata_host_prefix(); extern int recursively_delete_dir(const char *path, const char *reason); extern volatile sig_atomic_t netdata_exit; -extern const char *os_type; extern const char *program_version; @@ -303,9 +302,14 @@ extern char *find_and_replace(const char *src, const char *find, const char *rep #define KILOBITS_IN_A_MEGABIT 1000 /* misc. */ + #define UNUSED(x) (void)(x) #define error_report(x, args...) do { errno = 0; error(x, ##args); } while(0) +// Taken from linux kernel +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) + + extern void netdata_cleanup_and_exit(int ret) NORETURN; extern void send_statistics(const char *action, const char *action_result, const char *action_data); extern char *netdata_configured_host_prefix; @@ -318,6 +322,7 @@ extern char *netdata_configured_host_prefix; #include "avl/avl.h" #include "inlined.h" #include "clocks/clocks.h" +#include "completion/completion.h" #include "popen/popen.h" #include "simple_pattern/simple_pattern.h" #ifdef ENABLE_HTTPS diff --git a/libnetdata/log/log.c b/libnetdata/log/log.c index 95d3d98d4..90581269d 100644 --- a/libnetdata/log/log.c +++ b/libnetdata/log/log.c @@ -24,10 +24,10 @@ const char *facility_log = NULL; // Log facility(https://tools.ietf.org/html/rfc5424) // // The facilities accepted in the Netdata are in according with the following -// header files for their respective operate system: -// sys/syslog.h (Linux ) -// sys/sys/syslog.h (FreeBSD) -// bsd/sys/syslog.h (darwin-xnu) +// header files for their respective operating system: +// sys/syslog.h (Linux ) +// sys/sys/syslog.h (FreeBSD) +// bsd/sys/syslog.h (darwin-xnu) #define LOG_AUTH_KEY "auth" #define LOG_AUTHPRIV_KEY "authpriv" @@ -71,229 +71,229 @@ const char *facility_log = NULL; static int log_facility_id(const char *facility_name) { - static int - hash_auth = 0, - hash_authpriv = 0, + static int + hash_auth = 0, + hash_authpriv = 0, #ifdef __FreeBSD__ - hash_console = 0, + hash_console = 0, #endif - hash_cron = 0, - hash_daemon = 0, - hash_ftp = 0, + hash_cron = 0, + hash_daemon = 0, + hash_ftp = 0, #ifdef __APPLE__ - hash_install = 0, + hash_install = 0, #endif - hash_kern = 0, - hash_lpr = 0, - hash_mail = 0, -// hash_mark = 0, + hash_kern = 0, + hash_lpr = 0, + hash_mail = 0, +// hash_mark = 0, #ifdef __APPLE__ - hash_netinfo = 0, - hash_ras = 0, - hash_remoteauth = 0, + hash_netinfo = 0, + hash_ras = 0, + hash_remoteauth = 0, #endif - hash_news = 0, + hash_news = 0, #ifdef __FreeBSD__ - hash_ntp = 0, + hash_ntp = 0, #endif - hash_security = 0, - hash_syslog = 0, - hash_user = 0, - hash_uucp = 0, + hash_security = 0, + hash_syslog = 0, + hash_user = 0, + hash_uucp = 0, #ifdef __APPLE__ - hash_launchd = 0, + hash_launchd = 0, #endif - hash_local0 = 0, - hash_local1 = 0, - hash_local2 = 0, - hash_local3 = 0, - hash_local4 = 0, - hash_local5 = 0, - hash_local6 = 0, - hash_local7 = 0; - - if(unlikely(!hash_auth)) - { - hash_auth = simple_hash(LOG_AUTH_KEY); - hash_authpriv = simple_hash(LOG_AUTHPRIV_KEY); + hash_local0 = 0, + hash_local1 = 0, + hash_local2 = 0, + hash_local3 = 0, + hash_local4 = 0, + hash_local5 = 0, + hash_local6 = 0, + hash_local7 = 0; + + if(unlikely(!hash_auth)) + { + hash_auth = simple_hash(LOG_AUTH_KEY); + hash_authpriv = simple_hash(LOG_AUTHPRIV_KEY); #ifdef __FreeBSD__ - hash_console = simple_hash(LOG_CONSOLE_KEY); + hash_console = simple_hash(LOG_CONSOLE_KEY); #endif - hash_cron = simple_hash(LOG_CRON_KEY); - hash_daemon = simple_hash(LOG_DAEMON_KEY); - hash_ftp = simple_hash(LOG_FTP_KEY); + hash_cron = simple_hash(LOG_CRON_KEY); + hash_daemon = simple_hash(LOG_DAEMON_KEY); + hash_ftp = simple_hash(LOG_FTP_KEY); #ifdef __APPLE__ - hash_install = simple_hash(LOG_INSTALL_KEY); + hash_install = simple_hash(LOG_INSTALL_KEY); #endif - hash_kern = simple_hash(LOG_KERN_KEY); - hash_lpr = simple_hash(LOG_LPR_KEY); - hash_mail = simple_hash(LOG_MAIL_KEY); -// hash_mark = simple_uhash(); + hash_kern = simple_hash(LOG_KERN_KEY); + hash_lpr = simple_hash(LOG_LPR_KEY); + hash_mail = simple_hash(LOG_MAIL_KEY); +// hash_mark = simple_uhash(); #ifdef __APPLE__ - hash_netinfo = simple_hash(LOG_NETINFO_KEY); - hash_ras = simple_hash(LOG_RAS_KEY); - hash_remoteauth = simple_hash(LOG_REMOTEAUTH_KEY); + hash_netinfo = simple_hash(LOG_NETINFO_KEY); + hash_ras = simple_hash(LOG_RAS_KEY); + hash_remoteauth = simple_hash(LOG_REMOTEAUTH_KEY); #endif - hash_news = simple_hash(LOG_NEWS_KEY); + hash_news = simple_hash(LOG_NEWS_KEY); #ifdef __FreeBSD__ - hash_ntp = simple_hash(LOG_NTP_KEY); + hash_ntp = simple_hash(LOG_NTP_KEY); #endif - hash_security = simple_hash(LOG_SECURITY_KEY); - hash_syslog = simple_hash(LOG_SYSLOG_KEY); - hash_user = simple_hash(LOG_USER_KEY); - hash_uucp = simple_hash(LOG_UUCP_KEY); + hash_security = simple_hash(LOG_SECURITY_KEY); + hash_syslog = simple_hash(LOG_SYSLOG_KEY); + hash_user = simple_hash(LOG_USER_KEY); + hash_uucp = simple_hash(LOG_UUCP_KEY); #ifdef __APPLE__ - hash_launchd = simple_hash(LOG_LAUNCHD_KEY); + hash_launchd = simple_hash(LOG_LAUNCHD_KEY); #endif - hash_local0 = simple_hash(LOG_LOCAL0_KEY); - hash_local1 = simple_hash(LOG_LOCAL1_KEY); - hash_local2 = simple_hash(LOG_LOCAL2_KEY); - hash_local3 = simple_hash(LOG_LOCAL3_KEY); - hash_local4 = simple_hash(LOG_LOCAL4_KEY); - hash_local5 = simple_hash(LOG_LOCAL5_KEY); - hash_local6 = simple_hash(LOG_LOCAL6_KEY); - hash_local7 = simple_hash(LOG_LOCAL7_KEY); - } - - int hash = simple_hash(facility_name); - if ( hash == hash_auth ) - { - return LOG_AUTH; - } - else if ( hash == hash_authpriv ) - { - return LOG_AUTHPRIV; - } + hash_local0 = simple_hash(LOG_LOCAL0_KEY); + hash_local1 = simple_hash(LOG_LOCAL1_KEY); + hash_local2 = simple_hash(LOG_LOCAL2_KEY); + hash_local3 = simple_hash(LOG_LOCAL3_KEY); + hash_local4 = simple_hash(LOG_LOCAL4_KEY); + hash_local5 = simple_hash(LOG_LOCAL5_KEY); + hash_local6 = simple_hash(LOG_LOCAL6_KEY); + hash_local7 = simple_hash(LOG_LOCAL7_KEY); + } + + int hash = simple_hash(facility_name); + if ( hash == hash_auth ) + { + return LOG_AUTH; + } + else if ( hash == hash_authpriv ) + { + return LOG_AUTHPRIV; + } #ifdef __FreeBSD__ - else if ( hash == hash_console ) - { - return LOG_CONSOLE; - } + else if ( hash == hash_console ) + { + return LOG_CONSOLE; + } #endif - else if ( hash == hash_cron ) - { - return LOG_CRON; - } - else if ( hash == hash_daemon ) - { - return LOG_DAEMON; - } - else if ( hash == hash_ftp ) - { - return LOG_FTP; - } + else if ( hash == hash_cron ) + { + return LOG_CRON; + } + else if ( hash == hash_daemon ) + { + return LOG_DAEMON; + } + else if ( hash == hash_ftp ) + { + return LOG_FTP; + } #ifdef __APPLE__ - else if ( hash == hash_install ) - { - return LOG_INSTALL; - } + else if ( hash == hash_install ) + { + return LOG_INSTALL; + } #endif - else if ( hash == hash_kern ) - { - return LOG_KERN; - } - else if ( hash == hash_lpr ) - { - return LOG_LPR; - } - else if ( hash == hash_mail ) - { - return LOG_MAIL; - } - /* - else if ( hash == hash_mark ) - { - //this is internal for all OS - return INTERNAL_MARK; - } - */ + else if ( hash == hash_kern ) + { + return LOG_KERN; + } + else if ( hash == hash_lpr ) + { + return LOG_LPR; + } + else if ( hash == hash_mail ) + { + return LOG_MAIL; + } + /* + else if ( hash == hash_mark ) + { + //this is internal for all OS + return INTERNAL_MARK; + } + */ #ifdef __APPLE__ - else if ( hash == hash_netinfo ) - { - return LOG_NETINFO; - } - else if ( hash == hash_ras ) - { - return LOG_RAS; - } - else if ( hash == hash_remoteauth ) - { - return LOG_REMOTEAUTH; - } + else if ( hash == hash_netinfo ) + { + return LOG_NETINFO; + } + else if ( hash == hash_ras ) + { + return LOG_RAS; + } + else if ( hash == hash_remoteauth ) + { + return LOG_REMOTEAUTH; + } #endif - else if ( hash == hash_news ) - { - return LOG_NEWS; - } + else if ( hash == hash_news ) + { + return LOG_NEWS; + } #ifdef __FreeBSD__ - else if ( hash == hash_ntp ) - { - return LOG_NTP; - } + else if ( hash == hash_ntp ) + { + return LOG_NTP; + } #endif - else if ( hash == hash_security ) - { - //FreeBSD is the unique that does not consider - //this facility deprecated. We are keeping - //it for other OS while they are kept in their headers. + else if ( hash == hash_security ) + { + //FreeBSD is the unique that does not consider + //this facility deprecated. We are keeping + //it for other OS while they are kept in their headers. #ifdef __FreeBSD__ - return LOG_SECURITY; + return LOG_SECURITY; #else - return LOG_AUTH; + return LOG_AUTH; #endif - } - else if ( hash == hash_syslog ) - { - return LOG_SYSLOG; - } - else if ( hash == hash_user ) - { - return LOG_USER; - } - else if ( hash == hash_uucp ) - { - return LOG_UUCP; - } - else if ( hash == hash_local0 ) - { - return LOG_LOCAL0; - } - else if ( hash == hash_local1 ) - { - return LOG_LOCAL1; - } - else if ( hash == hash_local2 ) - { - return LOG_LOCAL2; - } - else if ( hash == hash_local3 ) - { - return LOG_LOCAL3; - } - else if ( hash == hash_local4 ) - { - return LOG_LOCAL4; - } - else if ( hash == hash_local5 ) - { - return LOG_LOCAL5; - } - else if ( hash == hash_local6 ) - { - return LOG_LOCAL6; - } - else if ( hash == hash_local7 ) - { - return LOG_LOCAL7; - } + } + else if ( hash == hash_syslog ) + { + return LOG_SYSLOG; + } + else if ( hash == hash_user ) + { + return LOG_USER; + } + else if ( hash == hash_uucp ) + { + return LOG_UUCP; + } + else if ( hash == hash_local0 ) + { + return LOG_LOCAL0; + } + else if ( hash == hash_local1 ) + { + return LOG_LOCAL1; + } + else if ( hash == hash_local2 ) + { + return LOG_LOCAL2; + } + else if ( hash == hash_local3 ) + { + return LOG_LOCAL3; + } + else if ( hash == hash_local4 ) + { + return LOG_LOCAL4; + } + else if ( hash == hash_local5 ) + { + return LOG_LOCAL5; + } + else if ( hash == hash_local6 ) + { + return LOG_LOCAL6; + } + else if ( hash == hash_local7 ) + { + return LOG_LOCAL7; + } #ifdef __APPLE__ - else if ( hash == hash_launchd ) - { - return LOG_LAUNCHD; - } + else if ( hash == hash_launchd ) + { + return LOG_LAUNCHD; + } #endif - return LOG_DAEMON; + return LOG_DAEMON; } //we do not need to use this now, but I already created this function to be @@ -301,135 +301,135 @@ static int log_facility_id(const char *facility_name) /* char *log_facility_name(int code) { - char *defvalue = { "daemon" }; - switch(code) - { - case LOG_AUTH: - { - return "auth"; - } - case LOG_AUTHPRIV: - { - return "authpriv"; - } + char *defvalue = { "daemon" }; + switch(code) + { + case LOG_AUTH: + { + return "auth"; + } + case LOG_AUTHPRIV: + { + return "authpriv"; + } #ifdef __FreeBSD__ - case LOG_CONSOLE: - { - return "console"; - } + case LOG_CONSOLE: + { + return "console"; + } #endif - case LOG_CRON: - { - return "cron"; - } - case LOG_DAEMON: - { - return defvalue; - } - case LOG_FTP: - { - return "ftp"; - } + case LOG_CRON: + { + return "cron"; + } + case LOG_DAEMON: + { + return defvalue; + } + case LOG_FTP: + { + return "ftp"; + } #ifdef __APPLE__ - case LOG_INSTALL: - { - return "install"; - } + case LOG_INSTALL: + { + return "install"; + } #endif - case LOG_KERN: - { - return "kern"; - } - case LOG_LPR: - { - return "lpr"; - } - case LOG_MAIL: - { - return "mail"; - } + case LOG_KERN: + { + return "kern"; + } + case LOG_LPR: + { + return "lpr"; + } + case LOG_MAIL: + { + return "mail"; + } #ifdef __APPLE__ - case LOG_NETINFO: - { - return "netinfo" ; - } - case LOG_RAS: - { - return "ras"; - } - case LOG_REMOTEAUTH: - { - return "remoteauth"; - } + case LOG_NETINFO: + { + return "netinfo" ; + } + case LOG_RAS: + { + return "ras"; + } + case LOG_REMOTEAUTH: + { + return "remoteauth"; + } #endif - case LOG_NEWS: - { - return "news"; - } + case LOG_NEWS: + { + return "news"; + } #ifdef __FreeBSD__ - case LOG_NTP: - { - return "ntp" ; - } - case LOG_SECURITY: - { - return "security"; - } + case LOG_NTP: + { + return "ntp" ; + } + case LOG_SECURITY: + { + return "security"; + } #endif - case LOG_SYSLOG: - { - return "syslog"; - } - case LOG_USER: - { - return "user"; - } - case LOG_UUCP: - { - return "uucp"; - } - case LOG_LOCAL0: - { - return "local0"; - } - case LOG_LOCAL1: - { - return "local1"; - } - case LOG_LOCAL2: - { - return "local2"; - } - case LOG_LOCAL3: - { - return "local3"; - } - case LOG_LOCAL4: - { - return "local4" ; - } - case LOG_LOCAL5: - { - return "local5"; - } - case LOG_LOCAL6: - { - return "local6"; - } - case LOG_LOCAL7: - { - return "local7" ; - } + case LOG_SYSLOG: + { + return "syslog"; + } + case LOG_USER: + { + return "user"; + } + case LOG_UUCP: + { + return "uucp"; + } + case LOG_LOCAL0: + { + return "local0"; + } + case LOG_LOCAL1: + { + return "local1"; + } + case LOG_LOCAL2: + { + return "local2"; + } + case LOG_LOCAL3: + { + return "local3"; + } + case LOG_LOCAL4: + { + return "local4" ; + } + case LOG_LOCAL5: + { + return "local5"; + } + case LOG_LOCAL6: + { + return "local6"; + } + case LOG_LOCAL7: + { + return "local7" ; + } #ifdef __APPLE__ - case LOG_LAUNCHD: - { - return "launchd"; - } + case LOG_LAUNCHD: + { + return "launchd"; + } #endif - } + } - return defvalue; -} + return defvalue; +} */ // ---------------------------------------------------------------------------- @@ -486,7 +486,7 @@ static FILE *open_log_file(int fd, FILE *fp, const char *filename, int *enabled_ filename = "/dev/null"; devnull = 1; - syslog_init(); + syslog_init(); if(enabled_syslog) *enabled_syslog = 1; } else if(enabled_syslog) *enabled_syslog = 0; @@ -607,13 +607,15 @@ int error_log_limit(int reset) { if(prevented) { char date[LOG_DATE_LENGTH]; log_date(date, LOG_DATE_LENGTH); - fprintf(stderr, "%s: %s LOG FLOOD PROTECTION reset for process '%s' (prevented %lu logs in the last %ld seconds).\n" - , date - , program_name - , program_name - , prevented - , now - start - ); + fprintf( + stderr, + "%s: %s LOG FLOOD PROTECTION reset for process '%s' " + "(prevented %lu logs in the last %"PRId64" seconds).\n", + date, + program_name, + program_name, + prevented, + (int64_t)(now - start)); } start = now; @@ -628,13 +630,15 @@ int error_log_limit(int reset) { if(prevented) { char date[LOG_DATE_LENGTH]; log_date(date, LOG_DATE_LENGTH); - fprintf(stderr, "%s: %s LOG FLOOD PROTECTION resuming logging from process '%s' (prevented %lu logs in the last %ld seconds).\n" - , date - , program_name - , program_name - , prevented - , error_log_throttle_period - ); + fprintf( + stderr, + "%s: %s LOG FLOOD PROTECTION resuming logging from process '%s' " + "(prevented %lu logs in the last %"PRId64" seconds).\n", + date, + program_name, + program_name, + prevented, + (int64_t)error_log_throttle_period); } // restart the period accounting @@ -650,15 +654,18 @@ int error_log_limit(int reset) { if(!prevented) { char date[LOG_DATE_LENGTH]; log_date(date, LOG_DATE_LENGTH); - fprintf(stderr, "%s: %s LOG FLOOD PROTECTION too many logs (%lu logs in %ld seconds, threshold is set to %lu logs in %ld seconds). Preventing more logs from process '%s' for %ld seconds.\n" - , date - , program_name - , counter - , now - start - , error_log_errors_per_period - , error_log_throttle_period - , program_name - , start + error_log_throttle_period - now); + fprintf( + stderr, + "%s: %s LOG FLOOD PROTECTION too many logs (%lu logs in %"PRId64" seconds, threshold is set to %lu logs " + "in %"PRId64" seconds). Preventing more logs from process '%s' for %"PRId64" seconds.\n", + date, + program_name, + counter, + (int64_t)(now - start), + error_log_errors_per_period, + (int64_t)error_log_throttle_period, + program_name, + (int64_t)(start + error_log_throttle_period - now)); } prevented++; diff --git a/libnetdata/os.c b/libnetdata/os.c index 4271a917c..196288a6a 100644 --- a/libnetdata/os.c +++ b/libnetdata/os.c @@ -123,7 +123,9 @@ void get_system_HZ(void) { // ===================================================================================================================== // FreeBSD -#if (TARGET_OS == OS_FREEBSD) +#if __FreeBSD__ + +const char *os_type = "freebsd"; int getsysctl_by_name(const char *name, void *ptr, size_t len) { size_t nlen = len; @@ -198,7 +200,9 @@ int getsysctl_mib(const char *name, int *mib, size_t len) { // ===================================================================================================================== // MacOS -#if (TARGET_OS == OS_MACOS) +#if __APPLE__ + +const char *os_type = "macos"; int getsysctl_by_name(const char *name, void *ptr, size_t len) { size_t nlen = len; @@ -214,4 +218,13 @@ int getsysctl_by_name(const char *name, void *ptr, size_t len) { return 0; } -#endif // (TARGET_OS == OS_MACOS) +#endif + +// ===================================================================================================================== +// Linux + +#if __linux__ + +const char *os_type = "linux"; + +#endif diff --git a/libnetdata/os.h b/libnetdata/os.h index 2494174bc..7872f82b9 100644 --- a/libnetdata/os.h +++ b/libnetdata/os.h @@ -6,15 +6,9 @@ #include "libnetdata.h" // ===================================================================================================================== -// Linux - -#if (TARGET_OS == OS_LINUX) - - -// ===================================================================================================================== // FreeBSD -#elif (TARGET_OS == OS_FREEBSD) +#if __FreeBSD__ #include <sys/sysctl.h> @@ -35,28 +29,24 @@ extern int getsysctl_simple(const char *name, int *mib, size_t miblen, void *ptr extern int getsysctl(const char *name, int *mib, size_t miblen, void *ptr, size_t *len); +#endif // ===================================================================================================================== // MacOS -#elif (TARGET_OS == OS_MACOS) +#if __APPLE__ #include <sys/sysctl.h> #define GETSYSCTL_BY_NAME(name, var) getsysctl_by_name(name, &(var), sizeof(var)) extern int getsysctl_by_name(const char *name, void *ptr, size_t len); - -// ===================================================================================================================== -// unknown O/S - -#else -#error unsupported operating system #endif - // ===================================================================================================================== -// common for all O/S +// common defs for Apple/FreeBSD/Linux + +extern const char *os_type; extern int processors; extern long get_system_cpus(void); |