X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Fplugin_tc.c;h=d70f52650b5601b5c52891b6c29df881eee6ab60;hb=d4a462d10af143d17a574e8fe0a1280875e8ca41;hp=5ed9140505c8fa4031f28db8133b1e7bb9ef7dc2;hpb=56ee3a77006efdc1fb78ea041986b1f7a6ba42b9;p=netdata.git diff --git a/src/plugin_tc.c b/src/plugin_tc.c old mode 100755 new mode 100644 index 5ed91405..d70f5265 --- a/src/plugin_tc.c +++ b/src/plugin_tc.c @@ -15,6 +15,7 @@ #include "popen.h" #include "plugin_tc.h" #include "main.h" +#include "../config.h" #define RRD_TYPE_TC "tc" #define RRD_TYPE_TC_LEN strlen(RRD_TYPE_TC) @@ -42,6 +43,15 @@ struct tc_class { char hasparent; char isleaf; unsigned long long bytes; + unsigned long long packets; + unsigned long long dropped; + unsigned long long overlimits; + unsigned long long requeues; + unsigned long long lended; + unsigned long long borrowed; + unsigned long long giants; + unsigned long long tokens; + unsigned long long ctokens; char updated; // updated bytes char seen; // seen in the tc list (even without bytes) @@ -84,11 +94,13 @@ static int tc_device_compare(void* a, void* b) { avl_tree tc_device_root_index = { NULL, tc_device_compare, +#ifndef AVL_WITHOUT_PTHREADS #ifdef AVL_LOCK_WITH_MUTEX PTHREAD_MUTEX_INITIALIZER #else PTHREAD_RWLOCK_INITIALIZER #endif +#endif }; #define tc_device_index_add(st) avl_insert(&tc_device_root_index, (avl *)(st)) @@ -235,7 +247,7 @@ static void tc_device_commit(struct tc_device *d) if(!st) { debug(D_TC_LOOP, "TC: Creating new chart for device '%s'", d->name?d->name:d->id); - st = rrdset_create(RRD_TYPE_TC, d->id, d->name?d->name:d->id, d->family?d->family:d->id, "Class Usage", "kilobits/s", 1000, rrd_update_every, RRDSET_TYPE_STACKED); + st = rrdset_create(RRD_TYPE_TC, d->id, d->name?d->name:d->id, d->family?d->family:d->id, RRD_TYPE_TC ".qos", "Class Usage", "kilobits/s", 7000, rrd_update_every, RRDSET_TYPE_STACKED); for(c = d->classes ; c ; c = c->next) { if(!c->updated) continue; @@ -337,11 +349,17 @@ static struct tc_device *tc_device_create(char *id) d->classes_index.root = NULL; d->classes_index.compar = tc_class_compare; + + int lock; +#ifndef AVL_WITHOUT_PTHREADS #ifdef AVL_LOCK_WITH_MUTEX - pthread_mutex_init(&d->classes_index.mutex, NULL); + lock = pthread_mutex_init(&d->classes_index.mutex, NULL); #else - pthread_rwlock_init(&d->classes_index.rwlock, NULL); + lock = pthread_rwlock_init(&d->classes_index.rwlock, NULL); +#endif #endif + if(lock != 0) + fatal("Failed to initialize plugin_tc mutex/rwlock, return code %d.", lock); tc_device_index_add(d); @@ -499,6 +517,8 @@ void *tc_main(void *ptr) uint32_t END_HASH = simple_hash("END"); uint32_t CLASS_HASH = simple_hash("class"); uint32_t SENT_HASH = simple_hash("Sent"); + uint32_t LENDED_HASH = simple_hash("lended:"); + uint32_t TOKENS_HASH = simple_hash("tokens:"); uint32_t SETDEVICENAME_HASH = simple_hash("SETDEVICENAME"); uint32_t SETDEVICEGROUP_HASH = simple_hash("SETDEVICEGROUP"); uint32_t SETCLASSNAME_HASH = simple_hash("SETCLASSNAME"); @@ -540,11 +560,21 @@ void *tc_main(void *ptr) first_hash = simple_hash(words[0]); - if(first_hash == CLASS_HASH && strcmp(words[0], "class") == 0 && device) { + if(device && first_hash == CLASS_HASH && strcmp(words[0], "class") == 0) { // 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]); - if(words[1] && words[2] && words[3] && words[4] && (strcmp(words[3], "parent") == 0 || strcmp(words[3], "root") == 0)) { - // char *type = words[1]; // the class: htb, fq_codel, etc + // clear the last class + class = NULL; + + // words[1] : class type + // words[2] : N:XX + // words[3] : parent or root + if(words[1] && words[2] && words[3] && (strcmp(words[3], "parent") == 0 || strcmp(words[3], "root") == 0)) { + //char *type = words[1]; // the class: htb, fq_codel, etc + + // we are only interested for HTB classes + //if(strcmp(type, "htb") != 0) continue; + char *id = words[2]; // the class major:minor char *parent = words[3]; // 'parent' or 'root' char *parentid = words[4]; // the parent's id @@ -598,23 +628,53 @@ void *tc_main(void *ptr) class = NULL; } } - else if(first_hash == SENT_HASH && strcmp(words[0], "Sent") == 0 && device && class) { + else if(device && class && first_hash == SENT_HASH && strcmp(words[0], "Sent") == 0) { // debug(D_TC_LOOP, "SENT line '%s'", words[1]); if(words[1] && *words[1]) { class->bytes = strtoull(words[1], NULL, 10); class->updated = 1; } - else class->bytes = 0; + + if(words[3] && *words[3]) + class->packets = strtoull(words[3], NULL, 10); + + if(words[6] && *words[6]) + class->dropped = strtoull(words[6], NULL, 10); + + if(words[8] && *words[8]) + class->overlimits = strtoull(words[8], NULL, 10); + + if(words[10] && *words[10]) + class->requeues = strtoull(words[8], NULL, 10); + } + else if(device && class && class->updated && first_hash == LENDED_HASH && strcmp(words[0], "lended:") == 0) { + // debug(D_TC_LOOP, "LENDED line '%s'", words[1]); + if(words[1] && *words[1]) + class->lended = strtoull(words[1], NULL, 10); + + if(words[3] && *words[3]) + class->borrowed = strtoull(words[3], NULL, 10); + + if(words[5] && *words[5]) + class->giants = strtoull(words[5], NULL, 10); + } + else if(device && class && class->updated && first_hash == TOKENS_HASH && strcmp(words[0], "tokens:") == 0) { + // debug(D_TC_LOOP, "TOKENS line '%s'", words[1]); + if(words[1] && *words[1]) + class->tokens = strtoull(words[1], NULL, 10); + + if(words[3] && *words[3]) + class->ctokens = strtoull(words[3], NULL, 10); } - else if(first_hash == SETDEVICENAME_HASH && strcmp(words[0], "SETDEVICENAME") == 0 && device) { + else if(device && first_hash == SETDEVICENAME_HASH && strcmp(words[0], "SETDEVICENAME") == 0) { // debug(D_TC_LOOP, "SETDEVICENAME line '%s'", words[1]); if(words[1] && *words[1]) tc_device_set_device_name(device, words[1]); } - else if(first_hash == SETDEVICEGROUP_HASH && strcmp(words[0], "SETDEVICEGROUP") == 0 && device) { + else if(device && first_hash == SETDEVICEGROUP_HASH && strcmp(words[0], "SETDEVICEGROUP") == 0) { // debug(D_TC_LOOP, "SETDEVICEGROUP line '%s'", words[1]); if(words[1] && *words[1]) tc_device_set_device_family(device, words[1]); } - else if(first_hash == SETCLASSNAME_HASH && strcmp(words[0], "SETCLASSNAME") == 0 && device) { + else if(device && first_hash == SETCLASSNAME_HASH && strcmp(words[0], "SETCLASSNAME") == 0) { // debug(D_TC_LOOP, "SETCLASSNAME line '%s' '%s'", words[1], words[2]); char *id = words[1]; char *path = words[2]; @@ -626,7 +686,7 @@ void *tc_main(void *ptr) if(!stcpu) stcpu = rrdset_find("netdata.plugin_tc_cpu"); if(!stcpu) { - stcpu = rrdset_create("netdata", "plugin_tc_cpu", NULL, "netdata", "NetData TC CPU usage", "milliseconds/s", 10000, rrd_update_every, RRDSET_TYPE_STACKED); + stcpu = rrdset_create("netdata", "plugin_tc_cpu", NULL, "tc.helper", NULL, "NetData TC CPU usage", "milliseconds/s", 135000, rrd_update_every, RRDSET_TYPE_STACKED); rrddim_add(stcpu, "user", NULL, 1, 1000, RRDDIM_INCREMENTAL); rrddim_add(stcpu, "system", NULL, 1, 1000, RRDDIM_INCREMENTAL); } @@ -638,7 +698,7 @@ void *tc_main(void *ptr) if(!sttime) stcpu = rrdset_find("netdata.plugin_tc_time"); if(!sttime) { - sttime = rrdset_create("netdata", "plugin_tc_time", NULL, "netdata", "NetData TC script execution", "milliseconds/run", 10001, rrd_update_every, RRDSET_TYPE_AREA); + sttime = rrdset_create("netdata", "plugin_tc_time", NULL, "tc.helper", NULL, "NetData TC script execution", "milliseconds/run", 135001, rrd_update_every, RRDSET_TYPE_AREA); rrddim_add(sttime, "run_time", "run time", 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next(sttime); @@ -662,7 +722,8 @@ void *tc_main(void *ptr) // debug(D_TC_LOOP, "IGNORED line"); //} } - mypclose(fp, tc_child_pid); + // fgets() failed or loop broke + int code = mypclose(fp, tc_child_pid); tc_child_pid = 0; if(device) { @@ -677,10 +738,19 @@ void *tc_main(void *ptr) return NULL; } + if(code == 1 || code == 127) { + // 1 = DISABLE + // 127 = cannot even run it + error("TC: tc-qos-helper.sh exited with code %d. Disabling it.", code); + + tc_device_free_all(); + pthread_exit(NULL); + return NULL; + } + sleep((unsigned int) rrd_update_every); } pthread_exit(NULL); return NULL; } -