diff --git a/MANPAGE.md b/MANPAGE.md index 4f1bcf5..9789a04 100644 --- a/MANPAGE.md +++ b/MANPAGE.md @@ -104,6 +104,21 @@ When earlyoom is run through its default systemd service, the `-p` switch doesn' #### -n Enable notifications via d-bus. +#### -g +Kill all processes that are in the same process group as the one with excessive +memory usage. + +For example, with this flag turned on, the whole application will be killed when +one of its subprocess consumes too much memory (as long as they all have the +same PGID, of course). + +Enable this flag when completely cleaning up the "entire process" is more desirable. + +Notice that some desktop environments (GNOME, for example) put every desktop +application in the same process group as `gnome-shell` does. EarlyOOM might kill +all such processes when this flag is turned on. Be sure to check how your environment +behaves beforehand. + #### \-\-prefer REGEX prefer killing processes matching REGEX (adds 300 to oom_score) diff --git a/README.md b/README.md index 74d245e..5e99bd8 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,7 @@ Usage: ./earlyoom [OPTION]... -i user-space oom killer should ignore positive oom_score_adj values -n enable d-bus notifications + -g kill all processes within a process group -d enable debugging messages -v print version information and exit -r INTERVAL memory report interval in seconds (default 1), set diff --git a/kill.c b/kill.c index 351b439..9f1b0e4 100644 --- a/kill.c +++ b/kill.c @@ -73,6 +73,12 @@ int kill_wait(const poll_loop_args_t* args, pid_t pid, int sig) } meminfo_t m = { 0 }; const unsigned poll_ms = 100; + if (args->kill_process_group) { + if ((pid = getpgid(pid)) < 0) { + return pid; + } + pid = -pid; + } int res = kill(pid, sig); if (res != 0) { return res; diff --git a/kill.h b/kill.h index 336fad1..d854dc8 100644 --- a/kill.h +++ b/kill.h @@ -18,6 +18,8 @@ typedef struct { bool ignore_oom_score_adj; /* send d-bus notifications? */ bool notify; + /* kill all processes within a process group */ + bool kill_process_group; /* prefer/avoid killing these processes. NULL = no-op. */ regex_t* prefer_regex; regex_t* avoid_regex; diff --git a/main.c b/main.c index 6218794..b0c09cd 100644 --- a/main.c +++ b/main.c @@ -101,7 +101,7 @@ int main(int argc, char* argv[]) meminfo_t m = parse_meminfo(); int c; - const char* short_opt = "m:s:M:S:kinN:dvr:ph"; + const char* short_opt = "m:s:M:S:kingN:dvr:ph"; struct option long_opt[] = { { "prefer", required_argument, NULL, LONG_OPT_PREFER }, { "avoid", required_argument, NULL, LONG_OPT_AVOID }, @@ -173,6 +173,9 @@ int main(int argc, char* argv[]) args.notify = true; fprintf(stderr, "Notifying through D-Bus\n"); break; + case 'g': + args.kill_process_group = true; + break; case 'N': args.notify = true; fprintf(stderr, "Notifying through D-Bus, argument '%s' ignored for compatability\n", optarg); @@ -220,6 +223,7 @@ int main(int argc, char* argv[]) " -i user-space oom killer should ignore positive\n" " oom_score_adj values\n" " -n enable d-bus notifications\n" + " -g kill all processes within a process group\n" " -d enable debugging messages\n" " -v print version information and exit\n" " -r INTERVAL memory report interval in seconds (default 1), set\n"