convert nfacct to linked-list instead of array
Costa Tsaousis (ktsaou) committed
Mar 17, 2017 at 01:36 UTC
518fb596709b39a374820471cb146f481f0b8340
1 file changed
+57
-70
src/plugin_nfacct.c
+57
-70
@@ -4,8 +4,8 @@
4
#include <libmnl/libmnl.h>
5
#include <libnetfilter_acct/libnetfilter_acct.h>
6
7
-struct mynfacct {
8
- const char *name;
7
+struct nfacct_data {
8
+ char *name;
9
uint32_t hash;
10
11
uint64_t pkts;
@@ -15,75 +15,58 @@ struct mynfacct {
15
RRDDIM *rd_packets;
16
17
int updated;
18
-};
18
20
-struct nfacct_list {
21
- int size;
22
- int len;
23
- struct mynfacct data[];
24
-} *nfacct_list = NULL;
19
+ struct nfacct_data *next;
20
+};
21
26
-static inline void nfacct_list_grow() {
27
- if(!nfacct_list || nfacct_list->len == nfacct_list->size) {
28
- int size = (nfacct_list) ? nfacct_list->size : 0;
29
- int len = (nfacct_list) ? nfacct_list->len : 0;
30
- size++;
22
+static struct nfacct_list {
23
+ struct nfacct *nfacct_buffer;
24
+ struct nfacct_data *nfacct_metrics;
25
+} nfacct_root = {
26
+ .nfacct_buffer = NULL,
27
+ .nfacct_metrics = NULL
28
+};
29
32
- info("nfacct.plugin: increasing nfacct_list to size %d", size);
30
+static inline struct nfacct_data *nfacct_data_get(const char *name, uint32_t hash) {
31
+ struct nfacct_data *d = NULL, *last = NULL;
32
+ for(d = nfacct_root.nfacct_metrics; d ; last = d, d = d->next) {
33
+ if(unlikely(d->hash == hash && !strcmp(d->name, name)))
34
+ return d;
35
+ }
36
34
- nfacct_list = reallocz(nfacct_list, sizeof(struct nfacct_list) + (sizeof(struct mynfacct) * size));
35
- memset(&nfacct_list->data[len], 0, sizeof(struct mynfacct));
37
+ d = callocz(1, sizeof(struct nfacct_data));
38
+ d->name = strdupz(name);
39
+ d->hash = hash;
40
37
- nfacct_list->size = size;
38
- nfacct_list->len = len;
41
+ if(!last) {
42
+ d->next = nfacct_root.nfacct_metrics;
43
+ nfacct_root.nfacct_metrics = d;
44
}
45
+ else {
46
+ d->next = last->next;
47
+ last->next = d;
48
+ }
49
+
50
+ return d;
51
}
52
53
static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
54
(void)data;
55
45
- static struct nfacct *nfacct = NULL;
46
-
47
- if(unlikely(!nfacct)) {
48
- nfacct = nfacct_alloc();
49
- if(!nfacct) {
50
- error("nfacct.plugin: nfacct_alloc() failed.");
51
- return MNL_CB_OK;
52
- }
53
-
54
- if(unlikely(!nfacct_list))
55
- nfacct_list_grow();
56
- }
57
-
58
- if(nfacct_nlmsg_parse_payload(nlh, nfacct) < 0) {
56
+ if(nfacct_nlmsg_parse_payload(nlh, nfacct_root.nfacct_buffer) < 0) {
57
error("nfacct.plugin: nfacct_nlmsg_parse_payload() failed.");
58
return MNL_CB_OK;
59
}
60
63
- const char *name = nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME);
61
+ const char *name = nfacct_attr_get_str(nfacct_root.nfacct_buffer, NFACCT_ATTR_NAME);
62
uint32_t hash = simple_hash(name);
63
66
- int i;
67
- struct mynfacct *mynfacct = NULL;
68
- for(i = 0; i < nfacct_list->len; i++) {
69
- if(nfacct_list->data[i].hash == hash && !strcmp(nfacct_list->data[i].name, name)) {
70
- mynfacct = &nfacct_list->data[i];
71
- break;
72
- }
73
- }
74
-
75
- if(!mynfacct) {
76
- nfacct_list_grow();
77
- mynfacct = &nfacct_list->data[nfacct_list->len++];
78
- mynfacct->name = name;
79
- mynfacct->hash = hash;
80
- }
64
+ struct nfacct_data *d = nfacct_data_get(name, hash);
65
82
- mynfacct->pkts = nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS);
83
- mynfacct->bytes = nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES);
84
- mynfacct->updated = 1;
66
+ d->pkts = nfacct_attr_get_u64(nfacct_root.nfacct_buffer, NFACCT_ATTR_PKTS);
67
+ d->bytes = nfacct_attr_get_u64(nfacct_root.nfacct_buffer, NFACCT_ATTR_BYTES);
68
+ d->updated = 1;
69
86
- nfacct_list->len++;
70
return MNL_CB_OK;
71
}
72
@@ -98,6 +81,10 @@ void *nfacct_main(void *ptr) {
81
if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
82
error("nfacct.plugin: Cannot set pthread cancel state to ENABLE.");
83
84
+ nfacct_root.nfacct_buffer = nfacct_alloc();
85
+ if(!nfacct_root.nfacct_buffer)
86
+ fatal("nfacct.plugin: nfacct_alloc() failed.");
87
+
88
char buf[MNL_SOCKET_BUFFER_SIZE];
89
struct mnl_socket *nl = NULL;
90
struct nlmsghdr *nlh = NULL;
@@ -161,8 +148,8 @@ void *nfacct_main(void *ptr) {
148
149
// --------------------------------------------------------------------
150
164
- if(nfacct_list && nfacct_list->len) {
165
- int i;
151
+ if(nfacct_root.nfacct_metrics) {
152
+ struct nfacct_data *d;
153
154
if(!st_packets) {
155
st_packets = rrdset_create_localhost(
@@ -180,12 +167,12 @@ void *nfacct_main(void *ptr) {
167
}
168
else rrdset_next(st_packets);
169
183
- for(i = 0; i < nfacct_list->len ; i++) {
184
- if(nfacct_list->data[i].updated) {
185
- if(unlikely(!nfacct_list->data[i].rd_packets))
186
- nfacct_list->data[i].rd_packets = rrddim_add(
170
+ for(d = nfacct_root.nfacct_metrics; d ; d = d->next) {
171
+ if(likely(d->updated)) {
172
+ if(unlikely(!d->rd_packets))
173
+ d->rd_packets = rrddim_add(
174
st_packets
188
- , nfacct_list->data[i].name
175
+ , d->name
176
, NULL
177
, 1
178
, update_every
@@ -194,8 +181,8 @@ void *nfacct_main(void *ptr) {
181
182
rrddim_set_by_pointer(
183
st_packets
197
- , nfacct_list->data[i].rd_packets
198
- , (collected_number)nfacct_list->data[i].pkts
184
+ , d->rd_packets
185
+ , (collected_number)d->pkts
186
);
187
}
188
}
@@ -221,12 +208,12 @@ void *nfacct_main(void *ptr) {
208
}
209
else rrdset_next(st_bytes);
210
224
- for(i = 0; i < nfacct_list->len ; i++) {
225
- if(nfacct_list->data[i].updated) {
226
- if(unlikely(!nfacct_list->data[i].rd_bytes))
227
- nfacct_list->data[i].rd_bytes = rrddim_add(
211
+ for(d = nfacct_root.nfacct_metrics; d ; d = d->next) {
212
+ if(likely(d->updated)) {
213
+ if(unlikely(!d->rd_bytes))
214
+ d->rd_bytes = rrddim_add(
215
st_bytes
229
- , nfacct_list->data[i].name
216
+ , d->name
217
, NULL
218
, 1
219
, 1000 * update_every
@@ -235,8 +222,8 @@ void *nfacct_main(void *ptr) {
222
223
rrddim_set_by_pointer(
224
st_bytes
238
- , nfacct_list->data[i].rd_bytes
239
- , (collected_number)nfacct_list->data[i].bytes
225
+ , d->rd_bytes
226
+ , (collected_number)d->bytes
227
);
228
}
229
}
@@ -247,8 +234,8 @@ void *nfacct_main(void *ptr) {
234
// ----------------------------------------------------------------
235
// prepare for the next loop
236
250
- for(i = 0; i < nfacct_list->len ; i++)
251
- nfacct_list->data[i].updated = 0;
237
+ for(d = nfacct_root.nfacct_metrics; d ; d = d->next)
238
+ d->updated = 0;
239
}
240
}
241