summaryrefslogtreecommitdiffstats
path: root/src/collectors/ebpf.plugin/ebpf.h
blob: 6fc42b3e415047c1b1bd3c2ee191ba58fb8b5a02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef NETDATA_COLLECTOR_EBPF_H
#define NETDATA_COLLECTOR_EBPF_H 1

#ifndef __FreeBSD__
#include <linux/perf_event.h>
#endif
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>

#include <fcntl.h>
#include <ctype.h>
#include <dirent.h>

// From libnetdata.h
#include "libnetdata/threads/threads.h"
#include "libnetdata/locks/locks.h"
#include "libnetdata/avl/avl.h"
#include "libnetdata/clocks/clocks.h"
#include "libnetdata/config/appconfig.h"
#include "libnetdata/ebpf/ebpf.h"
#include "libnetdata/procfile/procfile.h"
#include "collectors/cgroups.plugin/sys_fs_cgroup.h"
#include "daemon/main.h"

#include "ebpf_apps.h"
#include "ebpf_functions.h"
#include "ebpf_cgroup.h"

#define NETDATA_EBPF_OLD_CONFIG_FILE "ebpf.conf"
#define NETDATA_EBPF_CONFIG_FILE "ebpf.d.conf"

extern size_t ebpf_hash_table_pids_count;
#ifdef LIBBPF_MAJOR_VERSION // BTF code
#include "cachestat.skel.h"
#include "dc.skel.h"
#include "disk.skel.h"
#include "fd.skel.h"
#include "filesystem.skel.h"
#include "hardirq.skel.h"
#include "mdflush.skel.h"
#include "mount.skel.h"
#include "shm.skel.h"
#include "sync.skel.h"
#include "socket.skel.h"
#include "swap.skel.h"
#include "vfs.skel.h"

extern struct cachestat_bpf *cachestat_bpf_obj;
extern struct dc_bpf *dc_bpf_obj;
extern struct disk_bpf *disk_bpf_obj;
extern struct fd_bpf *fd_bpf_obj;
extern struct hardirq_bpf *hardirq_bpf_obj;
extern struct mount_bpf *mount_bpf_obj;
extern struct mdflush_bpf *mdflush_bpf_obj;
extern struct shm_bpf *shm_bpf_obj;
extern struct socket_bpf *socket_bpf_obj;
extern struct swap_bpf *bpf_obj;
extern struct vfs_bpf *vfs_bpf_obj;
#endif

typedef struct netdata_syscall_stat {
    unsigned long bytes;               // total number of bytes
    uint64_t call;                     // total number of calls
    uint64_t ecall;                    // number of calls that returned error
    struct netdata_syscall_stat *next; // Link list
} netdata_syscall_stat_t;

typedef struct netdata_publish_syscall {
    char *dimension;
    char *name;
    char *algorithm;
    unsigned long nbyte;
    unsigned long pbyte;
    uint64_t ncall;
    uint64_t pcall;
    uint64_t nerr;
    uint64_t perr;
    struct netdata_publish_syscall *next;
} netdata_publish_syscall_t;

typedef struct netdata_publish_vfs_common {
    long write;
    long read;

    long running;
    long zombie;
} netdata_publish_vfs_common_t;

typedef struct netdata_error_report {
    char comm[16];
    __u32 pid;

    int type;
    int err;
} netdata_error_report_t;

typedef struct netdata_ebpf_judy_pid {
    ARAL *pid_table;

    // Index for PIDs
    struct {                            // support for multiple indexing engines
        Pvoid_t JudyLArray;            // the hash table
        RW_SPINLOCK rw_spinlock;        // protect the index
    } index;
} netdata_ebpf_judy_pid_t;

typedef struct netdata_ebpf_judy_pid_stats {
    char *cmdline;

    // Index for Socket timestamp
    struct {                            // support for multiple indexing engines
        Pvoid_t JudyLArray;            // the hash table
        RW_SPINLOCK rw_spinlock;        // protect the index
    } socket_stats;
} netdata_ebpf_judy_pid_stats_t;

extern ebpf_module_t ebpf_modules[];

typedef struct ebpf_tracepoint {
    bool enabled;
    char *class;
    char *event;
} ebpf_tracepoint_t;

// Copied from musl header
#ifndef offsetof
#if __GNUC__ > 3
#define offsetof(type, member) __builtin_offsetof(type, member)
#else
#define offsetof(type, member) ((size_t)((char *)&(((type *)0)->member) - (char *)0))
#endif
#endif

