@cryptotaxi247 / netdata-1 / commits / d849dd5f0

tc-qos-helper.sh optimization to avoid forks; added support for reading class names from /etc/iproute2/tc_cls; fixes #837

Costa Tsaousis (ktsaou) committed Dec 21, 2016 at 00:37 UTC d849dd5f0aa2150fda857a923fcc109096b5ee91
2 files changed +64 -16
plugins.d/loopsleepms.sh.inc
+1 -1
@@ -139,7 +139,7 @@ loopsleepms() {
139
140 # calculate ms since last run
141 [ ${LOOPSLEEPMS_LASTRUN} -gt 0 ] && \
142 - LOOPSLEEPMS_LASTWORK=$((now_ms - LOOPSLEEPMS_LASTRUN - LOOPSLEEPMS_LASTSLEEP))
142 + LOOPSLEEPMS_LASTWORK=$((now_ms - LOOPSLEEPMS_LASTRUN - LOOPSLEEPMS_LASTSLEEP + current_time_ms_accuracy))
143 # echo "# last loop's work took $LOOPSLEEPMS_LASTWORK ms"
144
145 # remember this run
plugins.d/tc-qos-helper.sh
+63 -15
@@ -5,8 +5,8 @@
5 # (C) 2016 Costa Tsaousis <costa@tsaousis.gr>
6 # GPL v3+
7 #
8 -# This script is a helper to allow netdata collect tc data
9 -# parsing tc output has been implemented in C, inside netdata
8 +# This script is a helper to allow netdata collect tc data.
9 +# tc output parsing has been implemented in C, inside netdata
10 # This script allows setting names to dimensions.
11
12 export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
@@ -90,21 +90,34 @@ if [ -z "${tc}" -o ! -x "${tc}" ]
90 fatal "cannot find command 'tc' in this system."
91 fi
92
93 -devices=
93 +tc_devices=
94 fix_names=
95
96 setclassname() {
97 echo "SETCLASSNAME $3 $2"
98 }
99
100 -show_tc() {
101 - local x="${1}" interface_dev interface_classes interface_classes_monitor
100 +show_tc_cls() {
101 + local x="${1}"
102
103 - echo "BEGIN ${x}"
104 - ${tc} -s class show dev ${x}
103 + if [ -f /etc/iproute2/tc_cls ]
104 + then
105 + local classid name rest
106 + while read classid name rest
107 + do
108 + [ -z "${classid}" -o -z "${name}" -o "${classid}" = "#" -o "${name}" = "#" -o "${classid:0:1}" = "#" -o "${name:0:1}" = "#" ] && continue
109 + setclassname "" "${name}" "${classid}"
110 + done </etc/iproute2/tc_cls
111 + return 0
112 + fi
113
106 - # check FireQOS names for classes
107 - if [ ! -z "${fix_names}" -a -f "${fireqos_run_dir}/ifaces/${x}" ]
114 + return 1
115 +}
116 +
117 +show_fireqos_names() {
118 + local x="${1}" name n interface_dev interface_classes interface_classes_monitor
119 +
120 + if [ -f "${fireqos_run_dir}/ifaces/${x}" ]
121 then
122 name="$(<"${fireqos_run_dir}/ifaces/${x}")"
123 echo "SETDEVICENAME ${name}"
@@ -118,15 +131,50 @@ show_tc() {
131 setclassname ${n//|/ }
132 done
133 [ ! -z "${interface_dev}" ] && echo "SETDEVICEGROUP ${interface_dev}"
134 +
135 + return 0
136 + fi
137 +
138 + return 1
139 +}
140 +
141 +show_tc() {
142 + local x="${1}"
143 +
144 + echo "BEGIN ${x}"
145 +
146 + # netdata can parse the output of tc
147 + ${tc} -s class show dev ${x}
148 +
149 + # check FireQOS names for classes
150 + if [ ! -z "${fix_names}" ]
151 + then
152 + show_fireqos_names "${x}" || show_tc_cls "${x}"
153 fi
154 +
155 echo "END ${x}"
156 }
157
125 -all_devices() {
126 - cat /proc/net/dev | grep ":" | cut -d ':' -f 1 | while read dev
158 +find_tc_devices() {
159 + local count=0 devs= dev rest l
160 +
161 + # find all the devices in the system
162 + # without forking
163 + while IFS=":| " read dev rest
164 + do
165 + count=$((count + 1))
166 + [ ${count} -le 2 ] && continue
167 + devs="${devs} ${dev}"
168 + done </proc/net/dev
169 +
170 + # from all the devices find the ones
171 + # that have QoS defined
172 + # unfortunately, one fork per device cannot be avoided
173 + tc_devices=
174 + for dev in ${devs}
175 do
128 - l=$(${tc} class show dev ${dev} | wc -l)
129 - [ $l -ne 0 ] && echo ${dev}
176 + l="$(${tc} class show dev ${dev} 2>/dev/null)"
177 + #[ ! -z "${l}" ] && tc_devices="${tc_devices} ${dev}"
178 done
179 }
180
@@ -150,10 +198,10 @@ do
198 then
199 c=1
200 fix_names="YES"
153 - devices="$( all_devices )"
201 + find_tc_devices
202 fi
203
156 - for d in ${devices}
204 + for d in ${tc_devices}
205 do
206 show_tc ${d}
207 done