@cryptotaxi247 / netdata-1 / commits / d09017439

fix for application group inheritance bug #79

Costa Tsaousis (ktsaou) committed Apr 2, 2016 at 17:26 UTC d09017439fba50423b1b21e75c0c6687a0b242b7
2 files changed +75 -25
conf.d/apps_groups.conf
+1 -1
@@ -23,7 +23,7 @@
23 compile: cc1 cc1plus as gcc ld make automake autoconf git
24 rsync: rsync
25 media: mplayer vlc xine mediatomb omxplayer omxplayer.bin kodi kodi.bin xbmc xbmc.bin mediacenter eventlircd
26 -squid: squid squid2 squid3
26 +squid: squid squid2 squid3 c-icap
27 apache: apache apache2
28 mysql: mysqld mysql
29 asterisk: asterisk
src/apps_plugin.c
+74 -24
@@ -575,7 +575,7 @@ struct pid_stat {
575 int *fds; // array of fds it uses
576 int fds_size; // the size of the fds array
577
578 - int childs; // number of processes directly referencing this
578 + int children_count; // number of processes directly referencing this
579 int updated; // 1 when update
580 int merged; // 1 when it has been merged to its parent
581 int new_entry;
@@ -804,7 +804,7 @@ int walk_down(pid_t pid, int level) {
804 if(p) {
805 if(!p->updated) ret += 1;
806 if(ret) fprintf(stderr, "%s %s %d [%s, %s] c=%d u=%llu+%llu, s=%llu+%llu, cu=%llu+%llu, cs=%llu+%llu, n=%llu+%llu, j=%llu+%llu, cn=%llu+%llu, cj=%llu+%llu\n"
807 - , b, p->comm, p->pid, p->updated?"OK":"KILLED", p->target->name, p->childs
807 + , b, p->comm, p->pid, p->updated?"OK":"KILLED", p->target->name, p->children_count
808 , p->utime, p->utime - p->old_utime
809 , p->stime, p->stime - p->old_stime
810 , p->cutime, p->cutime - p->old_cutime
@@ -1062,7 +1062,7 @@ int update_from_proc(void)
1062 all_pids_count++;
1063 p->parent = NULL;
1064 p->updated = 0;
1065 - p->childs = 0;
1065 + p->children_count = 0;
1066 p->merged = 0;
1067 p->new_entry = 0;
1068 }
@@ -1236,57 +1236,104 @@ void update_statistics(void)
1236 int c;
1237 struct pid_stat *p = NULL;
1238
1239 - // link all parents and update childs count
1239 +
1240 + // link all children to their parents
1241 + // and update children count on parents
1242 for(p = root_of_pids; p ; p = p->next) {
1241 - if(p->ppid > 0 && p->ppid <= pid_max && all_pids[p->ppid]) {
1242 - if(debug || (p->target && p->target->debug)) fprintf(stderr, "apps.plugin: \tparent of %d %s is %d %s\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);
1243 + // for each process found running
1244 +
1245 + if(p->ppid > 0
1246 + && p->ppid <= pid_max
1247 + && all_pids[p->ppid]
1248 + ) {
1249 + // for valid processes
1250 +
1251 + if(debug || (p->target && p->target->debug))
1252 + fprintf(stderr, "apps.plugin: \tparent of %d (%s) is %d (%s)\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);
1253
1254 p->parent = all_pids[p->ppid];
1245 - p->parent->childs++;
1255 + p->parent->children_count++;
1256 }
1247 - else if(p->ppid != 0) error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid);
1257 + else if(p->ppid != 0)
1258 + error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid);
1259 }
1260
1261 +
1262 + // children that do not have a target
1263 + // inherit their target from their parent
1264 + int found = 1;
1265 + while(found) {
1266 + found = 0;
1267 + for(p = root_of_pids; p ; p = p->next) {
1268 + // if this process does not have a target
1269 + // and it has a parent
1270 + // and its parent has a target
1271 + // then, set the parent's target to this process
1272 + if(unlikely(!p->target && p->parent && p->parent->target)) {
1273 + p->target = p->parent->target;
1274 + found++;
1275 +
1276 + if(debug || (p->target && p->target->debug))
1277 + fprintf(stderr, "apps.plugin: \t\tTARGET INHERITANCE: %s is inherited by %d (%s) from its parent %d (%s).\n", p->target->name, p->pid, p->comm, p->parent->pid, p->parent->comm);
1278 + }
1279 + }
1280 + }
1281 +
1282 +
1283 // find all the procs with 0 childs and merge them to their parents
1284 // repeat, until nothing more can be done.
1252 - int found = 1;
1285 + found = 1;
1286 while(found) {
1287 found = 0;
1288 for(p = root_of_pids; p ; p = p->next) {
1256 - // if this process does not have any childs, and
1257 - // is not already merged, and
1258 - // its parent has childs waiting to be merged, and
1259 - // the target of this process and its parent is the same, or the parent does not have a target, or this process does not have a parent
1289 + // if this process does not have any children
1290 + // and is not already merged
1291 + // and has a parent
1292 + // and its parent has children
1293 + // and the target of this process and its parent is the same, or the parent does not have a target
1294 // and its parent is not init
1261 - // then... merge them!
1262 - if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target) && p->ppid != 1) {
1263 - p->parent->childs--;
1295 + // then, mark them as merged.
1296 + if(unlikely(
1297 + !p->children_count
1298 + && !p->merged
1299 + && p->parent
1300 + && p->parent->children_count
1301 + && (p->target == p->parent->target || !p->parent->target)
1302 + && p->ppid != 1
1303 + )) {
1304 + p->parent->children_count--;
1305 p->merged = 1;
1306
1307 // the parent inherits the child's target, if it does not have a target itself
1267 - if(p->target && !p->parent->target) {
1308 + if(unlikely(p->target && !p->parent->target)) {
1309 p->parent->target = p->target;
1269 - if(debug || (p->target && p->target->debug)) fprintf(stderr, "apps.plugin: \t\ttarget %s is inherited by %d %s from its child %d %s.\n", p->target->name, p->parent->pid, p->parent->comm, p->pid, p->comm);
1310 +
1311 + if(debug || (p->target && p->target->debug))
1312 + fprintf(stderr, "apps.plugin: \t\tTARGET INHERITANCE: %s is inherited by %d (%s) from its child %d (%s).\n", p->target->name, p->parent->pid, p->parent->comm, p->pid, p->comm);
1313 }
1314
1315 found++;
1316 }
1317 }
1275 - if(debug) fprintf(stderr, "apps.plugin: merged %d processes\n", found);
1318 +
1319 + if(debug)
1320 + fprintf(stderr, "apps.plugin: merged %d processes\n", found);
1321 }
1322
1278 - // give a default target on all top level processes
1323 // init goes always to default target
1280 - if(all_pids[1]) all_pids[1]->target = default_target;
1324 + if(all_pids[1])
1325 + all_pids[1]->target = default_target;
1326
1327 + // give a default target on all top level processes
1328 for(p = root_of_pids; p ; p = p->next) {
1329 // if the process is not merged itself
1330 // then is is a top level process
1285 - if(!p->merged && !p->target) p->target = default_target;
1331 + if(!p->merged && !p->target)
1332 + p->target = default_target;
1333
1334 #ifdef INCLUDE_CHILDS
1335 // by the way, update the diffs
1289 - // will be used later for substracting killed process times
1336 + // will be used later for subtracting killed process times
1337 p->diff_cutime = p->utime - p->cutime;
1338 p->diff_cstime = p->stime - p->cstime;
1339 p->diff_cminflt = p->minflt - p->cminflt;
@@ -1299,9 +1346,12 @@ void update_statistics(void)
1346 while(found) {
1347 found = 0;
1348 for(p = root_of_pids; p ; p = p->next) {
1302 - if(!p->target && p->merged && p->parent && p->parent->target) {
1349 + if(unlikely(!p->target && p->merged && p->parent && p->parent->target)) {
1350 p->target = p->parent->target;
1351 found++;
1352 +
1353 + if(debug || (p->target && p->target->debug))
1354 + fprintf(stderr, "apps.plugin: \t\tTARGET INHERITANCE: %s is inherited by %d (%s) from its parent %d (%s) at phase 2.\n", p->target->name, p->pid, p->comm, p->parent->pid, p->parent->comm);
1355 }
1356 }
1357 }