@cryptotaxi247 / netdata-1 / commits / 2b183c2ab

tc now supports hierarchical qdiscs too

Costa Tsaousis (ktsaou) committed Jan 29, 2017 at 08:47 UTC 2b183c2ab992540571df2d2d01c8b14edf038a42
2 files changed +65 -21
plugins.d/tc-qos-helper.sh
+21 -3
@@ -63,6 +63,8 @@ fireqos_run_dir="/var/run/fireqos"
63 qos_get_class_names_every=120
64 qos_exit_every=3600
65
66 +tc_show="qdisc" # can also be "class"
67 +
68 # check if we have a valid number for interval
69 t=${1}
70 update_every=$((t))
@@ -75,6 +77,16 @@ if [ -f "${config_dir}/tc-qos-helper.conf" ]
77 source "${config_dir}/tc-qos-helper.conf"
78 fi
79
80 +case "${tc_show}" in
81 + qdisc|class)
82 + ;;
83 +
84 + *)
85 + error "tc_show variable can be either 'qdisc' or 'class' but is set to '${tc_show}'. Assuming it is 'qdisc'."
86 + tc_show="qdisc"
87 + ;;
88 +esac
89 +
90 # default sleep function
91 LOOPSLEEPMS_LASTWORK=0
92 loopsleepms() {
@@ -94,10 +106,17 @@ tc_devices=
106 fix_names=
107
108 setclassname() {
97 - echo "SETCLASSNAME $3 $2"
109 + if [ "${tc_show}" = "qdisc" ]
110 + then
111 + echo "SETCLASSNAME $4 $2"
112 + else
113 + echo "SETCLASSNAME $3 $2"
114 + fi
115 }
116
117 show_tc_cls() {
118 + [ "${tc_show}" = "qdisc" ] && return 1
119 +
120 local x="${1}"
121
122 if [ -f /etc/iproute2/tc_cls ]
@@ -143,8 +162,7 @@ show_tc() {
162 echo "BEGIN ${x}"
163
164 # netdata can parse the output of tc
146 - ${tc} -s class show dev ${x}
147 - ${tc} -s qdisc show dev ${x}
165 + ${tc} -s ${tc_show} show dev ${x}
166
167 # check FireQOS names for classes
168 if [ ! -z "${fix_names}" ]
src/plugin_tc.c
+44 -18
@@ -267,13 +267,20 @@ static inline void tc_device_commit(struct tc_device *d) {
267 for(c = d->classes; c; c = c->next) {
268 if(unlikely(!c->updated)) continue;
269
270 + //debug(D_TC_LOOP, "TC: In device '%s', %s '%s' has leafid: '%s' and parentid '%s'.",
271 + // d->id,
272 + // c->isqdisc?"qdisc":"class",
273 + // c->id,
274 + // c->leafid?c->leafid:"NULL",
275 + // c->parentid?c->parentid:"NULL");
276 +
277 // find if c is leaf or not
278 for(x = d->classes; x; x = x->next) {
279 if(unlikely(!x->updated || c == x || !x->parentid)) continue;
280
281 if( (c->hash == x->parent_hash && strcmp(c->id, x->parentid) == 0) ||
282 (c->leafid && c->leaf_hash == x->parent_hash && strcmp(c->leafid, x->parentid) == 0)) {
276 - // debug(D_TC_LOOP, "TC: In device '%s', class '%s' (leafid: '%s') has as leaf class '%s' (parentid: '%s').", d->name?d->name:d->id, c->name?c->name:c->id, c->leafid?c->leafid:c->id, x->name?x->name:x->id, x->parentid?x->parentid:x->id);
283 + // debug(D_TC_LOOP, "TC: In device '%s', %s '%s' (leafid: '%s') has as leaf %s '%s' (parentid: '%s').", d->name?d->name:d->id, c->isqdisc?"qdisc":"class", c->name?c->name:c->id, c->leafid?c->leafid:c->id, x->isqdisc?"qdisc":"class", x->name?x->name:x->id, x->parentid?x->parentid:x->id);
284 c->isleaf = 0;
285 x->hasparent = 1;
286 }
@@ -284,8 +291,8 @@ static inline void tc_device_commit(struct tc_device *d) {
291 /*
292 if(unlikely(debug_flags & D_TC_LOOP)) {
293 for(c = d->classes ; c ; c = c->next) {
287 - if((c->isleaf && c->hasparent) || d->enabled_all_classes_qdiscs) debug(D_TC_LOOP, "TC: Device '%s', class %s, OK", d->name, c->id);
288 - 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)");
294 + if((c->isleaf && c->hasparent) || d->enabled_all_classes_qdiscs) debug(D_TC_LOOP, "TC: final nodes dump for '%s': class %s, OK", d->name, c->id);
295 + else debug(D_TC_LOOP, "TC: final nodes dump for '%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)");
296 }
297 }
298 */
@@ -293,7 +300,7 @@ static inline void tc_device_commit(struct tc_device *d) {
300 for(c = d->classes ; c ; c = c->next) {
301 if(unlikely(!c->updated)) continue;
302
296 - // 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);
303 + // debug(D_TC_LOOP, "TC: device '%s', %s '%s' isleaf=%d, hasparent=%d", d->id, (c->isqdisc)?"qdisc":"class", c->id, c->isleaf, c->hasparent);
304
305 if(unlikely((c->isleaf && c->hasparent) || d->enabled_all_classes_qdiscs)) {
306 c->render = 1;
@@ -787,26 +794,45 @@ void *tc_main(void *ptr) {
794 if(unlikely(device && ((first_hash == CLASS_HASH && strcmp(words[0], "class") == 0) || (first_hash == QDISC_HASH && strcmp(words[0], "qdisc") == 0)))) {
795 // 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]);
796
790 - // words[1] : class type
791 - // words[2] : N:XX
792 - // words[3] : parent or root
793 - if(likely(words[1] && words[2] && words[3] && (strcmp(words[3], "parent") == 0 || strcmp(words[3], "root") == 0))) {
794 - //char *type = words[1]; // the class: htb, fq_codel, etc
797 + char *type = words[1]; // the class/qdisc type: htb, fq_codel, etc
798 + char *id = words[2]; // the class/qdisc major:minor
799 + char *parent = words[3]; // the word 'parent' or 'root'
800 + char *parentid = words[4]; // parentid
801 + char *leaf = words[5]; // the word 'leaf'
802 + char *leafid = words[6]; // leafid
803 +
804 + int parent_is_root = 0;
805 + int parent_is_parent = 0;
806 + if(likely(parent)) {
807 + parent_is_parent = !strcmp(parent, "parent");
808
796 - // we are only interested for HTB classes
797 - //if(strcmp(type, "htb") != 0) continue;
809 + if(!parent_is_parent)
810 + parent_is_root = !strcmp(parent, "root");
811 + }
812
799 - char *id = words[2]; // the class major:minor
800 - char *parent = words[3]; // 'parent' or 'root'
801 - char *parentid = words[4]; // the parent's id
802 - char *leaf = words[5]; // 'leaf'
803 - char *leafid = words[6]; // leafid
813 + if(likely(type && id && (parent_is_root || parent_is_parent))) {
814 char qdisc = 0;
815
806 - if(first_hash == QDISC_HASH)
816 + if(first_hash == QDISC_HASH) {
817 qdisc = 1;
818
809 - if(strcmp(parent, "root") == 0) {
819 + if(!strcmp(type, "ingress")) {
820 + // we don't want to get the ingress qdisc
821 + // there should be an IFB interface for this
822 +
823 + class = NULL;
824 + continue;
825 + }
826 +
827 + if(parent_is_parent && parentid) {
828 + // eliminate the minor number from parentid
829 + char *s = parentid;
830 + while(*s && *s != ':') s++;
831 + if(*s == ':') s[1] = '\0';
832 + }
833 + }
834 +
835 + if(parent_is_root) {
836 parentid = NULL;
837 leafid = NULL;
838 }