@cryptotaxi247 / netdata-1 / commits / 4d061299d

cgroup-network search for PIDs in sub-cgroups; also it works even when there are no veth interfaces at the system; fixes #3199

Costa Tsaousis (ktsaou) committed Jan 4, 2018 at 18:41 UTC 4d061299d1eb0103c484d973e5b058b53031cabd
1 file changed +69 -22
src/cgroup-network.c
+69 -22
@@ -247,25 +247,18 @@ int switch_namespace(const char *prefix, pid_t pid) {
247 #endif
248 }
249
250 -pid_t read_pid_from_cgroup(const char *path) {
251 - char buffer[FILENAME_MAX + 1];
252 -
253 - snprintfz(buffer, FILENAME_MAX, "%s/cgroup.procs", path);
254 - FILE *fp = fopen(buffer, "r");
250 +pid_t read_pid_from_cgroup_file(const char *filename) {
251 + FILE *fp = fopen(filename, "r");
252 if(!fp) {
256 - error("Cannot read file '%s'.", buffer);
257 - snprintfz(buffer, FILENAME_MAX, "%s/tasks", path);
258 - fp = fopen(buffer, "r");
259 - }
260 -
261 - if(!fp) {
262 - error("Cannot read file '%s'.", buffer);
253 + error("Cannot read file '%s'.", filename);
254 return 0;
255 }
256
257 + char buffer[100 + 1];
258 pid_t pid = 0;
259 char *s;
268 - while((s = fgets(buffer, FILENAME_MAX, fp))) {
260 + while((s = fgets(buffer, 100, fp))) {
261 + buffer[100] = '\0';
262 pid = atoi(s);
263 if(pid > 0) break;
264 }
@@ -274,6 +267,46 @@ pid_t read_pid_from_cgroup(const char *path) {
267 return pid;
268 }
269
270 +pid_t read_pid_from_cgroup_files(const char *path) {
271 + char filename[FILENAME_MAX + 1];
272 +
273 + snprintfz(filename, FILENAME_MAX, "%s/cgroup.procs", path);
274 + pid_t pid = read_pid_from_cgroup_file(filename);
275 + if(pid > 0) return pid;
276 +
277 + snprintfz(filename, FILENAME_MAX, "%s/tasks", path);
278 + return read_pid_from_cgroup_file(filename);
279 +}
280 +
281 +pid_t read_pid_from_cgroup(const char *path) {
282 + pid_t pid = read_pid_from_cgroup_files(path);
283 + if (pid > 0) return pid;
284 +
285 + DIR *dir = opendir(path);
286 + if (!dir) {
287 + error("cannot read directory '%s'", path);
288 + return 0;
289 + }
290 +
291 + struct dirent *de = NULL;
292 + while ((de = readdir(dir))) {
293 + if (de->d_type == DT_DIR
294 + && (
295 + (de->d_name[0] == '.' && de->d_name[1] == '\0')
296 + || (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')
297 + ))
298 + continue;
299 +
300 + if (de->d_type == DT_DIR) {
301 + char filename[FILENAME_MAX + 1];
302 + snprintfz(filename, FILENAME_MAX, "%s/%s", path, de->d_name);
303 + pid = read_pid_from_cgroup(filename);
304 + if(pid > 0) break;
305 + }
306 + }
307 + closedir(dir);
308 + return pid;
309 +}
310
311 // ----------------------------------------------------------------------------
312 // send the result to netdata
@@ -337,18 +370,30 @@ void detect_veth_interfaces(pid_t pid) {
370 if(!host)
371 fatal("cannot read host interface list.");
372
340 - if(!eligible_ifaces(host))
341 - fatal("there are no double-linked host interfaces available.");
373 + if(!eligible_ifaces(host)) {
374 + errno = 0;
375 + error("there are no double-linked host interfaces available.");
376 + return;
377 + }
378
343 - if(switch_namespace(prefix, pid))
344 - fatal("cannot switch to the namespace of pid %u", (unsigned int)pid);
379 + if(switch_namespace(prefix, pid)) {
380 + errno = 0;
381 + error("cannot switch to the namespace of pid %u", (unsigned int) pid);
382 + return;
383 + }
384
385 cgroup = read_proc_net_dev(NULL);
347 - if(!cgroup)
348 - fatal("cannot read cgroup interface list.");
386 + if(!cgroup) {
387 + errno = 0;
388 + error("cannot read cgroup interface list.");
389 + return;
390 + }
391
350 - if(!eligible_ifaces(cgroup))
351 - fatal("there are not double-linked cgroup interfaces available.");
392 + if(!eligible_ifaces(cgroup)) {
393 + errno = 0;
394 + error("there are not double-linked cgroup interfaces available.");
395 + return;
396 + }
397
398 for(h = host; h ; h = h->next) {
399 if(iface_is_eligible(h)) {
@@ -462,5 +507,7 @@ int main(int argc, char **argv) {
507 if(pid > 0)
508 detect_veth_interfaces(pid);
509
465 - return send_devices();
510 + int found = send_devices();
511 + if(found <= 0) return 1;
512 + return 0;
513 }