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.
27 #include <linux/oom.h>
33 #include "closestream.h"
35 static void __attribute__((__noreturn__
)) usage(void)
38 fputs(USAGE_HEADER
, out
);
40 _(" %1$s [options] -p pid\n"
41 " %1$s [options] -n number -p pid\n"
42 " %1$s [options] -n number command [args...]]\n"),
43 program_invocation_short_name
);
45 fputs(USAGE_SEPARATOR
, out
);
46 fputs(_("Display and adjust OOM-killer score.\n"), out
);
48 fputs(USAGE_OPTIONS
, out
);
49 fputs(_(" -n, --adjust <num> specify the adjust score value\n"), out
);
50 fputs(_(" -p, --pid <num> process ID\n"), out
);
51 fputs(USAGE_SEPARATOR
, out
);
52 printf(USAGE_HELP_OPTIONS(24));
53 printf(USAGE_MAN_TAIL("choom(1)"));
57 static int get_score(const pid_t pid
)
59 return path_read_s32("/proc/%d/oom_score", (int) pid
);
62 static int get_score_adj(const pid_t pid
)
64 return path_read_s32("/proc/%d/oom_score_adj", (int) pid
);
67 static int set_score_adj(const pid_t pid
, int adj
)
69 char buf
[sizeof(stringify_value(OOM_SCORE_ADJ_MIN
))];
71 snprintf(buf
, sizeof(buf
), "%d", adj
);
73 if (path_write_str(buf
, "/proc/%d/oom_score_adj", (int) pid
) < 0)
78 int main(int argc
, char **argv
)
81 int c
, adj
= 0, has_adj
= 0;
83 static const struct option longopts
[] = {
84 { "adjust", required_argument
, NULL
, 'n' },
85 { "pid", required_argument
, NULL
, 'p' },
86 { "help", no_argument
, NULL
, 'h' },
87 { "version", no_argument
, NULL
, 'V' },
91 setlocale(LC_ALL
, "");
92 bindtextdomain(PACKAGE
, LOCALEDIR
);
96 while ((c
= getopt_long(argc
, argv
, "hn:p:V", longopts
, NULL
)) != -1) {
99 pid
= strtos32_or_err(optarg
, _("invalid PID argument"));
102 adj
= strtos32_or_err(optarg
, _("invalid adjust argument"));
106 printf(UTIL_LINUX_VERSION
);
111 errtryhelp(EXIT_FAILURE
);
115 if (optind
< argc
&& pid
) {
116 warnx(_("invalid argument: %s"), argv
[optind
]);
117 errtryhelp(EXIT_FAILURE
);
119 if (!pid
&& argc
- optind
< 1) {
120 warnx(_("no PID or COMMAND specified"));
121 errtryhelp(EXIT_FAILURE
);
123 if (optind
< argc
&& !has_adj
) {
124 warnx(_("no OOM score adjust value specified"));
125 errtryhelp(EXIT_FAILURE
);
130 printf(_("pid %d's current OOM score: %d\n"), pid
, get_score(pid
));
131 printf(_("pid %d's current OOM score adjust value: %d\n"), pid
, get_score_adj(pid
));
135 int old
= get_score_adj(pid
);
137 if (set_score_adj(pid
, adj
))
138 err(EXIT_FAILURE
, _("failed to set score adjust value"));
140 printf(_("pid %d's OOM score adjust value changed from %d to %d\n"), pid
, old
, adj
);
142 /* Start new process */
145 execvp(argv
[0], argv
);