Skip to content

Commit afe0360

Browse files
tsipinakisrfjakob
authored andcommitted
Implement programmatic notifications
Add support for running a script for each process killed (or would kill in dryrun mode). Signed-off-by: Nikos Tsipinakis <[email protected]>
1 parent 898f590 commit afe0360

File tree

5 files changed

+56
-2
lines changed

5 files changed

+56
-2
lines changed

MANPAGE.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,19 @@ To actually see the notifications in your GUI session, you need to have
108108
[systembus-notify](https://github.com/rfjakob/systembus-notify)
109109
running as your user.
110110

111+
#### -N SCRIPT
112+
Run the given script for each process killed.
113+
114+
Within the script, information about the killed process can be obtained via the
115+
following environment variables:
116+
117+
EARLYOOM_PID Process PID
118+
EARLYOOM_NAME Process name/path
119+
EARLYOOM_UID UID of the user running the process
120+
121+
Warning: In case of dryrun mode, the script will be executed in rapid
122+
succession, ensure you have some sort of rate-limit implemented.
123+
111124
#### -g
112125
Kill all processes that have same process group id (PGID) as the process
113126
with excessive memory usage.

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,13 @@ To actually see the notifications in your GUI session, you need to have
195195
[systembus-notify](https://github.com/rfjakob/systembus-notify)
196196
running as your user.
197197

198+
Additionally, earlyoom can execute a script for each process killed, providing
199+
information about the process via the `EARLYOOM_PID`, `EARLYOOM_UID` and
200+
`EARLYOOM_NAME` environment variables. Pass `-N /path/to/script` to enable.
201+
202+
Warning: In case of dryrun mode, the script will be executed in rapid
203+
succession, ensure you have some sort of rate-limit implemented.
204+
198205
### Preferred Processes
199206

200207
The command-line flag `--prefer` specifies processes to prefer killing;

kill.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#define BADNESS_PREFER 300
2222
#define BADNESS_AVOID -300
2323

24+
// Buffer size for UID/GID/PID string conversion
25+
#define UID_BUFSIZ 128
26+
2427
static int isnumeric(char* str)
2528
{
2629
int i = 0;
@@ -61,6 +64,32 @@ static void notify(const char* summary, const char* body)
6164
exit(1);
6265
}
6366

67+
static void notify_ext(const char* script, const procinfo_t victim)
68+
{
69+
pid_t pid1 = fork();
70+
71+
if (pid1 == -1) {
72+
warn("fork() returned -1: %s\n", strerror(errno));
73+
return;
74+
} else if (pid1 != 0) {
75+
return;
76+
}
77+
78+
char pid_str[UID_BUFSIZ];
79+
char uid_str[UID_BUFSIZ];
80+
81+
snprintf(pid_str, UID_BUFSIZ, "%d", victim.pid);
82+
snprintf(uid_str, UID_BUFSIZ, "%d", victim.uid);
83+
84+
setenv("EARLYOOM_PID", pid_str, 1);
85+
setenv("EARLYOOM_UID", uid_str, 1);
86+
setenv("EARLYOOM_NAME", victim.name, 1);
87+
88+
execlp(script, script, NULL);
89+
warn("notify_ext: exec failed: %s\n", strerror(errno));
90+
exit(1);
91+
}
92+
6493
/*
6594
* Send the selected signal to "pid" and wait for the process to exit
6695
* (max 10 seconds)
@@ -312,6 +341,9 @@ void kill_process(const poll_loop_args_t* args, int sig, const procinfo_t victim
312341
if (args->notify) {
313342
notify("earlyoom", notif_args);
314343
}
344+
if (args->notify_ext) {
345+
notify_ext(args->notify_ext, victim);
346+
}
315347
}
316348

317349
if (sig == 0) {

kill.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ typedef struct {
1616
double swap_kill_percent;
1717
/* send d-bus notifications? */
1818
bool notify;
19+
/* Path to script for programmatic notifications (or NULL) */
20+
char *notify_ext;
1921
/* kill all processes within a process group */
2022
bool kill_process_group;
2123
/* prefer/avoid killing these processes. NULL = no-op. */

main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ int main(int argc, char* argv[])
176176
args.kill_process_group = true;
177177
break;
178178
case 'N':
179-
args.notify = true;
180-
fprintf(stderr, "Notifying through D-Bus, argument '%s' ignored for compatability\n", optarg);
179+
args.notify_ext = optarg;
181180
break;
182181
case 'd':
183182
enable_debug = 1;
@@ -220,6 +219,7 @@ int main(int argc, char* argv[])
220219
" -M SIZE[,KILL_SIZE] set available memory minimum to SIZE KiB\n"
221220
" -S SIZE[,KILL_SIZE] set free swap minimum to SIZE KiB\n"
222221
" -n enable d-bus notifications\n"
222+
" -N enable programmatic notifications\n"
223223
" -g kill all processes within a process group\n"
224224
" -d enable debugging messages\n"
225225
" -v print version information and exit\n"

0 commit comments

Comments
 (0)