// Messages
#define NETDATA_EBPF_DEFAULT_FNT_NOT_FOUND "Cannot find the necessary functions to monitor"

// Chart definitions
#define NETDATA_EBPF_FAMILY "ebpf"
#define NETDATA_EBPF_IP_FAMILY "ip"
#define NETDATA_FILESYSTEM_FAMILY "filesystem"
#define NETDATA_EBPF_MOUNT_GLOBAL_FAMILY "mount_points"
#define NETDATA_EBPF_CHART_TYPE_LINE "line"
#define NETDATA_EBPF_CHART_TYPE_STACKED "stacked"
#define NETDATA_EBPF_MEMORY_GROUP "mem"
#define NETDATA_EBPF_SYSTEM_GROUP "system"
#define NETDATA_SYSTEM_SWAP_SUBMENU "swap"
#define NETDATA_SYSTEM_IPC_SHM_SUBMENU "ipc shared memory"
#define NETDATA_MONITORING_FAMILY "netdata"

// Statistics charts
#define NETDATA_EBPF_THREADS "ebpf_threads"
#define NETDATA_EBPF_LIFE_TIME "ebpf_life_time"
#define NETDATA_EBPF_LOAD_METHOD "ebpf_load_methods"
#define NETDATA_EBPF_KERNEL_MEMORY "ebpf_kernel_memory"
#define NETDATA_EBPF_HASH_TABLES_LOADED "ebpf_hash_tables_count"
#define NETDATA_EBPF_HASH_TABLES_PER_CORE "ebpf_hash_tables_per_core"
#define NETDATA_EBPF_HASH_TABLES_GLOBAL_ELEMENTS "ebpf_hash_tables_global_elements"
#define NETDATA_EBPF_HASH_TABLES_INSERT_PID_ELEMENTS "ebpf_hash_tables_insert_pid_elements"
#define NETDATA_EBPF_HASH_TABLES_REMOVE_PID_ELEMENTS "ebpf_hash_tables_remove_pid_elements"

// Log file
#define NETDATA_DEVELOPER_LOG_FILE "developer.log"

// Maximum number of processors monitored on perf events
#define NETDATA_MAX_PROCESSOR 512

// Kernel versions calculated with the formula:
// R = MAJOR*65536 + MINOR*256 + PATCH
#define NETDATA_KERNEL_V5_3 328448
#define NETDATA_KERNEL_V4_15 265984

#define EBPF_SYS_CLONE_IDX 11
#define EBPF_MAX_MAPS 32

#define EBPF_DEFAULT_UPDATE_EVERY 10

enum ebpf_algorithms_list {
    NETDATA_EBPF_ABSOLUTE_IDX,
    NETDATA_EBPF_INCREMENTAL_IDX
};

// Threads
void *ebpf_process_thread(void *ptr);
void *ebpf_socket_thread(void *ptr);

// Common variables
extern pthread_mutex_t lock;
extern pthread_mutex_t ebpf_exit_cleanup;
extern int ebpf_nprocs;
extern int running_on_kernel;
extern int isrh;
extern char *ebpf_plugin_dir;
extern int process_pid_fd;

extern pthread_mutex_t collect_data_mutex;

// Common functions
void ebpf_global_labels(netdata_syscall_stat_t *is,
                               netdata_publish_syscall_t *pio,
                               char **dim,
                               char **name,
                               int *algorithm,
                               int end);

void ebpf_write_chart_cmd(char *type,
                                 char *id,
                                 char *suffix,
                                 char *title,
                                 char *units,
                                 char *family,
                                 char *charttype,
                                 char *context,
                                 int order,
                                 int update_every,
                                 char *module);

void ebpf_write_global_dimension(char *name, char *id, char *algorithm);

void ebpf_create_global_dimension(void *ptr, int end);

void ebpf_create_chart(char *type,
                              char *id,
                              char *title,
                              char *units,
                              char *family,
                              char *context,
                              char *charttype,
                              int order,
                              void (*ncd)(void *, int),
                              void *move,
                              int end,
                              int update_every,
                              char *module);

void write_chart_dimension(char *dim, long long value);

void write_count_chart(char *name, char *family, netdata_publish_syscall_t *move, uint32_t end);

void write_err_chart(char *name, char *family, netdata_publish_syscall_t *move, int end);

void write_io_chart(char *chart, char *family, char *dwrite, long long vwrite,
                           char *dread, long long vread);

/**
 * Create Chart labels
 *
 * @param name    the label name.
 * @param value   the label value.
 * @param origin  the labeel source.
 */
