[RFC][PATCH] Add support for oom_score_adj
Marc - A. Dahlhaus
mad at wol.de
Sun Mar 13 18:29:32 UTC 2011
Hello List
I've added support for the oom_score_adj procfs file to upstart 1.0.
The old oom_adj procfs interface is deprecated and scheduled for removal.
Also usage of the old interface pollutes dmesg with warning messages.
I'll send updates for the test suite when this patch is in an acceptable form.
Please review and comment on the patch.
Thanks,
Marc
Signed-off-by: Marc - A. Dahlhaus <mad at wol.de>
--- a/init/errors.h
+++ b/init/errors.h
@@ -62,7 +62,8 @@ enum {
#define PARSE_ILLEGAL_EXIT_STR N_("Illegal exit status, expected integer")
#define PARSE_ILLEGAL_UMASK_STR N_("Illegal file creation mask, expected octal integer")
#define PARSE_ILLEGAL_NICE_STR N_("Illegal nice value, expected -20 to 19")
-#define PARSE_ILLEGAL_OOM_STR N_("Illegal oom adjustment, expected -16 to 15 or never")
+#define PARSE_ILLEGAL_OOM_STR N_("Illegal oom adjustment, expected -16 to 15 or 'never'")
+#define PARSE_ILLEGAL_OOM_SCORE_STR N_("Illegal oom score adjustment, expected -999 to 1000 or 'never'")
#define PARSE_ILLEGAL_LIMIT_STR N_("Illegal limit, expected 'unlimited' or integer")
#define PARSE_EXPECTED_EVENT_STR N_("Expected event")
#define PARSE_EXPECTED_OPERATOR_STR N_("Expected operator")
--- a/init/job_class.c
+++ b/init/job_class.c
@@ -212,6 +212,7 @@ job_class_new (const void *parent,
class->umask = JOB_DEFAULT_UMASK;
class->nice = 0;
class->oom_adj = 0;
+ class->oom_score_adj = 0;
for (i = 0; i < RLIMIT_NLIMITS; i++)
class->limits[i] = NULL;
--- a/init/job_class.h
+++ b/init/job_class.h
@@ -94,6 +94,7 @@ typedef enum console_type {
* @umask: file mode creation mask,
* @nice: process priority,
* @oom_adj: OOM killer adjustment,
+ * @oom_score_adj: OOM killer score adjustment,
* @limits: resource limits indexed by resource,
* @chroot: root directory of process (implies @chdir if not set),
* @chdir: working directory of process,
@@ -142,6 +143,7 @@ typedef struct job_class {
mode_t umask;
int nice;
int oom_adj;
+ int oom_score_adj;
struct rlimit *limits[RLIMIT_NLIMITS];
char *chroot;
char *chdir;
--- a/init/job_process.c
+++ b/init/job_process.c
@@ -363,7 +363,7 @@ job_process_spawn (JobClass *class,
{
sigset_t child_set, orig_set;
pid_t pid;
- int i, fds[2];
+ int i, fds[2], oom_value;
char filename[PATH_MAX];
FILE *fd;
@@ -487,14 +487,20 @@ job_process_spawn (JobClass *class,
*/
if (class->oom_adj) {
snprintf (filename, sizeof (filename),
- "/proc/%d/oom_adj", getpid ());
-
+ "/proc/%d/oom_score_adj", getpid ());
+ oom_value = class->oom_score_adj;
fd = fopen (filename, "w");
if (! fd) {
+ snprintf (filename, sizeof (filename),
+ "/proc/%d/oom_adj", getpid ());
+ oom_value = class->oom_adj;
+ fd = fopen (filename, "w");
+ }
+ if (! fd) {
nih_error_raise_system ();
job_process_error_abort (fds[1], JOB_PROCESS_ERROR_OOM_ADJ, 0);
} else {
- fprintf (fd, "%d\n", class->oom_adj);
+ fprintf (fd, "%d\n", oom_value);
if (fclose (fd)) {
nih_error_raise_system ();
--- a/init/parse_job.c
+++ b/init/parse_job.c
@@ -2247,12 +2247,43 @@ stanza_oom (JobClass *class,
if (! arg)
goto finish;
+ if (! strcmp (arg, "score")) {
+ nih_local char *scorearg = NULL;
+
+ scorearg = nih_config_next_arg (NULL, file, len,
+ &a_pos, &a_lineno);
+ if (! scorearg)
+ goto finish;
+
+ if (! strcmp (scorearg, "never")) {
+ class->oom_score_adj = -1000;
+ class->oom_adj = -17;
+ } else {
+ errno = 0;
+ class->oom_score_adj = (int)strtol (scorearg, &endptr, 10);
+ if (class->oom_adj == 0) {
+ class->oom_adj = (class->oom_score_adj * 16) / 1000;
+ if (class->oom_adj > 15)
+ class->oom_adj = 15;
+ }
+ if (errno || *endptr ||
+ (class->oom_score_adj < -1000) ||
+ (class->oom_score_adj > 1000))
+ nih_return_error (-1, PARSE_ILLEGAL_OOM,
+ _(PARSE_ILLEGAL_OOM_SCORE_STR));
+ }
+ }
+
if (! strcmp (arg, "never")) {
class->oom_adj = -17;
+ class->oom_score_adj = -1000;
} else {
errno = 0;
class->oom_adj = (int)strtol (arg, &endptr, 10);
- if (errno || *endptr || (class->oom_adj < -17) || (class->oom_adj > 15))
+ if (class->oom_score_adj == 0)
+ class->oom_score_adj = (class->oom_adj * 1000) / 17;
+ if (errno || *endptr || (class->oom_adj < -17) ||
+ (class->oom_adj > 15))
nih_return_error (-1, PARSE_ILLEGAL_OOM,
_(PARSE_ILLEGAL_OOM_STR));
}
More information about the upstart-devel
mailing list