@cryptotaxi247 / netdata-1 / commits / f5944e3dc

added qdiscs to tc plugin

Stefan Forstenlechner committed Dec 15, 2016 at 15:36 UTC f5944e3dcbf7bb63d108cdf00d7b3498c9b319e1
2 files changed +50 -40
plugins.d/tc-qos-helper.sh
+1 -1
@@ -110,7 +110,6 @@ show_tc_cls() {
110 done </etc/iproute2/tc_cls
111 return 0
112 fi
113 -
113 return 1
114 }
115
@@ -145,6 +144,7 @@ show_tc() {
144
145 # netdata can parse the output of tc
146 ${tc} -s class show dev ${x}
147 + ${tc} -s qdisc show dev ${x}
148
149 # check FireQOS names for classes
150 if [ ! -z "${fix_names}" ]
src/plugin_tc.c
+49 -39
@@ -25,6 +25,7 @@ struct tc_class {
25
26 char hasparent;
27 char isleaf;
28 + char isqdisc;
29 unsigned long long bytes;
30 unsigned long long packets;
31 unsigned long long dropped;
@@ -68,7 +69,7 @@ struct tc_device {
69 char enabled_dropped;
70 char enabled_tokens;
71 char enabled_ctokens;
71 - char enabled_all_classes;
72 + char enabled_all_classes_qdiscs;
73
74 RRDSET *st_bytes;
75 RRDSET *st_packets;
@@ -185,22 +186,22 @@ static inline void tc_device_classes_cleanup(struct tc_device *d) {
186 }
187
188 static inline void tc_device_commit(struct tc_device *d) {
188 - static int enable_new_interfaces = -1, enable_bytes = -1, enable_packets = -1, enable_dropped = -1, enable_tokens = -1, enable_ctokens = -1, enabled_all_classes = -1;
189 + static int enable_new_interfaces = -1, enable_bytes = -1, enable_packets = -1, enable_dropped = -1, enable_tokens = -1, enable_ctokens = -1, enabled_all_classes_qdiscs = -1;
190
191 if(unlikely(enable_new_interfaces == -1)) {
191 - enable_new_interfaces = config_get_boolean_ondemand("plugin:tc", "enable new interfaces detected at runtime", CONFIG_ONDEMAND_YES);
192 - enable_bytes = config_get_boolean_ondemand("plugin:tc", "enable traffic charts for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
193 - enable_packets = config_get_boolean_ondemand("plugin:tc", "enable packets charts for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
194 - enable_dropped = config_get_boolean_ondemand("plugin:tc", "enable dropped charts for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
195 - enable_tokens = config_get_boolean_ondemand("plugin:tc", "enable tokens charts for all interfaces", CONFIG_ONDEMAND_NO);
196 - enable_ctokens = config_get_boolean_ondemand("plugin:tc", "enable ctokens charts for all interfaces", CONFIG_ONDEMAND_NO);
197 - enabled_all_classes = config_get_boolean_ondemand("plugin:tc", "enable show all classes for all interfaces", CONFIG_ONDEMAND_NO);
192 + enable_new_interfaces = config_get_boolean_ondemand("plugin:tc", "enable new interfaces detected at runtime", CONFIG_ONDEMAND_YES);
193 + enable_bytes = config_get_boolean_ondemand("plugin:tc", "enable traffic charts for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
194 + enable_packets = config_get_boolean_ondemand("plugin:tc", "enable packets charts for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
195 + enable_dropped = config_get_boolean_ondemand("plugin:tc", "enable dropped charts for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
196 + enable_tokens = config_get_boolean_ondemand("plugin:tc", "enable tokens charts for all interfaces", CONFIG_ONDEMAND_NO);
197 + enable_ctokens = config_get_boolean_ondemand("plugin:tc", "enable ctokens charts for all interfaces", CONFIG_ONDEMAND_NO);
198 + enabled_all_classes_qdiscs = config_get_boolean_ondemand("plugin:tc", "enable show all classes and qdiscs for all interfaces", CONFIG_ONDEMAND_NO);
199 }
200
201 // we only need to add leaf classes
202 struct tc_class *c, *x;
203 unsigned long long bytes_sum = 0, packets_sum = 0, dropped_sum = 0, tokens_sum = 0, ctokens_sum = 0;
203 - int active_classes = 0;
204 + int active_qos = 0;
205
206 // set all classes
207 for(c = d->classes ; c ; c = c->next) {
@@ -216,11 +217,12 @@ static inline void tc_device_commit(struct tc_device *d) {
217 // mark the classes as leafs and parents
218 for(c = d->classes ; c ; c = c->next) {
219 if(unlikely(!c->updated)) continue;
220 + if(unlikely(c->isqdisc)) continue;
221
222 for(x = d->classes ; x ; x = x->next) {
223 if(unlikely(!x->updated)) continue;
222 -
224 if(unlikely(c == x)) continue;
225 + if(unlikely(x->isqdisc)) continue;
226
227 if(x->parentid && (
228 ( c->hash == x->parent_hash && strcmp(c->id, x->parentid) == 0) ||
@@ -236,26 +238,29 @@ static inline void tc_device_commit(struct tc_device *d) {
238 /*
239 if(unlikely(debug_flags & D_TC_LOOP)) {
240 for(c = d->classes ; c ; c = c->next) {
239 - if((c->isleaf && c->hasparent) || d->enabled_all_classes) debug(D_TC_LOOP, "TC: Device '%s', class %s, OK", d->name, c->id);
241 + if((c->isleaf && c->hasparent) || d->enabled_all_classes_qdiscs) debug(D_TC_LOOP, "TC: Device '%s', class %s, OK", d->name, c->id);
242 else debug(D_TC_LOOP, "TC: Device '%s', class %s, IGNORE (isleaf: %d, hasparent: %d, parent: %s)", d->name?d->name:d->id, c->id, c->isleaf, c->hasparent, c->parentid?c->parentid:"(unset)");
243 }
244 }
245 */
246
245 - // we need at least a class
247 + // we need the root qdisc
248 for(c = d->classes ; c ; c = c->next) {
249 // debug(D_TC_LOOP, "TC: Device '%s', class '%s', isLeaf=%d, HasParent=%d, Seen=%d", d->name?d->name:d->id, c->name?c->name:c->id, c->isleaf, c->hasparent, c->seen);
248 - if(unlikely(c->updated && ((c->isleaf && c->hasparent) || d->enabled_all_classes))) {
249 - active_classes++;
250 - bytes_sum += c->bytes;
251 - packets_sum += c->packets;
252 - dropped_sum += c->dropped;
253 - tokens_sum += c->tokens;
254 - ctokens_sum += c->ctokens;
250 + debug(D_TC_LOOP, "TC: Device '%s', class '%s', isleaf=%s, isqdisc=%s, hasparent=%s bytes=%d, packtes=%d, dropped=%d, tokens=%d, ctokens=%d", d->name?d->name:d->id, c->name?c->name:c->id, c->isleaf?"true":"false", c->isqdisc?"true":"false", c->hasparent?"true":"false", c->bytes, c->packets, c->dropped, c->tokens, c->ctokens);
251 + if(unlikely(c->updated && c->isqdisc && !c->hasparent)) {
252 + active_qos = 1;
253 + bytes_sum = c->bytes;
254 + packets_sum = c->packets;
255 + dropped_sum = c->dropped;
256 + tokens_sum = c->tokens;
257 + ctokens_sum = c->ctokens;
258 + debug(D_TC_LOOP, "TC: found root qdisc. active_qos=%d, bytes_sum=%llu", active_qos, bytes_sum);
259 + break;
260 }
261 }
262
258 - if(unlikely(!active_classes)) {
263 + if(unlikely(!active_qos)) {
264 debug(D_TC_LOOP, "TC: Ignoring TC device '%s'. No leaf classes.", d->name?d->name:d->id);
265 tc_device_classes_cleanup(d);
266 return;
@@ -264,28 +269,28 @@ static inline void tc_device_commit(struct tc_device *d) {
269 if(unlikely(d->enabled == (char)-1)) {
270 char var_name[CONFIG_MAX_NAME + 1];
271 snprintfz(var_name, CONFIG_MAX_NAME, "qos for %s", d->id);
267 - d->enabled = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_new_interfaces);
272 + d->enabled = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_new_interfaces);
273
274 snprintfz(var_name, CONFIG_MAX_NAME, "traffic chart for %s", d->id);
270 - d->enabled_bytes = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_bytes);
275 + d->enabled_bytes = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_bytes);
276
277 snprintfz(var_name, CONFIG_MAX_NAME, "packets chart for %s", d->id);
273 - d->enabled_packets = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_packets);
278 + d->enabled_packets = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_packets);
279
280 snprintfz(var_name, CONFIG_MAX_NAME, "dropped packets chart for %s", d->id);
276 - d->enabled_dropped = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_dropped);
281 + d->enabled_dropped = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_dropped);
282
283 snprintfz(var_name, CONFIG_MAX_NAME, "tokens chart for %s", d->id);
279 - d->enabled_tokens = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_tokens);
284 + d->enabled_tokens = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_tokens);
285
286 snprintfz(var_name, CONFIG_MAX_NAME, "ctokens chart for %s", d->id);
282 - d->enabled_ctokens = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_ctokens);
287 + d->enabled_ctokens = (char)config_get_boolean_ondemand("plugin:tc", var_name, enable_ctokens);
288
289 snprintfz(var_name, CONFIG_MAX_NAME, "show all classes for %s", d->id);
285 - d->enabled_all_classes = (char)config_get_boolean_ondemand("plugin:tc", var_name, enabled_all_classes);
290 + d->enabled_all_classes_qdiscs = (char)config_get_boolean_ondemand("plugin:tc", var_name, enabled_all_classes_qdiscs);
291 }
292
288 - debug(D_TC_LOOP, "TC: evaluating TC device '%s'. enabled = %d/%d (bytes: %d/%d, packets: %d/%d, dropped: %d/%d, tokens: %d/%d, ctokens: %d/%d), classes = %d (bytes = %llu, packets = %llu, dropped = %llu, tokens = %llu, ctokens = %llu).",
293 + debug(D_TC_LOOP, "TC: evaluating TC device '%s'. enabled = %d/%d (bytes: %d/%d, packets: %d/%d, dropped: %d/%d, tokens: %d/%d, ctokens: %d/%d, all_classes_qdiscs: %d/%d), classes: (bytes = %llu, packets = %llu, dropped = %llu, tokens = %llu, ctokens = %llu).",
294 d->name?d->name:d->id,
295 d->enabled, enable_new_interfaces,
296 d->enabled_bytes, enable_bytes,
@@ -293,8 +298,7 @@ static inline void tc_device_commit(struct tc_device *d) {
298 d->enabled_dropped, enable_dropped,
299 d->enabled_tokens, enable_tokens,
300 d->enabled_ctokens, enable_ctokens,
296 - d->enabled_all_classes, enabled_all_classes,
297 - active_classes,
301 + d->enabled_all_classes_qdiscs, enabled_all_classes_qdiscs,
302 bytes_sum,
303 packets_sum,
304 dropped_sum,
@@ -332,7 +336,7 @@ static inline void tc_device_commit(struct tc_device *d) {
336 for(c = d->classes ; c ; c = c->next) {
337 if(unlikely(!c->updated)) continue;
338
335 - if((c->isleaf && c->hasparent) || d->enabled_all_classes) {
339 + if((c->isleaf && c->hasparent && !c->isqdisc) || d->enabled_all_classes_qdiscs) {
340 if(unlikely(!c->rd_bytes)) {
341 c->rd_bytes = rrddim_find(d->st_bytes, c->id);
342 if(unlikely(!c->rd_bytes)) {
@@ -386,7 +390,7 @@ static inline void tc_device_commit(struct tc_device *d) {
390 for(c = d->classes ; c ; c = c->next) {
391 if(unlikely(!c->updated)) continue;
392
389 - if((c->isleaf && c->hasparent) || d->enabled_all_classes) {
393 + if((c->isleaf && c->hasparent && !c->isqdisc) || d->enabled_all_classes_qdiscs) {
394 if(unlikely(!c->rd_packets)) {
395 c->rd_packets = rrddim_find(d->st_packets, c->id);
396 if(unlikely(!c->rd_packets)) {
@@ -440,7 +444,7 @@ static inline void tc_device_commit(struct tc_device *d) {
444 for(c = d->classes ; c ; c = c->next) {
445 if(unlikely(!c->updated)) continue;
446
443 - if((c->isleaf && c->hasparent) || d->enabled_all_classes) {
447 + if((c->isleaf && c->hasparent && !c->isqdisc) || d->enabled_all_classes_qdiscs) {
448 if(unlikely(!c->rd_dropped)) {
449 c->rd_dropped = rrddim_find(d->st_dropped, c->id);
450 if(unlikely(!c->rd_dropped)) {
@@ -494,7 +498,7 @@ static inline void tc_device_commit(struct tc_device *d) {
498 for(c = d->classes ; c ; c = c->next) {
499 if(unlikely(!c->updated)) continue;
500
497 - if((c->isleaf && c->hasparent) || d->enabled_all_classes) {
501 + if((c->isleaf && c->hasparent && !c->isqdisc) || d->enabled_all_classes_qdiscs) {
502 if(unlikely(!c->rd_tokens)) {
503 c->rd_tokens = rrddim_find(d->st_tokens, c->id);
504 if(unlikely(!c->rd_tokens)) {
@@ -548,7 +552,7 @@ static inline void tc_device_commit(struct tc_device *d) {
552 for(c = d->classes ; c ; c = c->next) {
553 if(unlikely(!c->updated)) continue;
554
551 - if((c->isleaf && c->hasparent) || d->enabled_all_classes) {
555 + if((c->isleaf && c->hasparent && !c->isqdisc) || d->enabled_all_classes_qdiscs) {
556 if(unlikely(!c->rd_ctokens)) {
557 c->rd_ctokens = rrddim_find(d->st_ctokens, c->id);
558 if(unlikely(!c->rd_ctokens)) {
@@ -645,7 +649,7 @@ static inline struct tc_device *tc_device_create(char *id)
649 return(d);
650 }
651
648 -static inline struct tc_class *tc_class_add(struct tc_device *n, char *id, char *parentid, char *leafid)
652 +static inline struct tc_class *tc_class_add(struct tc_device *n, char *id, char qdisc, char *parentid, char *leafid)
653 {
654 struct tc_class *c = tc_class_index_find(n, id, 0);
655
@@ -661,6 +665,7 @@ static inline struct tc_class *tc_class_add(struct tc_device *n, char *id, char
665 c->id = strdupz(id);
666 c->hash = simple_hash(c->id);
667
668 + c->isqdisc = qdisc;
669 if(parentid && *parentid) {
670 c->parentid = strdupz(parentid);
671 c->parent_hash = simple_hash(c->parentid);
@@ -773,6 +778,7 @@ void *tc_main(void *ptr) {
778
779 uint32_t BEGIN_HASH = simple_hash("BEGIN");
780 uint32_t END_HASH = simple_hash("END");
781 + uint32_t QDISC_HASH = simple_hash("qdisc");
782 uint32_t CLASS_HASH = simple_hash("class");
783 uint32_t SENT_HASH = simple_hash("Sent");
784 uint32_t LENDED_HASH = simple_hash("lended:");
@@ -821,7 +827,7 @@ void *tc_main(void *ptr) {
827
828 first_hash = simple_hash(words[0]);
829
824 - if(unlikely(device && first_hash == CLASS_HASH && strcmp(words[0], "class") == 0)) {
830 + if(unlikely(device && ((first_hash == CLASS_HASH && strcmp(words[0], "class") == 0) || (first_hash == QDISC_HASH && strcmp(words[0], "qdisc") == 0)))) {
831 // debug(D_TC_LOOP, "CLASS line on class id='%s', parent='%s', parentid='%s', leaf='%s', leafid='%s'", words[2], words[3], words[4], words[5], words[6]);
832
833 // words[1] : class type
@@ -838,7 +844,11 @@ void *tc_main(void *ptr) {
844 char *parentid = words[4]; // the parent's id
845 char *leaf = words[5]; // 'leaf'
846 char *leafid = words[6]; // leafid
847 + char qdisc = 0;
848
849 + if(strcmp(words[0], "qdisc") == 0) {
850 + qdisc = 1;
851 + }
852 if(strcmp(parent, "root") == 0) {
853 parentid = NULL;
854 leafid = NULL;
@@ -853,7 +863,7 @@ void *tc_main(void *ptr) {
863 leafid = leafbuf;
864 }
865
856 - class = tc_class_add(device, id, parentid, leafid);
866 + class = tc_class_add(device, id, qdisc, parentid, leafid);
867 }
868 else {
869 // clear the last class