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
}