@cryptotaxi247 / netdata-1 / commits / 87d093eac

apps.plugin, properly handle the kernel issues that does not include grandchildren and not-waited-for children into the parent resources

Costa Tsaousis committed Jul 2, 2016 at 02:46 UTC 87d093eac8e346e807692abf577ad1e0c176cc8c
1 file changed +52 -4
src/apps_plugin.c
+52 -4
@@ -1323,6 +1323,7 @@ int collect_data_for_all_processes_from_proc(void)
1323 // check: update_apps_groups_statistics()
1324
1325 void link_all_processes_to_their_parents(void) {
1326 + struct pid_stat *init = all_pids[1];
1327 struct pid_stat *p = NULL;
1328
1329 // link all children to their parents
@@ -1372,10 +1373,57 @@ void link_all_processes_to_their_parents(void) {
1373 pp->fix_cutime += p->last_utime + p->last_cutime + p->last_fix_cutime;
1374 pp->fix_cstime += p->last_stime + p->last_cstime + p->last_fix_cstime;
1375
1375 - if(unlikely(pp->cminflt < pp->fix_cminflt)) pp->fix_cminflt = pp->cminflt;
1376 - if(unlikely(pp->cmajflt < pp->fix_cmajflt)) pp->fix_cmajflt = pp->cmajflt;
1377 - if(unlikely(pp->cutime < pp->fix_cutime)) pp->fix_cutime = pp->cutime;
1378 - if(unlikely(pp->cstime < pp->fix_cstime)) pp->fix_cstime = pp->cstime;
1376 + // The known exited children (the ones we track) may have
1377 + // contributed more than the value accumulated into the process
1378 + // by the kernel.
1379 + // This can happen if the parent process has not waited-for
1380 + // its children (check: man 2 times).
1381 + // In this case, the kernel adds these resources to init (pid 1).
1382 + //
1383 + // The following code, attempts to fix this.
1384 + // Without this code, the charts will have random spikes
1385 + // for example, when an SSH session ends (sshd forks a child
1386 + // to serve the session, but when this session ends, sshd
1387 + // does not wait-for its child, thus all the resources of the
1388 + // ssh session get added to init, resulting in a huge spike on
1389 + // the charts).
1390 +
1391 + if(unlikely(pp->cminflt < pp->fix_cminflt)) {
1392 + if(likely(init && pp != init)) {
1393 + unsigned long long have = pp->fix_cminflt - pp->cminflt;
1394 + unsigned long long max = init->cminflt - init->fix_cminflt;
1395 + if(have > max) have = max;
1396 + init->fix_cminflt += have;
1397 + }
1398 + pp->fix_cminflt = pp->cminflt;
1399 + }
1400 + if(unlikely(pp->cmajflt < pp->fix_cmajflt)) {
1401 + if(likely(init && pp != init)) {
1402 + unsigned long long have = pp->fix_cmajflt - pp->cmajflt;
1403 + unsigned long long max = init->cmajflt - init->fix_cmajflt;
1404 + if(have > max) have = max;
1405 + init->fix_cmajflt += have;
1406 + }
1407 + pp->fix_cmajflt = pp->cmajflt;
1408 + }
1409 + if(unlikely(pp->cutime < pp->fix_cutime)) {
1410 + if(likely(init && pp != init)) {
1411 + unsigned long long have = pp->fix_cutime - pp->cutime;
1412 + unsigned long long max = init->cutime - init->fix_cutime;
1413 + if(have > max) have = max;
1414 + init->fix_cutime += have;
1415 + }
1416 + pp->fix_cutime = pp->cutime;
1417 + }
1418 + if(unlikely(pp->cstime < pp->fix_cstime)) {
1419 + if(likely(init && pp != init)) {
1420 + unsigned long long have = pp->fix_cstime - pp->cstime;
1421 + unsigned long long max = init->cstime - init->fix_cstime;
1422 + if(have > max) have = max;
1423 + init->fix_cstime += have;
1424 + }
1425 + pp->fix_cstime = pp->cstime;
1426 + }
1427
1428 if(unlikely(debug))
1429 fprintf(stderr, "apps.plugin: \tupdating child metrics of %d (%s, %s) to its parent %d (%s, %s). Parent has now: utime=%llu, stime=%llu, minflt=%llu, majflt=%llu, cutime=%llu, cstime=%llu, cminflt=%llu, cmajflt=%llu, fix_cutime=%llu, fix_cstime=%llu, fix_cminflt=%llu, fix_cmajflt=%llu\n", p->pid, p->comm, p->updated?"running":"exited", pp->pid, pp->comm, pp->updated?"running":"exited", pp->utime, pp->stime, pp->minflt, pp->majflt, pp->cutime, pp->cstime, pp->cminflt, pp->cmajflt, pp->fix_cutime, pp->fix_cstime, pp->fix_cminflt, pp->fix_cmajflt);