static inline void ebpf_create_chart_labels(char *name, char *value, int source)
{
    fprintf(stdout, "CLABEL '%s' '%s' %d\n", name, value, source);
}

/**
 * Commit label
 *
 * Write commit label to stdout
 */
static inline void ebpf_commit_label()
{
    fprintf(stdout, "CLABEL_COMMIT\n");
}

/**
 * Write begin command on standard output
 *
 * @param family the chart family name
 * @param name   the chart name
 * @param metric the chart suffix (used with apps and cgroups)
 */
static inline void ebpf_write_begin_chart(char *family, char *name, char *metric)
{
    printf("BEGIN %s.%s%s\n", family, name, metric);
}

/**
 * Write END command on stdout.
 */
static inline void ebpf_write_end_chart()
{
    printf("END\n");
}

int ebpf_enable_tracepoint(ebpf_tracepoint_t *tp);
int ebpf_disable_tracepoint(ebpf_tracepoint_t *tp);
uint32_t ebpf_enable_tracepoints(ebpf_tracepoint_t *tps);

void ebpf_pid_file(char *filename, size_t length);

#define EBPF_PROGRAMS_SECTION "ebpf programs"

#define EBPF_COMMON_UNITS_PERCENTAGE "%"
#define EBPF_COMMON_UNITS_CALLS_PER_SEC "calls/s"
#define EBPF_COMMON_UNITS_CALLS "calls"
#define EBPF_COMMON_UNITS_MILLISECONDS "milliseconds"

#define EBPF_CHART_ALGORITHM_ABSOLUTE "absolute"
#define EBPF_CHART_ALGORITHM_INCREMENTAL "incremental"

// Common variables
extern int debug_enabled;
extern struct ebpf_pid_stat *ebpf_root_of_pids;
extern ebpf_cgroup_target_t *ebpf_cgroup_pids;
extern char *ebpf_algorithms[];
extern struct config collector_config;
extern netdata_ebpf_cgroup_shm_t shm_ebpf_cgroup;
extern int shm_fd_ebpf_cgroup;
extern sem_t *shm_sem_ebpf_cgroup;
extern pthread_mutex_t mutex_cgroup_shm;
extern size_t ebpf_all_pids_count;
extern ebpf_plugin_stats_t plugin_statistics;
#ifdef LIBBPF_MAJOR_VERSION
extern struct btf *default_btf;
#else
extern void *default_btf;
#endif

// Socket functions and variables
// Common functions
void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr);
void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr);
void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *root);
void ebpf_one_dimension_write_charts(char *family, char *chart, char *dim, long long v1);
collected_number get_value_from_structure(char *basis, size_t offset);
void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em);
void ebpf_write_chart_obsolete(char *type, char *id, char *suffix, char *title, char *units, char *family,
                                      char *charttype, char *context, int order, int update_every);
void write_histogram_chart(char *family, char *name, const netdata_idx_t *hist, char **dimensions, uint32_t end);
void ebpf_update_disabled_plugin_stats(ebpf_module_t *em);
ARAL *ebpf_allocate_pid_aral(char *name, size_t size);
void ebpf_unload_legacy_code(struct bpf_object *objects, struct bpf_link **probe_links);

void ebpf_read_global_table_stats(netdata_idx_t *stats, netdata_idx_t *values, int map_fd,
                                  int maps_per_core, uint32_t begin, uint32_t end);
void **ebpf_judy_insert_unsafe(PPvoid_t arr, Word_t key);
netdata_ebpf_judy_pid_stats_t *ebpf_get_pid_from_judy_unsafe(PPvoid_t judy_array, uint32_t pid);

void parse_network_viewer_section(struct config *cfg);
void ebpf_clean_ip_structure(ebpf_network_viewer_ip_list_t **clean);
void ebpf_clean_port_structure(ebpf_network_viewer_port_list_t **clean);
void ebpf_read_local_addresses_unsafe();

extern ebpf_filesystem_partitions_t localfs[];
extern ebpf_sync_syscalls_t local_syscalls[];
extern bool ebpf_plugin_exit;
extern uint64_t collect_pids;

static inline bool ebpf_plugin_stop(void) {
    return ebpf_plugin_exit || nd_thread_signaled_to_cancel();
}

void ebpf_stop_threads(int sig);
extern netdata_ebpf_judy_pid_t ebpf_judy_pid;

#define EBPF_MAX_SYNCHRONIZATION_TIME 300

#endif /* NETDATA_COLLECTOR_EBPF_H */