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