2 * choom - Change OOM score setting
4 * Copyright (C) 2018 Karel Zak <kzak@redhat.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it would be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "closestream.h"
33 static void __attribute__((__noreturn__
)) usage(void)
36 fputs(USAGE_HEADER
, out
);
38 _(" %1$s [options] -p pid\n"
39 " %1$s [options] -n number -p pid\n"
40 " %1$s [options] -n number [--] command [args...]]\n"),
41 program_invocation_short_name
);
43 fputs(USAGE_SEPARATOR
, out
);
44 fputs(_("Display and adjust OOM-killer score.\n"), out
);
46 fputs(USAGE_OPTIONS
, out
);
47 fputs(_(" -n, --adjust <num> specify the adjust score value\n"), out
);
48 fputs(_(" -p, --pid <num> process ID\n"), out
);
49 fputs(USAGE_SEPARATOR
, out
);
50 printf(USAGE_HELP_OPTIONS(24));
51 printf(USAGE_MAN_TAIL("choom(1)"));
55 static int get_score(struct path_cxt
*pc
)
59 if (ul_path_read_s32(pc
, &ret
, "oom_score") != 0)
60 err(EXIT_FAILURE
, _("failed to read OOM score value"));
65 static int get_score_adj(struct path_cxt
*pc
)
69 if (ul_path_read_s32(pc
, &ret
, "oom_score_adj") != 0)
70 err(EXIT_FAILURE
, _("failed to read OOM score adjust value"));
75 static int set_score_adj(struct path_cxt
*pc
, int adj
)
77 return ul_path_write_s64(pc
, adj
, "oom_score_adj");
80 int main(int argc
, char **argv
)
83 int c
, adj
= 0, has_adj
= 0;
84 struct path_cxt
*pc
= NULL
;
86 static const struct option longopts
[] = {
87 { "adjust", required_argument
, NULL
, 'n' },
88 { "pid", required_argument
, NULL
, 'p' },
89 { "help", no_argument
, NULL
, 'h' },
90 { "version", no_argument
, NULL
, 'V' },
94 setlocale(LC_ALL
, "");
95 bindtextdomain(PACKAGE
, LOCALEDIR
);
97 close_stdout_atexit();
99 while ((c
= getopt_long(argc
, argv
, "hn:p:V", longopts
, NULL
)) != -1) {
102 pid
= strtos32_or_err(optarg
, _("invalid PID argument"));
105 adj
= strtos32_or_err(optarg
, _("invalid adjust argument"));
110 print_version(EXIT_SUCCESS
);
114 errtryhelp(EXIT_FAILURE
);
118 if (optind
< argc
&& pid
) {
119 warnx(_("invalid argument: %s"), argv
[optind
]);
120 errtryhelp(EXIT_FAILURE
);
122 if (!pid
&& argc
- optind
< 1) {
123 warnx(_("no PID or COMMAND specified"));
124 errtryhelp(EXIT_FAILURE
);
126 if (optind
< argc
&& !has_adj
) {
127 warnx(_("no OOM score adjust value specified"));
128 errtryhelp(EXIT_FAILURE
);
131 pc
= ul_new_path("/proc/%d", (int) (pid
? pid
: getpid()));
135 printf(_("pid %d's current OOM score: %d\n"), pid
, get_score(pc
));
136 printf(_("pid %d's current OOM score adjust value: %d\n"), pid
, get_score_adj(pc
));
140 int old
= get_score_adj(pc
);
142 if (set_score_adj(pc
, adj
))
143 err(EXIT_FAILURE
, _("failed to set score adjust value"));
145 printf(_("pid %d's OOM score adjust value changed from %d to %d\n"), pid
, old
, adj
);
147 /* Start new process */
149 if (set_score_adj(pc
, adj
))
150 err(EXIT_FAILURE
, _("failed to set score adjust value"));
153 execvp(argv
[0], argv
);