Merge lp:~vorlon/upstart/default-priority-not-always-zero into lp:upstart

Proposed by Steve Langasek
Status: Merged
Merged at revision: 1412
Proposed branch: lp:~vorlon/upstart/default-priority-not-always-zero
Merge into: lp:upstart
Diff against target: 93 lines (+20/-6)
5 files modified
ChangeLog (+9/-0)
init/job_class.c (+3/-1)
init/job_class.h (+3/-3)
init/job_process.c (+2/-1)
init/tests/test_job_class.c (+3/-1)
To merge this branch: bzr merge lp:~vorlon/upstart/default-priority-not-always-zero
Reviewer Review Type Date Requested Status
James Hunt Approve
Review via email: mp+140025@code.launchpad.net

This proposal supersedes a proposal from 2012-11-18.

Description of the change

Upstart doesn't cope well when it can't set the nice level to 0, which may
be the case if the process is non-root and has been niced. So instead of
using 0 as the default, use the current nice level as the default; this
gives identical results in the common case, and there's really no reason a
non-root upstart should fail if niced.

To post a comment you must log in.
Revision history for this message
James Hunt (jamesodhunt) wrote : Posted in a previous version of this proposal

Hi Steve,

I think really we should be querying the priority when jobs are started since otherwise we effectively cache the priority such that if it is changed _after_ a Session Init is started, any newly-created user job will be run with the original priority.

I think the correct fix therefore is to modify job_process_spawn() to call getpriority() just prior to the setpriority() to deterine the current priority. We can retain the original behaviour if running as root *and* as PID 1, but not if only running as root (to allow for root running a Session Init).

review: Needs Fixing
Revision history for this message
James Hunt (jamesodhunt) wrote : Posted in a previous version of this proposal

Strike that first comment. What we actually need to do is:

- retain the original behaviour and set class->nice = 0.
- in job_process_spawn(), only call setpriority() if:
  - running as root and with PID 1.
  - not running as root and where 'class->nice > getpriority()'.

That way, Session Init job processes will by default just get the priority of their parent (whatever that has recently been set to). But if a user job attempts to lower the job priority explictly using the nice stanza, that will be honoured).

Revision history for this message
Steve Langasek (vorlon) wrote : Posted in a previous version of this proposal

Thanks for the review, James. You're right that my proposed solution falls a bit short. I think there are still some issues with your counterproposal as well, though:

 - a non-root session init process may have CAP_SYS_NICE set, in which case 'nice' settings in the job which raise the priority should be honored.
 - For root, if getpriority() != 0 and class->nice == 0, it's impossible to distinguish between a default and an explicitly-configured 'nice 0'. For the first, we should not be resetting the priority; for the second, we should be setting it.

and a lower-priority issue:

 - If the user session has a positive getpriority() value n, and a job foo has a 'nice' option m such that 0 < m < n, foo will be started with the same priority as all the other jobs, whereas it's likely the *intent* was to start it with a nice level m *higher* than the session (i.e., base+m where base is normally 0).

I'll put together a fix addressing the first two points (as well as the other points you brought up), then take the last to upstart-devel for discussion as it requires a syntax change.

Revision history for this message
James Hunt (jamesodhunt) wrote :

LGTM - merged.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2012-12-11 13:59:01 +0000
3+++ ChangeLog 2012-12-14 21:14:25 +0000
4@@ -1,3 +1,12 @@
5+2012-12-14 Steve Langasek <steve.langasek@ubuntu.com>
6+ * init/job_class.[ch]: instead of assuming a fixed value (0) as the
7+ default nice value for job processes, use whatever the nice value
8+ of the current process is. This will be important later for user
9+ sessions where an entire session may be started with a higher nice
10+ value; and it fixes running the test suite as part of a nice'd
11+ build.
12+ * init/tests/test_job_class.c: update test suite to match.
13+
14 2012-12-11 James Hunt <james.hunt@ubuntu.com>
15
16 * init/Makefile.am: Add explicit -lrt for tests (LP: #1088863)
17
18=== modified file 'init/job_class.c'
19--- init/job_class.c 2012-11-22 16:32:36 +0000
20+++ init/job_class.c 2012-12-14 21:14:25 +0000
21@@ -27,6 +27,8 @@
22 #include <errno.h>
23 #include <string.h>
24 #include <signal.h>
25+#include <sys/time.h>
26+#include <sys/resource.h>
27
28 #include <nih/macros.h>
29 #include <nih/alloc.h>
30@@ -219,7 +221,7 @@
31 class->console = default_console >= 0 ? default_console : CONSOLE_LOG;
32
33 class->umask = JOB_DEFAULT_UMASK;
34- class->nice = JOB_DEFAULT_NICE;
35+ class->nice = JOB_NICE_INVALID;
36 class->oom_score_adj = JOB_DEFAULT_OOM_SCORE_ADJ;
37
38 for (i = 0; i < RLIMIT_NLIMITS; i++)
39
40=== modified file 'init/job_class.h'
41--- init/job_class.h 2012-09-24 09:10:05 +0000
42+++ init/job_class.h 2012-12-14 21:14:25 +0000
43@@ -102,11 +102,11 @@
44 #define JOB_DEFAULT_UMASK 022
45
46 /**
47- * JOB_DEFAULT_NICE:
48+ * JOB_NICE_INVALID:
49 *
50- * The default nice level for processes.
51+ * The nice level for processes when no nice level is set.
52 **/
53-#define JOB_DEFAULT_NICE 0
54+#define JOB_NICE_INVALID -21
55
56 /**
57 * JOB_DEFAULT_OOM_SCORE_ADJ:
58
59=== modified file 'init/job_process.c'
60--- init/job_process.c 2012-12-03 20:27:09 +0000
61+++ init/job_process.c 2012-12-14 21:14:25 +0000
62@@ -780,7 +780,8 @@
63
64 /* Adjust the process priority ("nice level").
65 */
66- if (setpriority (PRIO_PROCESS, 0, class->nice) < 0) {
67+ if (class->nice != JOB_NICE_INVALID &&
68+ setpriority (PRIO_PROCESS, 0, class->nice) < 0) {
69 nih_error_raise_system ();
70 job_process_error_abort (fds[1],
71 JOB_PROCESS_ERROR_PRIORITY, 0);
72
73=== modified file 'init/tests/test_job_class.c'
74--- init/tests/test_job_class.c 2011-12-09 15:27:57 +0000
75+++ init/tests/test_job_class.c 2012-12-14 21:14:25 +0000
76@@ -27,6 +27,8 @@
77 #include <sys/wait.h>
78 #include <sys/ptrace.h>
79 #include <sys/select.h>
80+#include <sys/time.h>
81+#include <sys/resource.h>
82
83 #include <time.h>
84 #include <stdio.h>
85@@ -131,7 +133,7 @@
86 TEST_EQ (class->console, CONSOLE_LOG);
87
88 TEST_EQ (class->umask, 022);
89- TEST_EQ (class->nice, 0);
90+ TEST_EQ (class->nice, JOB_NICE_INVALID);
91 TEST_EQ (class->oom_score_adj, 0);
92
93 for (i = 0; i < RLIMIT_NLIMITS; i++)

Subscribers

People subscribed via source and target branches