-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathnetdata_common.h
228 lines (184 loc) · 6.37 KB
/
netdata_common.h
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
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef _NETDATA_COMMON_
#define _NETDATA_COMMON_ 1
#include "netdata_defs.h"
struct netdata_error_report_t {
char comm[TASK_COMM_LEN];
__u32 pid;
int type;
int err;
};
static __always_inline void libnetdata_update_u64(__u64 *res, __u64 value)
{
__sync_fetch_and_add(res, value);
if ( (0xFFFFFFFFFFFFFFFF - *res) <= value) {
*res = value;
}
}
static __always_inline void libnetdata_update_s64(__s64 *res, __s64 value)
{
__sync_fetch_and_add(res, value);
}
static __always_inline void libnetdata_update_global(void *tbl, __u32 key, __u64 value)
{
__u64 *res;
res = bpf_map_lookup_elem(tbl, &key);
if (res)
libnetdata_update_u64(res, value) ;
else
bpf_map_update_elem(tbl, &key, &value, BPF_EXIST);
}
static __always_inline void libnetdata_update_sglobal(void *tbl, __u32 key, __s64 value)
{
__s64 *res;
res = bpf_map_lookup_elem(tbl, &key);
if (res)
libnetdata_update_s64(res, value) ;
else
bpf_map_update_elem(tbl, &key, &value, BPF_EXIST);
}
static __always_inline void libnetdata_update_uid_gid(__u32 *uid, __u32 *gid)
{
__u64 uid_gid = bpf_get_current_uid_gid();
*uid = (__u32)uid_gid;
*gid = (__u32)(uid_gid>>32);
}
/**
* The motive we are using log2 to plot instead the raw value is well explained
* inside this paper https://www.fsl.cs.stonybrook.edu/docs/osprof-osdi2006/osprof.pdf
*/
static __always_inline unsigned int libnetdata_log2(unsigned int v)
{
unsigned int r;
unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
shift = (v > 0xF) << 2; v >>= shift; r |= shift;
shift = (v > 0x3) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
return r;
}
static __always_inline unsigned int libnetdata_log2l(__u64 v)
{
unsigned int hi = v >> 32;
if (hi)
return libnetdata_log2(hi) + 32;
else
return libnetdata_log2(v);
}
static __always_inline void libnetdata_update_u32(u32 *res, u32 value)
{
if (!value)
return;
__sync_fetch_and_add(res, value);
if ( (0xFFFFFFFF - *res) <= value) {
*res = value;
}
}
static __always_inline __u32 libnetdata_select_idx(__u64 val, __u32 end)
{
__u32 rlog;
rlog = libnetdata_log2l(val);
if (rlog > end)
rlog = end;
return rlog;
}
// Copied from linux/samples/bpf/tracex1_kern.c
#define _(P) \
({ \
typeof(P) val = 0; \
bpf_probe_read(&val, sizeof(val), &(P)); \
val; \
})
// Copied from linux/samples/bpf/trace_common.h
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0))
#ifdef __x86_64__
#define NETDATA_SYSCALL(SYS) "__x64_sys_" __stringify(SYS)
#elif defined(__s390x__)
#define NETDATA_SYSCALL(SYS) "__s390x_" __stringify(SYS)
#else
#define NETDATA_SYSCALL(SYS) "sys_" __stringify(SYS)
#endif
#else
#define NETDATA_SYSCALL(SYS) "sys_" __stringify(SYS)
#endif
/*
the TP_DATA_LOC_READ_* macros are used for reading from a field that's pointed
to by a __data_loc variable.
FYI, a __data_loc variable is really an int that contains within it the data
needed to get the location of the actual value. these macros do the
transformation needed to get that final location and then read from it.
this code is from iovisor/bcc file src/cc/exports/helpers.h and modified by
Netdata's Agent team for inclusion in Netdata.
*/
#define TP_DATA_LOC_READ_CONST(_dst, _arg, _data_loc, _length) do { \
unsigned short __offset = _data_loc & 0xFFFF; \
bpf_probe_read((void *)_dst, _length, (char *)_arg + __offset); \
} while (0)
#define TP_DATA_LOC_READ(_dst, _arg, _data_loc) do { \
unsigned short __offset = _data_loc & 0xFFFF; \
unsigned short __length = _data_loc >> 16; \
bpf_probe_read((void *)_dst, __length, (char *)_arg + __offset); \
} while (0)
// Get real parent PID
static __always_inline __u32 netdata_get_real_parent_pid()
{
__u32 ppid;
struct task_struct *task, *real_parent;
task = (struct task_struct *)bpf_get_current_task();
real_parent = _(task->real_parent);
bpf_probe_read(&ppid, sizeof(__u32), &real_parent->tgid);
return ppid;
}
static __always_inline __u32 netdata_get_parent_pid()
{
__u32 ppid;
struct task_struct *task, *parent;
task = (struct task_struct *)bpf_get_current_task();
parent = _(task->parent);
bpf_probe_read(&ppid, sizeof(__u32), &parent->tgid);
return ppid;
}
static __always_inline __u32 netdata_get_current_pid(__u32 *tgid)
{
__u32 pid;
__u64 pid_tgid = bpf_get_current_pid_tgid();
pid = (__u32)pid_tgid;
*tgid = (__u32)(pid_tgid>>32);
return pid;
}
static __always_inline __u32 netdata_get_pid(void *ctrl_tbl, __u32 *tgid)
{
__u32 key = NETDATA_CONTROLLER_APPS_LEVEL;
__u64 *level = bpf_map_lookup_elem(ctrl_tbl ,&key);
if (level) {
if (*level == NETDATA_APPS_LEVEL_REAL_PARENT) {
__u64 pid_tgid = bpf_get_current_pid_tgid();
*tgid = (__u32)(pid_tgid>>32);
return netdata_get_real_parent_pid();
} else if (*level == NETDATA_APPS_LEVEL_PARENT) {
__u64 pid_tgid = bpf_get_current_pid_tgid();
*tgid = (__u32)(pid_tgid>>32);
return netdata_get_parent_pid();
} else if (*level == NETDATA_APPS_LEVEL_ALL)
return netdata_get_current_pid(tgid);
else if (*level == NETDATA_APPS_LEVEL_IGNORE) // Ignore PID
return 0;
}
return netdata_get_real_parent_pid();
}
static __always_inline void *netdata_get_pid_structure(__u32 *store_pid, __u32 *store_tgid, void *ctrl_tbl, void *pid_tbl)
{
__u32 pid = netdata_get_pid(ctrl_tbl, store_tgid);
*store_pid = pid;
return bpf_map_lookup_elem(pid_tbl, store_pid);
}
static __always_inline __u32 monitor_apps(void *ctrl_tbl)
{
__u32 apps_key = NETDATA_CONTROLLER_APPS_ENABLED;
__u64 *apps = bpf_map_lookup_elem(ctrl_tbl ,&apps_key);
if (!apps || (apps && *apps == 0))
return 0;
return 1;
}
#endif /* _NETDATA_COMMON_ */