Merge lp:~jamesodhunt/ubuntu/oneiric/upstart/fixes-for-user-sessions into lp:ubuntu/oneiric/upstart

Proposed by James Hunt
Status: Merged
Merge reported by: Sebastien Bacher
Merged at revision: not available
Proposed branch: lp:~jamesodhunt/ubuntu/oneiric/upstart/fixes-for-user-sessions
Merge into: lp:ubuntu/oneiric/upstart
Diff against target: 1957 lines (+991/-211)
13 files modified
ChangeLog (+34/-0)
TESTING.sessions (+38/-12)
debian/changelog (+7/-0)
init/job_process.c (+108/-58)
init/job_process.h (+1/-0)
init/man/init.5 (+16/-2)
init/session.c (+50/-9)
init/session.h (+13/-11)
po/en@boldquot.po (+54/-39)
po/en@quot.po (+54/-39)
po/upstart.pot (+54/-39)
util/man/initctl.8 (+9/-2)
util/tests/test_user_sessions.sh (+553/-0)
To merge this branch: bzr merge lp:~jamesodhunt/ubuntu/oneiric/upstart/fixes-for-user-sessions
Reviewer Review Type Date Requested Status
Michael Vogt (community) Approve
Ubuntu branches Pending
Review via email: mp+69125@code.launchpad.net

Description of the change

Quite a bit of change wrt user sessions. If someone could check my fixup for <email address hidden> and <email address hidden>, that'd be great! Thanks.

The details:

  * init/man/init.5: Explain that symbolic links are not supported.
  * init/session.c: session_from_dbus(): Handle case where a users
    home directory is changed or where a uid is re-used for a
    different username.
  * init/session.h: Updated comments for Session object.
  * TESTING.sessions: Updated with information on user sessions.
  * init/job_process.c:
    - job_process_spawn():
      - Change group before user and do it as early as possible.
      - Ensure non-priv user is able to read script fd. Default system
        behaviour is seemingly not consistent/defined, so force it
        to be (LP: #813052)
      - Ensure cwd for user job is home directory by default.
    - job_process_error_read():
      - Added handling for JOB_PROCESS_ERROR_SETUID and
        JOB_PROCESS_ERROR_SETGID (LP: #807293).
      - Added new entry for JOB_PROCESS_ERROR_CHOWN.
  * init/job_process.h:
    - Added entry for JOB_PROCESS_ERROR_CHOWN in JobProcessErrorType.
  * init/man/init.5: Update for user jobs explaining behaviour of stanzas
    which manipulate system resource limits and when the init
    daemon reads the users job directory.
  * util/tests/test_user_sessions.sh: New script for testing user sessions
    (NOTE: this is *NOT* run automatically).

To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote :

Looks good, I do a testbuild now and install it.

As for the <email address hidden> fixups this looks ok. Usually it should be enough to just
refresh the po files. The .gmo stuff is autogenerated and not part of the bzr tree.

review: Approve
Revision history for this message
Sebastien Bacher (seb128) wrote :

setting to merged since that got approved, the ubuntu Vcs seems outdated for some reason, I pointed it to slangasek

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2011-07-20 11:28:25 +0000
3+++ ChangeLog 2011-07-25 16:29:00 +0000
4@@ -1,3 +1,37 @@
5+2011-07-25 James Hunt <james.hunt@ubuntu.com>
6+
7+ * init/job_process.c: job_process_spawn():
8+ - Added dup2() return check.
9+ * TESTING.sessions: Updated with information on user sessions.
10+ * init/job_process.c:
11+ - job_process_spawn():
12+ - Change group before user and do it as early as possible.
13+ - Ensure non-priv user is able to read script fd. Default system
14+ behaviour is seemingly not consistent/defined, so force it
15+ to be (LP: #813052)
16+ - Ensure cwd for user job is home directory by default.
17+ - job_process_error_read():
18+ - Added handling for JOB_PROCESS_ERROR_SETUID and
19+ JOB_PROCESS_ERROR_SETGID (LP: #807293).
20+ - Added new entry for JOB_PROCESS_ERROR_CHOWN.
21+ * init/job_process.h:
22+ - Added entry for JOB_PROCESS_ERROR_CHOWN in JobProcessErrorType.
23+ * init/man/init.5: Update for user jobs explaining behaviour of stanzas
24+ which manipulate system resource limits and when the init
25+ daemon reads the users job directory.
26+ * util/tests/test_user_sessions.sh: New script for testing user sessions
27+ (NOTE: this is *NOT* run automatically).
28+ * init/session.c: session_from_dbus(): Handle case where a users
29+ home directory is changed or where a uid is re-used for a
30+ different username.
31+ * init/session.h: Updated comments for Session object.
32+ * init/man/init.5: Explain that symbolic links are not supported.
33+
34+2011-07-22 James Hunt <james.hunt@ubuntu.com>
35+
36+ * util/man/initctl.8: Clarify semantics of restart(8)
37+ command (LP: #731225).
38+
39 2011-07-20 James Hunt <james.hunt@ubuntu.com>
40
41 * util/tests/test_initctl.c:
42
43=== modified file 'TESTING.sessions'
44--- TESTING.sessions 2011-06-14 14:16:04 +0000
45+++ TESTING.sessions 2011-07-25 16:29:00 +0000
46@@ -4,25 +4,51 @@
47 Testing Sessions with Upstart
48 =============================
49
50-Upstart now has support for chroots which are implemented by creating a
51-separate session for every user within each chroot. It also has partial
52-support for user sessions, but since this is experimental (and disabled
53-in Ubuntu), this document does not cover testing this feature.
54+Upstart now has support for two types of "sessions":
55+
56+* user sessions
57+
58+* chroots sessions
59+
60+Such sessions are implemented by asociating a separate Upstart session
61+with every chroot environment and every non-privileged user.
62
63 The session support does not yet provide full tests (as would be run by
64-"``make check``"). This is partly due to the complexity of automatically
65+"``make check``"). This is mostly due to the complexity of automatically
66 testing some of the scenarios below.
67
68 This document attempts to outline the minimum set of tests that should
69-be performed to ensure that chroot support works as expected.
70+be performed to ensure that session support works as expected.
71
72 Assumptions
73 ===========
74
75 You are running an Ubuntu or Debian system.
76
77+User Sessions
78+=============
79+
80+User sessions can be minimally tested using the script provided::
81+
82+ util/tests/test_user_sessions.sh
83+
84+Notes:
85+
86+- Run "``test_user_sessions.sh -h``" to understand what this script does.
87+
88+- that this script needs to be run on a system where the version of
89+ ``/sbin/init`` has session support since the ``/sbin/init`` binary
90+ itself will be tested. For this reason, the script cannot be run as part
91+ of the "``make check``" run.
92+
93+- The script will complain loudly if any of the tests fail and tell you
94+ how to raise a bug.
95+
96+Chroot Sessions
97+===============
98+
99 Setup
100-=====
101+-----
102
103 #. Install a chroot environement (such as ``schroot(1)``) and configure it.
104 #. run, "``debootstrap(8)``" to install the same release as you are running into your chroot.
105@@ -80,7 +106,7 @@
106
107
108 Run as non-``root`` with no chroot
109-==================================
110+----------------------------------
111
112 - ``initctl list``
113
114@@ -118,7 +144,7 @@
115 Should fail ("``initctl: Rejected send message``").
116
117 Run as ``root`` with no chroot
118-==============================
119+------------------------------
120
121 - ``initctl list``
122
123@@ -183,7 +209,7 @@
124 - Ensure ``/path/to/chroot/etc/init/in_chroot.conf`` does *NOT* run.
125
126 Run as ``root`` inside a chroot
127-===============================
128+-------------------------------
129
130 - ``initctl list``
131
132@@ -247,12 +273,12 @@
133 - Ensure ``/etc/init/outside_chroot.conf`` does *NOT* run.
134
135 Run as non-root inside a chroot
136-===============================
137+-------------------------------
138
139 Not supported.
140
141 Run with ``--no-sessions``
142-==========================
143+--------------------------
144
145 The "``--no-sessions``" option makes Upstart behave as it used to prior to
146 the introduction of session support.
147
148=== modified file 'debian/changelog'
149--- debian/changelog 2011-07-20 13:52:23 +0000
150+++ debian/changelog 2011-07-25 16:29:00 +0000
151@@ -1,3 +1,10 @@
152+upstart (1.3-0ubuntu5) oneiric; urgency=low
153+
154+ * Upstream cherry-pick for user session fixes
155+ ("bzr merge -r 1318..1324 lp:upstart").
156+
157+ -- James Hunt <james.hunt@ubuntu.com> Mon, 25 Jul 2011 17:09:47 +0100
158+
159 upstart (1.3-0ubuntu4) oneiric; urgency=low
160
161 * init/main.c: main(): Add support for "/run" directory with fallback to
162
163=== modified file 'init/job_process.c'
164--- init/job_process.c 2011-06-16 14:39:55 +0000
165+++ init/job_process.c 2011-07-25 16:29:00 +0000
166@@ -373,14 +373,20 @@
167 int trace,
168 int script_fd)
169 {
170- sigset_t child_set, orig_set;
171- pid_t pid;
172- int i, fds[2];
173- char filename[PATH_MAX];
174- FILE *fd;
175+ sigset_t child_set, orig_set;
176+ pid_t pid;
177+ int i, fds[2];
178+ char filename[PATH_MAX];
179+ FILE *fd;
180+ int user_job = FALSE;
181+ nih_local char *user_dir = NULL;
182+
183
184 nih_assert (class != NULL);
185
186+ if (class && class->session && class->session->user)
187+ user_job = TRUE;
188+
189 /* Create a pipe to communicate with the child process until it
190 * execs so we know whether that was successful or an error occurred.
191 */
192@@ -440,6 +446,8 @@
193 if (fds[1] == JOB_PROCESS_SCRIPT_FD) {
194 int tmp = dup2 (fds[1], fds[0]);
195 close (fds[1]);
196+ if (tmp < 0)
197+ nih_return_system_error (-1);
198 fds[1] = tmp;
199 }
200 nih_io_set_cloexec (fds[1]);
201@@ -460,6 +468,84 @@
202 */
203 setsid ();
204
205+ /* Set the process environment from the function paramters. */
206+ environ = (char **)env;
207+
208+ /* Handle unprivileged user job by dropping privileges to
209+ * their level as soon as possible to avoid privilege
210+ * escalations when we set resource limits.
211+ */
212+ if (user_job) {
213+ uid_t uid = class->session->user;
214+ struct passwd *pw = NULL;
215+
216+ /* D-Bus does not expose a public API call to allow
217+ * us to query a users primary group.
218+ * _dbus_user_info_fill_uid () seems to exist for this
219+ * purpose, but is a "secret" API. It is unclear why
220+ * D-Bus neglects the gid when it allows the uid
221+ * to be queried directly.
222+ *
223+ * Our only recourse is to disallow user sessions in a
224+ * chroot and assume that all other user sessions
225+ * originate from the local system. In this way, we can
226+ * bypass D-Bus and use getpwuid ().
227+ */
228+
229+ if (class->session->chroot) {
230+ /* We cannot determine the group id of the user
231+ * session in the chroot via D-Bus, so disallow
232+ * all jobs in such an environment.
233+ */
234+ nih_return_error (-1, EPERM, "user jobs not supported in chroots");
235+ }
236+
237+ pw = getpwuid (uid);
238+
239+ if (!pw)
240+ nih_return_system_error (-1);
241+
242+ nih_assert (pw->pw_uid == uid);
243+
244+ if (! pw->pw_dir) {
245+ nih_local char *message = NIH_MUST (nih_sprintf (NULL,
246+ "no home directory for user with uid %d",
247+ uid));
248+
249+ nih_return_error (-1, ENOENT, message);
250+
251+ }
252+
253+ /* Note we don't use NIH_MUST since this could result in a
254+ * DOS for a (low priority) user job in low-memory scenarios.
255+ */
256+ user_dir = nih_strdup (NULL, pw->pw_dir);
257+
258+ if (!user_dir)
259+ nih_return_no_memory_error (-1);
260+
261+ /* Ensure the file associated with fd 9
262+ * (/proc/self/fd/9) is owned by the user we're about to
263+ * become to avoid EPERM.
264+ */
265+ if (script_fd != -1 && fchown (script_fd, pw->pw_uid, pw->pw_gid) < 0) {
266+ nih_error_raise_system ();
267+ job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CHOWN, 0);
268+ }
269+
270+ if (pw->pw_gid && setgid (pw->pw_gid) < 0) {
271+ nih_error_raise_system ();
272+ job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0);
273+ }
274+
275+ if (pw->pw_uid && setuid (pw->pw_uid) < 0) {
276+ nih_error_raise_system ();
277+ job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0);
278+ }
279+
280+
281+ }
282+
283 /* Set the standard file descriptors to an output of our chosing;
284 * any other open descriptor must be intended for the child, or have
285 * the FD_CLOEXEC flag so it's automatically closed when we exec()
286@@ -480,6 +566,7 @@
287 job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CONSOLE, 0);
288 }
289
290+
291 /* Set resource limits for the process, skipping over any that
292 * aren't set in the job class such that they inherit from
293 * ourselves (and we inherit from kernel defaults).
294@@ -495,9 +582,6 @@
295 }
296 }
297
298- /* Set the process environment from the function paramters. */
299- environ = (char **)env;
300-
301 /* Set the file mode creation mask; this is one of the few operations
302 * that can never fail.
303 */
304@@ -565,12 +649,11 @@
305 * configured in the job, or to the root directory of the filesystem
306 * (or at least relative to the chroot).
307 */
308- if (chdir (class->chdir ? class->chdir : "/") < 0) {
309+ if (chdir (class->chdir ? class->chdir : user_job ? user_dir : "/") < 0) {
310 nih_error_raise_system ();
311 job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CHDIR, 0);
312 }
313
314-
315 /* Reset all the signal handlers back to their default handling so
316 * the child isn't unexpectedly ignoring any, and so we won't
317 * surprisingly handle them before we've exec()d the new process.
318@@ -604,54 +687,6 @@
319 }
320 }
321
322- /* Handle unprivileged user job by dropping privileges to
323- * their level.
324- */
325- if (class->session && class->session->user) {
326- uid_t uid = class->session->user;
327- struct passwd *pw = NULL;
328-
329- /* D-Bus does not expose a public API call to allow
330- * us to query a users primary group.
331- * _dbus_user_info_fill_uid () seems to exist for this
332- * purpose, but is a "secret" API. It is unclear why
333- * D-Bus neglects the gid when it allows the uid
334- * to be queried directly.
335- *
336- * Our only recourse is to disallow user sessions in a
337- * chroot and assume that all other user sessions
338- * originate from the local system. In this way, we can
339- * bypass D-Bus and use getpwuid ().
340- */
341-
342- if (class->session->chroot) {
343- /* We cannot determine the group id of the user
344- * session in the chroot via D-Bus, so disallow
345- * all jobs in such an environment.
346- */
347- _nih_error_raise (__FILE__, __LINE__, __FUNCTION__,
348- EPERM, strerror (EPERM));
349- }
350-
351- pw = getpwuid (uid);
352-
353- if (!pw)
354- nih_return_system_error (-1);
355-
356- nih_assert (pw->pw_uid == uid);
357-
358- if (uid && setuid (uid) < 0) {
359- nih_error_raise_system ();
360- job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0);
361- }
362-
363- if (pw->pw_gid && setgid (pw->pw_gid) < 0) {
364- nih_error_raise_system ();
365- job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0);
366- }
367- }
368-
369-
370 /* Execute the process, if we escape from here it failed */
371 if (execvp (argv[0], argv) < 0) {
372 nih_error_raise_system ();
373@@ -845,6 +880,21 @@
374 err, _("unable to execute: %s"),
375 strerror (err->errnum)));
376 break;
377+ case JOB_PROCESS_ERROR_SETUID:
378+ err->error.message = NIH_MUST (nih_sprintf (
379+ err, _("unable to setuid: %s"),
380+ strerror (err->errnum)));
381+ break;
382+ case JOB_PROCESS_ERROR_SETGID:
383+ err->error.message = NIH_MUST (nih_sprintf (
384+ err, _("unable to setgid: %s"),
385+ strerror (err->errnum)));
386+ break;
387+ case JOB_PROCESS_ERROR_CHOWN:
388+ err->error.message = NIH_MUST (nih_sprintf (
389+ err, _("unable to chown: %s"),
390+ strerror (err->errnum)));
391+ break;
392 default:
393 nih_assert_not_reached ();
394 }
395
396=== modified file 'init/job_process.h'
397--- init/job_process.h 2011-06-16 14:39:55 +0000
398+++ init/job_process.h 2011-07-25 16:29:00 +0000
399@@ -59,6 +59,7 @@
400 JOB_PROCESS_ERROR_EXEC,
401 JOB_PROCESS_ERROR_SETUID,
402 JOB_PROCESS_ERROR_SETGID,
403+ JOB_PROCESS_ERROR_CHOWN
404 } JobProcessErrorType;
405
406 /**
407
408=== modified file 'init/man/init.5'
409--- init/man/init.5 2011-06-16 14:39:55 +0000
410+++ init/man/init.5 2011-07-25 16:29:00 +0000
411@@ -77,8 +77,12 @@
412 A User Job is a job configuration file created by a non\-privileged user
413 in their
414 .B $HOME/.init/
415-directory. Job configuration files in this directory have
416-the same syntax as system job configuration files.
417+directory. Job configuration files in this directory have the same
418+syntax as system job configuration files.
419+Files in this directory will be read and an
420+.BR inotify (7)
421+watch created the first time a user runs
422+.BR initctl (8) "."
423
424 Any user can create user jobs, but that user can control
425 .I only
426@@ -88,6 +92,10 @@
427 .BR initctl (8)
428 facility.
429
430+Note that stanzas which manipulate resources limits may cause a job to
431+fail to start should the value provided to such a stanza attempt to
432+exceed the maximum value the users privilege level allows.
433+
434 Note that a user job configuration file cannot have the same name as a
435 system job configuration file.
436 .\"
437@@ -749,6 +757,12 @@
438 is unable to supervise forking processes and will believe them to have
439 stopped as soon as they fork on startup.
440 .\"
441+.SH RESTRICTIONS
442+The use of symbolic links in job configuration file directories is not
443+supported since it can lead to unpredicable behaviour resulting from
444+broken or inaccessible links (such as would be caused by a link crossing
445+a filesystem boundary to a filesystem that has not yet been mounted).
446+.\"
447 .SH BUGS
448 The
449 .B and
450
451=== modified file 'init/session.c'
452--- init/session.c 2011-06-16 14:39:55 +0000
453+++ init/session.c 2011-07-25 16:29:00 +0000
454@@ -124,12 +124,14 @@
455 session_from_dbus (const void *parent,
456 NihDBusMessage *message)
457 {
458- const char *sender;
459- DBusError dbus_error;
460- unsigned long unix_user;
461- unsigned long unix_process_id;
462- char root[PATH_MAX];
463- Session *session;
464+ const char *sender;
465+ DBusError dbus_error;
466+ unsigned long unix_user;
467+ unsigned long unix_process_id;
468+ char root[PATH_MAX];
469+ Session *session;
470+ struct passwd *pwd;
471+ nih_local char *conf_path = NULL;
472
473 nih_assert (message != NULL);
474
475@@ -192,11 +194,25 @@
476 } else if (! unix_user) {
477 /* No process id or user id found, return the NULL session */
478 return NULL;
479-
480- }
481+ }
482+
483+ if (unix_user) {
484+ pwd = getpwuid (unix_user);
485+
486+ if (! pwd || ! pwd->pw_dir) {
487+ nih_error ("%lu: %s: %s", unix_user,
488+ _("Unable to lookup home directory"),
489+ strerror (errno));
490+ return NULL;
491+ }
492+
493+ NIH_MUST (nih_strcat_sprintf (&conf_path, NULL, "%s/%s",
494+ pwd->pw_dir, USERCONFDIR));
495+ }
496+
497
498 /* Now find in the existing Sessions list */
499- NIH_LIST_FOREACH (sessions, iter) {
500+ NIH_LIST_FOREACH_SAFE (sessions, iter) {
501 Session *session = (Session *)iter;
502
503 if (unix_process_id) {
504@@ -212,6 +228,31 @@
505 if (unix_user != session->user)
506 continue;
507
508+ /* Found a user with the same uid but different
509+ * conf_dir to the existing session user. Either the
510+ * original user has been deleted and a new user created
511+ * with the same uid, or the original users home
512+ * directory has changed since they first started
513+ * running jobs. Whatever the reason, we (can only) honour
514+ * the new value.
515+ *
516+ * Since multiple users with the same uid are considered
517+ * to be "the same user", invalidate the old path,
518+ * allowing the correct new path to be set below.
519+ *
520+ * Note that there may be a possibility of trouble if
521+ * the scenario relates to a deleted user and that original
522+ * user still has jobs running. However, if that were the
523+ * case, those jobs would likely fail anyway since they
524+ * would have no working directory due to the original
525+ * users home directory being deleted/changed/made inaccessible.
526+ */
527+ if (unix_user && conf_path && session->conf_path &&
528+ strcmp (conf_path, session->conf_path)) {
529+ nih_free (session->conf_path);
530+ session->conf_path = NULL;
531+ }
532+
533 if (! session->conf_path)
534 session_create_conf_source (session);
535
536
537=== modified file 'init/session.h'
538--- init/session.h 2011-06-16 14:39:55 +0000
539+++ init/session.h 2011-07-25 16:29:00 +0000
540@@ -33,23 +33,25 @@
541 * @entry: list header,
542 * @chroot: path all jobs are chrooted to,
543 * @user: uid all jobs are switched to,
544- * @conf_path: configuration path.
545+ * @conf_path: configuration path (either full path to chroot root, or
546+ * full path to users job directory (which may itself be prepended
547+ * with a chroot path)).
548 *
549 * This structure is used to identify collections of jobs
550 * that share either a common @chroot and/or common @user.
551 *
552 * Summary of Session values for different environments:
553 *
554- * +-------------+---------------------------------------+
555- * | D-Bus | Session |
556- * +------+------+--------+-----+------------------------+
557- * | user | PID | chroot | uid | Object contents |
558- * +------+------+--------+-----+------------------------+
559- * | 0 | >0 | no | 0 | NULL (*1) |
560- * | >0 | "0" | no | >0 | only uid set. |
561- * | 0 | >0 | yes | 0 | chroot + conf_path set |
562- * | >0 | ?? | yes | >0 | XXX: fails (*2) |
563- * +------+------+--------+-----+------------------------+
564+ * +-------------+--------------------------------------------------+
565+ * | D-Bus | Session |
566+ * +------+------+--------+-----+-----------------------------------+
567+ * | user | PID | chroot | uid | Object contents |
568+ * +------+------+--------+-----+-----------------------------------+
569+ * | 0 | >0 | no | 0 | NULL (*1) |
570+ * | >0 | "0" | no | >0 | uid + conf_path set to "~/.init". |
571+ * | 0 | >0 | yes | 0 | chroot + conf_path set |
572+ * | >0 | ?? | yes | >0 | XXX: fails (*2) |
573+ * +------+------+--------+-----+-----------------------------------+
574 *
575 * Notes:
576 *
577
578=== modified file 'po/en@boldquot.po'
579--- po/en@boldquot.po 2011-06-16 14:39:55 +0000
580+++ po/en@boldquot.po 2011-07-25 16:29:00 +0000
581@@ -32,7 +32,7 @@
582 msgstr ""
583 "Project-Id-Version: upstart 1.3\n"
584 "Report-Msgid-Bugs-To: new@bugs.launchpad.net\n"
585-"POT-Creation-Date: 2011-06-16 15:04+0100\n"
586+"POT-Creation-Date: 2011-07-25 17:06+0100\n"
587 "PO-Revision-Date: 2011-06-16 15:04+0100\n"
588 "Last-Translator: Automatically generated\n"
589 "Language-Team: none\n"
590@@ -88,7 +88,7 @@
591 msgid "Disconnected from system bus"
592 msgstr "Disconnected from system bus"
593
594-#: init/control.c:370 init/main.c:744
595+#: init/control.c:370 init/main.c:754
596 msgid "Reloading configuration"
597 msgstr "Reloading configuration"
598
599@@ -298,152 +298,167 @@
600 msgid "%s %s process (%d)"
601 msgstr "%s %s process (%d)"
602
603-#: init/job_process.c:403
604+#: init/job_process.c:409
605 #, c-format
606 msgid "Pausing %s (%d) [pre-exec] for debug"
607 msgstr "Pausing %s (%d) [pre-exec] for debug"
608
609-#: init/job_process.c:473
610+#: init/job_process.c:559
611 #, c-format
612 msgid "Failed to open system console: %s"
613 msgstr "Failed to open system console: %s"
614
615-#: init/job_process.c:755
616+#: init/job_process.c:790
617 #, c-format
618 msgid "unable to move script fd: %s"
619 msgstr "unable to move script fd: %s"
620
621-#: init/job_process.c:760
622+#: init/job_process.c:795
623 #, c-format
624 msgid "unable to open console: %s"
625 msgstr "unable to open console: %s"
626
627-#: init/job_process.c:815
628+#: init/job_process.c:850
629 #, c-format
630 msgid "unable to set \"%s\" resource limit: %s"
631 msgstr "unable to set “%s” resource limit: %s"
632
633-#: init/job_process.c:820
634+#: init/job_process.c:855
635 #, c-format
636 msgid "unable to set priority: %s"
637 msgstr "unable to set priority: %s"
638
639-#: init/job_process.c:825
640+#: init/job_process.c:860
641 #, c-format
642 msgid "unable to set oom adjustment: %s"
643 msgstr "unable to set oom adjustment: %s"
644
645-#: init/job_process.c:830
646+#: init/job_process.c:865
647 #, c-format
648 msgid "unable to change root directory: %s"
649 msgstr "unable to change root directory: %s"
650
651-#: init/job_process.c:835
652+#: init/job_process.c:870
653 #, c-format
654 msgid "unable to change working directory: %s"
655 msgstr "unable to change working directory: %s"
656
657-#: init/job_process.c:840
658+#: init/job_process.c:875
659 #, c-format
660 msgid "unable to set trace: %s"
661 msgstr "unable to set trace: %s"
662
663-#: init/job_process.c:845
664+#: init/job_process.c:880
665 #, c-format
666 msgid "unable to execute: %s"
667 msgstr "unable to execute: %s"
668
669-#: init/job_process.c:876 init/job_process.c:926
670+#: init/job_process.c:885
671+#, fuzzy, c-format
672+msgid "unable to setuid: %s"
673+msgstr "unable to set trace: %s"
674+
675+#: init/job_process.c:890
676+#, fuzzy, c-format
677+msgid "unable to setgid: %s"
678+msgstr "unable to set trace: %s"
679+
680+#: init/job_process.c:895
681+#, fuzzy, c-format
682+msgid "unable to chown: %s"
683+msgstr "unable to open console: %s"
684+
685+#: init/job_process.c:926 init/job_process.c:976
686 #, c-format
687 msgid "Sending %s signal to %s %s process (%d)"
688 msgstr "Sending %s signal to %s %s process (%d)"
689
690-#: init/job_process.c:885 init/job_process.c:935
691+#: init/job_process.c:935 init/job_process.c:985
692 #, c-format
693 msgid "Failed to send %s signal to %s %s process (%d): %s"
694 msgstr "Failed to send %s signal to %s %s process (%d): %s"
695
696-#: init/job_process.c:996
697+#: init/job_process.c:1046
698 #, c-format
699 msgid "%s %s process (%d) terminated with status %d"
700 msgstr "%s %s process (%d) terminated with status %d"
701
702-#: init/job_process.c:1001
703+#: init/job_process.c:1051
704 #, c-format
705 msgid "%s %s process (%d) exited normally"
706 msgstr "%s %s process (%d) exited normally"
707
708-#: init/job_process.c:1016
709+#: init/job_process.c:1066
710 #, c-format
711 msgid "%s %s process (%d) killed by %s signal"
712 msgstr "%s %s process (%d) killed by %s signal"
713
714-#: init/job_process.c:1020
715+#: init/job_process.c:1070
716 #, c-format
717 msgid "%s %s process (%d) killed by signal %d"
718 msgstr "%s %s process (%d) killed by signal %d"
719
720-#: init/job_process.c:1034
721+#: init/job_process.c:1084
722 #, c-format
723 msgid "%s %s process (%d) stopped by %s signal"
724 msgstr "%s %s process (%d) stopped by %s signal"
725
726-#: init/job_process.c:1038
727+#: init/job_process.c:1088
728 #, c-format
729 msgid "%s %s process (%d) stopped by signal %d"
730 msgstr "%s %s process (%d) stopped by signal %d"
731
732-#: init/job_process.c:1052
733+#: init/job_process.c:1102
734 #, c-format
735 msgid "%s %s process (%d) continued by %s signal"
736 msgstr "%s %s process (%d) continued by %s signal"
737
738-#: init/job_process.c:1056
739+#: init/job_process.c:1106
740 #, c-format
741 msgid "%s %s process (%d) continued by signal %d"
742 msgstr "%s %s process (%d) continued by signal %d"
743
744-#: init/job_process.c:1191
745+#: init/job_process.c:1241
746 #, c-format
747 msgid "%s respawning too fast, stopped"
748 msgstr "%s respawning too fast, stopped"
749
750-#: init/job_process.c:1197
751+#: init/job_process.c:1247
752 #, c-format
753 msgid "%s %s process ended, respawning"
754 msgstr "%s %s process ended, respawning"
755
756-#: init/job_process.c:1437
757+#: init/job_process.c:1487
758 #, c-format
759 msgid "Failed to set ptrace options for %s %s process (%d): %s"
760 msgstr "Failed to set ptrace options for %s %s process (%d): %s"
761
762-#: init/job_process.c:1450 init/job_process.c:1645
763+#: init/job_process.c:1500 init/job_process.c:1695
764 #, c-format
765 msgid "Failed to continue traced %s %s process (%d): %s"
766 msgstr "Failed to continue traced %s %s process (%d): %s"
767
768-#: init/job_process.c:1490 init/job_process.c:1581 init/job_process.c:1636
769+#: init/job_process.c:1540 init/job_process.c:1631 init/job_process.c:1686
770 #, c-format
771 msgid "Failed to detach traced %s %s process (%d): %s"
772 msgstr "Failed to detach traced %s %s process (%d): %s"
773
774-#: init/job_process.c:1530
775+#: init/job_process.c:1580
776 #, c-format
777 msgid "Failed to deliver signal to traced %s %s process (%d): %s"
778 msgstr "Failed to deliver signal to traced %s %s process (%d): %s"
779
780-#: init/job_process.c:1565
781+#: init/job_process.c:1615
782 #, c-format
783 msgid "Failed to obtain child process id for %s %s process (%d): %s"
784 msgstr "Failed to obtain child process id for %s %s process (%d): %s"
785
786-#: init/job_process.c:1572
787+#: init/job_process.c:1622
788 #, c-format
789 msgid "%s %s process (%d) became new process (%d)"
790 msgstr "%s %s process (%d) became new process (%d)"
791
792-#: init/job_process.c:1631
793+#: init/job_process.c:1681
794 #, c-format
795 msgid "%s %s process (%d) executable changed"
796 msgstr "%s %s process (%d) executable changed"
797@@ -490,7 +505,7 @@
798 msgid "Not being executed as init"
799 msgstr "Not being executed as init"
800
801-#: init/main.c:238 init/main.c:601
802+#: init/main.c:238 init/main.c:611
803 msgid "Unable to set root directory"
804 msgstr "Unable to set root directory"
805
806@@ -506,31 +521,31 @@
807 msgid "Unable to listen for private connections"
808 msgstr "Unable to listen for private connections"
809
810-#: init/main.c:618
811+#: init/main.c:628
812 #, c-format
813 msgid "Caught %s, core dumped"
814 msgstr "Caught %s, core dumped"
815
816-#: init/main.c:622
817+#: init/main.c:632
818 #, c-format
819 msgid "Caught %s, unable to dump core"
820 msgstr "Caught %s, unable to dump core"
821
822-#: init/main.c:651
823+#: init/main.c:661
824 #, c-format
825 msgid "Re-executing %s"
826 msgstr "Re-executing %s"
827
828-#: init/main.c:676
829+#: init/main.c:686
830 #, c-format
831 msgid "Failed to re-execute %s: %s"
832 msgstr "Failed to re-execute %s: %s"
833
834-#: init/main.c:761
835+#: init/main.c:771
836 msgid "Reconnecting to system bus"
837 msgstr "Reconnecting to system bus"
838
839-#: init/main.c:767
840+#: init/main.c:777
841 msgid "Unable to connect to the system bus"
842 msgstr "Unable to connect to the system bus"
843
844
845=== modified file 'po/en@quot.po'
846--- po/en@quot.po 2011-06-16 14:39:55 +0000
847+++ po/en@quot.po 2011-07-25 16:29:00 +0000
848@@ -29,7 +29,7 @@
849 msgstr ""
850 "Project-Id-Version: upstart 1.3\n"
851 "Report-Msgid-Bugs-To: new@bugs.launchpad.net\n"
852-"POT-Creation-Date: 2011-06-16 15:04+0100\n"
853+"POT-Creation-Date: 2011-07-25 17:06+0100\n"
854 "PO-Revision-Date: 2011-06-16 15:04+0100\n"
855 "Last-Translator: Automatically generated\n"
856 "Language-Team: none\n"
857@@ -85,7 +85,7 @@
858 msgid "Disconnected from system bus"
859 msgstr "Disconnected from system bus"
860
861-#: init/control.c:370 init/main.c:744
862+#: init/control.c:370 init/main.c:754
863 msgid "Reloading configuration"
864 msgstr "Reloading configuration"
865
866@@ -295,152 +295,167 @@
867 msgid "%s %s process (%d)"
868 msgstr "%s %s process (%d)"
869
870-#: init/job_process.c:403
871+#: init/job_process.c:409
872 #, c-format
873 msgid "Pausing %s (%d) [pre-exec] for debug"
874 msgstr "Pausing %s (%d) [pre-exec] for debug"
875
876-#: init/job_process.c:473
877+#: init/job_process.c:559
878 #, c-format
879 msgid "Failed to open system console: %s"
880 msgstr "Failed to open system console: %s"
881
882-#: init/job_process.c:755
883+#: init/job_process.c:790
884 #, c-format
885 msgid "unable to move script fd: %s"
886 msgstr "unable to move script fd: %s"
887
888-#: init/job_process.c:760
889+#: init/job_process.c:795
890 #, c-format
891 msgid "unable to open console: %s"
892 msgstr "unable to open console: %s"
893
894-#: init/job_process.c:815
895+#: init/job_process.c:850
896 #, c-format
897 msgid "unable to set \"%s\" resource limit: %s"
898 msgstr "unable to set “%s” resource limit: %s"
899
900-#: init/job_process.c:820
901+#: init/job_process.c:855
902 #, c-format
903 msgid "unable to set priority: %s"
904 msgstr "unable to set priority: %s"
905
906-#: init/job_process.c:825
907+#: init/job_process.c:860
908 #, c-format
909 msgid "unable to set oom adjustment: %s"
910 msgstr "unable to set oom adjustment: %s"
911
912-#: init/job_process.c:830
913+#: init/job_process.c:865
914 #, c-format
915 msgid "unable to change root directory: %s"
916 msgstr "unable to change root directory: %s"
917
918-#: init/job_process.c:835
919+#: init/job_process.c:870
920 #, c-format
921 msgid "unable to change working directory: %s"
922 msgstr "unable to change working directory: %s"
923
924-#: init/job_process.c:840
925+#: init/job_process.c:875
926 #, c-format
927 msgid "unable to set trace: %s"
928 msgstr "unable to set trace: %s"
929
930-#: init/job_process.c:845
931+#: init/job_process.c:880
932 #, c-format
933 msgid "unable to execute: %s"
934 msgstr "unable to execute: %s"
935
936-#: init/job_process.c:876 init/job_process.c:926
937+#: init/job_process.c:885
938+#, fuzzy, c-format
939+msgid "unable to setuid: %s"
940+msgstr "unable to set trace: %s"
941+
942+#: init/job_process.c:890
943+#, fuzzy, c-format
944+msgid "unable to setgid: %s"
945+msgstr "unable to set trace: %s"
946+
947+#: init/job_process.c:895
948+#, fuzzy, c-format
949+msgid "unable to chown: %s"
950+msgstr "unable to open console: %s"
951+
952+#: init/job_process.c:926 init/job_process.c:976
953 #, c-format
954 msgid "Sending %s signal to %s %s process (%d)"
955 msgstr "Sending %s signal to %s %s process (%d)"
956
957-#: init/job_process.c:885 init/job_process.c:935
958+#: init/job_process.c:935 init/job_process.c:985
959 #, c-format
960 msgid "Failed to send %s signal to %s %s process (%d): %s"
961 msgstr "Failed to send %s signal to %s %s process (%d): %s"
962
963-#: init/job_process.c:996
964+#: init/job_process.c:1046
965 #, c-format
966 msgid "%s %s process (%d) terminated with status %d"
967 msgstr "%s %s process (%d) terminated with status %d"
968
969-#: init/job_process.c:1001
970+#: init/job_process.c:1051
971 #, c-format
972 msgid "%s %s process (%d) exited normally"
973 msgstr "%s %s process (%d) exited normally"
974
975-#: init/job_process.c:1016
976+#: init/job_process.c:1066
977 #, c-format
978 msgid "%s %s process (%d) killed by %s signal"
979 msgstr "%s %s process (%d) killed by %s signal"
980
981-#: init/job_process.c:1020
982+#: init/job_process.c:1070
983 #, c-format
984 msgid "%s %s process (%d) killed by signal %d"
985 msgstr "%s %s process (%d) killed by signal %d"
986
987-#: init/job_process.c:1034
988+#: init/job_process.c:1084
989 #, c-format
990 msgid "%s %s process (%d) stopped by %s signal"
991 msgstr "%s %s process (%d) stopped by %s signal"
992
993-#: init/job_process.c:1038
994+#: init/job_process.c:1088
995 #, c-format
996 msgid "%s %s process (%d) stopped by signal %d"
997 msgstr "%s %s process (%d) stopped by signal %d"
998
999-#: init/job_process.c:1052
1000+#: init/job_process.c:1102
1001 #, c-format
1002 msgid "%s %s process (%d) continued by %s signal"
1003 msgstr "%s %s process (%d) continued by %s signal"
1004
1005-#: init/job_process.c:1056
1006+#: init/job_process.c:1106
1007 #, c-format
1008 msgid "%s %s process (%d) continued by signal %d"
1009 msgstr "%s %s process (%d) continued by signal %d"
1010
1011-#: init/job_process.c:1191
1012+#: init/job_process.c:1241
1013 #, c-format
1014 msgid "%s respawning too fast, stopped"
1015 msgstr "%s respawning too fast, stopped"
1016
1017-#: init/job_process.c:1197
1018+#: init/job_process.c:1247
1019 #, c-format
1020 msgid "%s %s process ended, respawning"
1021 msgstr "%s %s process ended, respawning"
1022
1023-#: init/job_process.c:1437
1024+#: init/job_process.c:1487
1025 #, c-format
1026 msgid "Failed to set ptrace options for %s %s process (%d): %s"
1027 msgstr "Failed to set ptrace options for %s %s process (%d): %s"
1028
1029-#: init/job_process.c:1450 init/job_process.c:1645
1030+#: init/job_process.c:1500 init/job_process.c:1695
1031 #, c-format
1032 msgid "Failed to continue traced %s %s process (%d): %s"
1033 msgstr "Failed to continue traced %s %s process (%d): %s"
1034
1035-#: init/job_process.c:1490 init/job_process.c:1581 init/job_process.c:1636
1036+#: init/job_process.c:1540 init/job_process.c:1631 init/job_process.c:1686
1037 #, c-format
1038 msgid "Failed to detach traced %s %s process (%d): %s"
1039 msgstr "Failed to detach traced %s %s process (%d): %s"
1040
1041-#: init/job_process.c:1530
1042+#: init/job_process.c:1580
1043 #, c-format
1044 msgid "Failed to deliver signal to traced %s %s process (%d): %s"
1045 msgstr "Failed to deliver signal to traced %s %s process (%d): %s"
1046
1047-#: init/job_process.c:1565
1048+#: init/job_process.c:1615
1049 #, c-format
1050 msgid "Failed to obtain child process id for %s %s process (%d): %s"
1051 msgstr "Failed to obtain child process id for %s %s process (%d): %s"
1052
1053-#: init/job_process.c:1572
1054+#: init/job_process.c:1622
1055 #, c-format
1056 msgid "%s %s process (%d) became new process (%d)"
1057 msgstr "%s %s process (%d) became new process (%d)"
1058
1059-#: init/job_process.c:1631
1060+#: init/job_process.c:1681
1061 #, c-format
1062 msgid "%s %s process (%d) executable changed"
1063 msgstr "%s %s process (%d) executable changed"
1064@@ -487,7 +502,7 @@
1065 msgid "Not being executed as init"
1066 msgstr "Not being executed as init"
1067
1068-#: init/main.c:238 init/main.c:601
1069+#: init/main.c:238 init/main.c:611
1070 msgid "Unable to set root directory"
1071 msgstr "Unable to set root directory"
1072
1073@@ -503,31 +518,31 @@
1074 msgid "Unable to listen for private connections"
1075 msgstr "Unable to listen for private connections"
1076
1077-#: init/main.c:618
1078+#: init/main.c:628
1079 #, c-format
1080 msgid "Caught %s, core dumped"
1081 msgstr "Caught %s, core dumped"
1082
1083-#: init/main.c:622
1084+#: init/main.c:632
1085 #, c-format
1086 msgid "Caught %s, unable to dump core"
1087 msgstr "Caught %s, unable to dump core"
1088
1089-#: init/main.c:651
1090+#: init/main.c:661
1091 #, c-format
1092 msgid "Re-executing %s"
1093 msgstr "Re-executing %s"
1094
1095-#: init/main.c:676
1096+#: init/main.c:686
1097 #, c-format
1098 msgid "Failed to re-execute %s: %s"
1099 msgstr "Failed to re-execute %s: %s"
1100
1101-#: init/main.c:761
1102+#: init/main.c:771
1103 msgid "Reconnecting to system bus"
1104 msgstr "Reconnecting to system bus"
1105
1106-#: init/main.c:767
1107+#: init/main.c:777
1108 msgid "Unable to connect to the system bus"
1109 msgstr "Unable to connect to the system bus"
1110
1111
1112=== modified file 'po/upstart.pot'
1113--- po/upstart.pot 2011-06-16 14:39:55 +0000
1114+++ po/upstart.pot 2011-07-25 16:29:00 +0000
1115@@ -8,7 +8,7 @@
1116 msgstr ""
1117 "Project-Id-Version: upstart 1.3\n"
1118 "Report-Msgid-Bugs-To: new@bugs.launchpad.net\n"
1119-"POT-Creation-Date: 2011-06-16 15:04+0100\n"
1120+"POT-Creation-Date: 2011-07-25 17:06+0100\n"
1121 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1122 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1123 "Language-Team: LANGUAGE <LL@li.org>\n"
1124@@ -63,7 +63,7 @@
1125 msgid "Disconnected from system bus"
1126 msgstr ""
1127
1128-#: init/control.c:370 init/main.c:744
1129+#: init/control.c:370 init/main.c:754
1130 msgid "Reloading configuration"
1131 msgstr ""
1132
1133@@ -273,152 +273,167 @@
1134 msgid "%s %s process (%d)"
1135 msgstr ""
1136
1137-#: init/job_process.c:403
1138+#: init/job_process.c:409
1139 #, c-format
1140 msgid "Pausing %s (%d) [pre-exec] for debug"
1141 msgstr ""
1142
1143-#: init/job_process.c:473
1144+#: init/job_process.c:559
1145 #, c-format
1146 msgid "Failed to open system console: %s"
1147 msgstr ""
1148
1149-#: init/job_process.c:755
1150+#: init/job_process.c:790
1151 #, c-format
1152 msgid "unable to move script fd: %s"
1153 msgstr ""
1154
1155-#: init/job_process.c:760
1156+#: init/job_process.c:795
1157 #, c-format
1158 msgid "unable to open console: %s"
1159 msgstr ""
1160
1161-#: init/job_process.c:815
1162+#: init/job_process.c:850
1163 #, c-format
1164 msgid "unable to set \"%s\" resource limit: %s"
1165 msgstr ""
1166
1167-#: init/job_process.c:820
1168+#: init/job_process.c:855
1169 #, c-format
1170 msgid "unable to set priority: %s"
1171 msgstr ""
1172
1173-#: init/job_process.c:825
1174+#: init/job_process.c:860
1175 #, c-format
1176 msgid "unable to set oom adjustment: %s"
1177 msgstr ""
1178
1179-#: init/job_process.c:830
1180+#: init/job_process.c:865
1181 #, c-format
1182 msgid "unable to change root directory: %s"
1183 msgstr ""
1184
1185-#: init/job_process.c:835
1186+#: init/job_process.c:870
1187 #, c-format
1188 msgid "unable to change working directory: %s"
1189 msgstr ""
1190
1191-#: init/job_process.c:840
1192+#: init/job_process.c:875
1193 #, c-format
1194 msgid "unable to set trace: %s"
1195 msgstr ""
1196
1197-#: init/job_process.c:845
1198+#: init/job_process.c:880
1199 #, c-format
1200 msgid "unable to execute: %s"
1201 msgstr ""
1202
1203-#: init/job_process.c:876 init/job_process.c:926
1204+#: init/job_process.c:885
1205+#, c-format
1206+msgid "unable to setuid: %s"
1207+msgstr ""
1208+
1209+#: init/job_process.c:890
1210+#, c-format
1211+msgid "unable to setgid: %s"
1212+msgstr ""
1213+
1214+#: init/job_process.c:895
1215+#, c-format
1216+msgid "unable to chown: %s"
1217+msgstr ""
1218+
1219+#: init/job_process.c:926 init/job_process.c:976
1220 #, c-format
1221 msgid "Sending %s signal to %s %s process (%d)"
1222 msgstr ""
1223
1224-#: init/job_process.c:885 init/job_process.c:935
1225+#: init/job_process.c:935 init/job_process.c:985
1226 #, c-format
1227 msgid "Failed to send %s signal to %s %s process (%d): %s"
1228 msgstr ""
1229
1230-#: init/job_process.c:996
1231+#: init/job_process.c:1046
1232 #, c-format
1233 msgid "%s %s process (%d) terminated with status %d"
1234 msgstr ""
1235
1236-#: init/job_process.c:1001
1237+#: init/job_process.c:1051
1238 #, c-format
1239 msgid "%s %s process (%d) exited normally"
1240 msgstr ""
1241
1242-#: init/job_process.c:1016
1243+#: init/job_process.c:1066
1244 #, c-format
1245 msgid "%s %s process (%d) killed by %s signal"
1246 msgstr ""
1247
1248-#: init/job_process.c:1020
1249+#: init/job_process.c:1070
1250 #, c-format
1251 msgid "%s %s process (%d) killed by signal %d"
1252 msgstr ""
1253
1254-#: init/job_process.c:1034
1255+#: init/job_process.c:1084
1256 #, c-format
1257 msgid "%s %s process (%d) stopped by %s signal"
1258 msgstr ""
1259
1260-#: init/job_process.c:1038
1261+#: init/job_process.c:1088
1262 #, c-format
1263 msgid "%s %s process (%d) stopped by signal %d"
1264 msgstr ""
1265
1266-#: init/job_process.c:1052
1267+#: init/job_process.c:1102
1268 #, c-format
1269 msgid "%s %s process (%d) continued by %s signal"
1270 msgstr ""
1271
1272-#: init/job_process.c:1056
1273+#: init/job_process.c:1106
1274 #, c-format
1275 msgid "%s %s process (%d) continued by signal %d"
1276 msgstr ""
1277
1278-#: init/job_process.c:1191
1279+#: init/job_process.c:1241
1280 #, c-format
1281 msgid "%s respawning too fast, stopped"
1282 msgstr ""
1283
1284-#: init/job_process.c:1197
1285+#: init/job_process.c:1247
1286 #, c-format
1287 msgid "%s %s process ended, respawning"
1288 msgstr ""
1289
1290-#: init/job_process.c:1437
1291+#: init/job_process.c:1487
1292 #, c-format
1293 msgid "Failed to set ptrace options for %s %s process (%d): %s"
1294 msgstr ""
1295
1296-#: init/job_process.c:1450 init/job_process.c:1645
1297+#: init/job_process.c:1500 init/job_process.c:1695
1298 #, c-format
1299 msgid "Failed to continue traced %s %s process (%d): %s"
1300 msgstr ""
1301
1302-#: init/job_process.c:1490 init/job_process.c:1581 init/job_process.c:1636
1303+#: init/job_process.c:1540 init/job_process.c:1631 init/job_process.c:1686
1304 #, c-format
1305 msgid "Failed to detach traced %s %s process (%d): %s"
1306 msgstr ""
1307
1308-#: init/job_process.c:1530
1309+#: init/job_process.c:1580
1310 #, c-format
1311 msgid "Failed to deliver signal to traced %s %s process (%d): %s"
1312 msgstr ""
1313
1314-#: init/job_process.c:1565
1315+#: init/job_process.c:1615
1316 #, c-format
1317 msgid "Failed to obtain child process id for %s %s process (%d): %s"
1318 msgstr ""
1319
1320-#: init/job_process.c:1572
1321+#: init/job_process.c:1622
1322 #, c-format
1323 msgid "%s %s process (%d) became new process (%d)"
1324 msgstr ""
1325
1326-#: init/job_process.c:1631
1327+#: init/job_process.c:1681
1328 #, c-format
1329 msgid "%s %s process (%d) executable changed"
1330 msgstr ""
1331@@ -462,7 +477,7 @@
1332 msgid "Not being executed as init"
1333 msgstr ""
1334
1335-#: init/main.c:238 init/main.c:601
1336+#: init/main.c:238 init/main.c:611
1337 msgid "Unable to set root directory"
1338 msgstr ""
1339
1340@@ -478,31 +493,31 @@
1341 msgid "Unable to listen for private connections"
1342 msgstr ""
1343
1344-#: init/main.c:618
1345+#: init/main.c:628
1346 #, c-format
1347 msgid "Caught %s, core dumped"
1348 msgstr ""
1349
1350-#: init/main.c:622
1351+#: init/main.c:632
1352 #, c-format
1353 msgid "Caught %s, unable to dump core"
1354 msgstr ""
1355
1356-#: init/main.c:651
1357+#: init/main.c:661
1358 #, c-format
1359 msgid "Re-executing %s"
1360 msgstr ""
1361
1362-#: init/main.c:676
1363+#: init/main.c:686
1364 #, c-format
1365 msgid "Failed to re-execute %s: %s"
1366 msgstr ""
1367
1368-#: init/main.c:761
1369+#: init/main.c:771
1370 msgid "Reconnecting to system bus"
1371 msgstr ""
1372
1373-#: init/main.c:767
1374+#: init/main.c:777
1375 msgid "Unable to connect to the system bus"
1376 msgstr ""
1377
1378
1379=== modified file 'util/man/initctl.8'
1380--- util/man/initctl.8 2011-06-16 14:39:55 +0000
1381+++ util/man/initctl.8 2011-07-25 16:29:00 +0000
1382@@ -169,8 +169,15 @@
1383
1384 Requests that an instance of the named
1385 .I JOB
1386-be restarted (stopped and then started), outputting the status of the
1387-job to standard output when the command completes.
1388+be restarted, outputting the status of the job to standard output when
1389+the command completes.
1390+
1391+The job instance being restarted will retain its original configuration.
1392+To have the new instance run with the latest job configuration,
1393+.B stop
1394+the job and then
1395+.B start
1396+it again instead.
1397
1398 See
1399 .B status
1400
1401=== added file 'util/tests/test_user_sessions.sh'
1402--- util/tests/test_user_sessions.sh 1970-01-01 00:00:00 +0000
1403+++ util/tests/test_user_sessions.sh 2011-07-25 16:29:00 +0000
1404@@ -0,0 +1,553 @@
1405+#!/bin/sh -u
1406+#---------------------------------------------------------------------
1407+# Script to run minimal Upstart user session tests.
1408+#
1409+# Note that this script _cannot_ be run as part of the "make check"
1410+# tests since those tests stimulate functions and features of the
1411+# as-yet-uninstalled version of Upstart. However, this script needs to
1412+# run on a system where the version of Upstart under test has _already_
1413+# been fully installed.
1414+#---------------------------------------------------------------------
1415+#
1416+# Copyright (C) 2011 Canonical Ltd.
1417+#
1418+# Author: James Hunt <james.hunt@canonical.com>
1419+#
1420+# This program is free software: you can redistribute it and/or modify
1421+# it under the terms of the GNU General Public License as published by
1422+# the Free Software Foundation, version 3 of the License.
1423+#
1424+# This program is distributed in the hope that it will be useful,
1425+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1426+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1427+# GNU General Public License for more details.
1428+#
1429+# You should have received a copy of the GNU General Public License
1430+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1431+#
1432+#---------------------------------------------------------------------
1433+
1434+script_name=${0##*/}
1435+user_job_dir="$HOME/.init"
1436+bug_url="https://bugs.launchpad.net/upstart/+filebug"
1437+test_dir=
1438+test_dir_suffix=
1439+user_to_create=
1440+uid=
1441+gid=
1442+opt=
1443+OPTARG=
1444+
1445+# allow non-priv users to find 'initctl'
1446+export PATH=$PATH:/sbin
1447+
1448+# for assertions
1449+die()
1450+{
1451+ msg="$*"
1452+ echo "ERROR: $msg" >&2
1453+ exit 1
1454+}
1455+
1456+TEST_FAILED()
1457+{
1458+ args="$*"
1459+
1460+ [ -z "$args" ] && die "need args"
1461+
1462+ printf "BAD: %s\n" "$args"
1463+ printf "\nPlease report a bug at $bug_url including the following details:\n"
1464+ printf "\nUpstart:\n"
1465+ /sbin/init --version|head -n1
1466+ /sbin/initctl --version|head -n1
1467+ echo
1468+ printf "cmdline:\n"
1469+ cat /proc/cmdline
1470+ echo
1471+ printf "Upstart Env:\n"
1472+ set|grep UPSTART_
1473+ echo
1474+ printf "lsb:\n"
1475+ lsb_release -a
1476+ printf "\nuname:\n"
1477+ uname -a
1478+ echo
1479+ sync
1480+ exit 1
1481+}
1482+
1483+TEST_GROUP()
1484+{
1485+ name="$1"
1486+
1487+ [ -z "$name" ] && die "need name"
1488+
1489+ printf "Testing %s\n", "$name"
1490+}
1491+
1492+TEST_FEATURE()
1493+{
1494+ feature="$1"
1495+
1496+ [ -z "$feature" ] && die "need feature"
1497+
1498+ printf "...%s\n" "$feature"
1499+}
1500+
1501+TEST_NE()
1502+{
1503+ cmd="$1"
1504+ value="$2"
1505+ expected="$3"
1506+
1507+ # XXX: no checks on value or expected since they might be blank
1508+ [ -z "$cmd" ] && die "need cmd"
1509+
1510+ [ "$value" = "$expected" ] && TEST_FAILED \
1511+ "wrong value for '$cmd', expected $expected got $value"
1512+}
1513+
1514+TEST_EQ()
1515+{
1516+ cmd="$1"
1517+ value="$2"
1518+ expected="$3"
1519+
1520+ # XXX: no checks on value or expected since they might be blank
1521+ [ -z "$cmd" ] && die "need cmd"
1522+
1523+ [ "$value" != "$expected" ] && TEST_FAILED \
1524+ "wrong value for '$cmd', expected '$expected' got '$value'"
1525+}
1526+
1527+setup()
1528+{
1529+ uid=$(id -u)
1530+ gid=$(id -g)
1531+
1532+ if [ "$uid" = 0 ]
1533+ then
1534+ [ -z "$user_to_create" ] && die "need '-u' option when running as root"
1535+
1536+ getent passwd "$user_to_create" && \
1537+ die "user '$user_to_create' already exists"
1538+
1539+ echo "Creating user '$user_to_create'"
1540+ cmd="useradd -mU -c 'Upstart Test User' $user_to_create"
1541+ eval "$cmd"
1542+ TEST_EQ "$cmd" $? 0
1543+
1544+ echo "Locking account for user '$user_to_create'"
1545+ cmd="usermod -L $user_to_create"
1546+ eval "$cmd"
1547+ TEST_EQ "$cmd" $? 0
1548+
1549+ # Run ourselves again as the new user
1550+ su -c "$0 -a" "$user_to_create"
1551+ test_run_rc=$?
1552+
1553+ if [ $test_run_rc -eq 0 ]
1554+ then
1555+ echo "Deleting user '$user_to_create'"
1556+ cmd="userdel -r \"$user_to_create\""
1557+ eval "$cmd"
1558+ TEST_EQ "$cmd" $? 0
1559+ fi
1560+
1561+ exit $test_run_rc
1562+ fi
1563+
1564+ # setup
1565+ if [ ! -d "$user_job_dir" ]
1566+ then
1567+ cmd="mkdir -p \"$user_job_dir\""
1568+ eval $cmd
1569+ TEST_EQ "$cmd" $? 0
1570+
1571+ cmd="chmod 755 \"$user_job_dir\""
1572+ eval "$cmd"
1573+ TEST_EQ "$cmd" $? 0
1574+ fi
1575+
1576+ # create somewhere to store user jobs
1577+ cmd="mktemp -d --tmpdir=\"$user_job_dir\""
1578+ test_dir=$(eval "$cmd")
1579+ TEST_EQ "$cmd" $? 0
1580+ TEST_NE "$test_dir" "$test_dir" ""
1581+ test_dir_suffix=${test_dir#${user_job_dir}/}
1582+
1583+ # ensure files in this directory are accessible since
1584+ # mktemp sets directory perms to 0700 regardless of umask.
1585+ cmd="chmod 755 \"$test_dir\""
1586+ eval "$cmd"
1587+ TEST_EQ "$cmd" $? 0
1588+
1589+ TEST_NE "HOME" "$HOME" ""
1590+}
1591+
1592+cleanup()
1593+{
1594+ if [ -d "$test_dir" ]
1595+ then
1596+ echo "Removing test directory '$test_dir'"
1597+ cmd="rmdir \"$test_dir\""
1598+ eval "$cmd"
1599+ TEST_EQ "$cmd" $? 0
1600+ fi
1601+}
1602+
1603+ensure_job_known()
1604+{
1605+ job="$1"
1606+ job_name="$2"
1607+
1608+ [ -z "$job" ] && die "no job"
1609+ [ -z "$job_name" ] && die "no job name"
1610+
1611+ TEST_FEATURE "ensure 'initctl' recognises job"
1612+ initctl list|grep -q "^$job " || \
1613+ TEST_FAILED "job $job_name not known to initctl"
1614+
1615+ TEST_FEATURE "ensure 'status' recognises job"
1616+ cmd="status ${job}"
1617+ eval "$cmd"
1618+ rc=$?
1619+ TEST_EQ "$cmd" $rc 0
1620+}
1621+
1622+run_user_job_tests()
1623+{
1624+ job_name="$1"
1625+ job_file="$2"
1626+ task="$3"
1627+ env="$4"
1628+
1629+ # XXX: env can be empty
1630+ [ -z "$job_name" ] && die "no job name"
1631+ [ -z "$job_file" ] && die "no job file"
1632+ [ -z "$task" ] && die "no task value"
1633+
1634+ job="${test_dir_suffix}/${job_name}"
1635+
1636+ [ -f "$job_file" ] || TEST_FAILED "job file '$job_file' does not exist"
1637+
1638+ ensure_job_known "$job" "$job_name"
1639+
1640+ TEST_FEATURE "ensure job can be started"
1641+ cmd="start ${job} ${env}"
1642+ output=$(eval "$cmd")
1643+ rc=$?
1644+ TEST_EQ "$cmd" $rc 0
1645+
1646+ if [ "$task" = no ]
1647+ then
1648+ TEST_FEATURE "ensure 'start' shows job pid"
1649+ pid=$(echo "$output"|awk '{print $4}')
1650+ TEST_NE "pid" "$pid" ""
1651+
1652+ TEST_FEATURE "ensure 'initctl' shows job is running with pid"
1653+ initctl list|grep -q "^$job start/running, process $pid" || \
1654+ TEST_FAILED "job $job_name did not start"
1655+
1656+ TEST_FEATURE "ensure 'status' shows job is running with pid"
1657+ cmd="status ${job}"
1658+ output=$(eval "$cmd")
1659+ echo "$output"|while read job_tmp state ignored status_pid
1660+ do
1661+ state=$(echo $state|tr -d ',')
1662+ TEST_EQ "job name" "$job_tmp" "$job"
1663+ TEST_EQ "job state" "$state" "start/running"
1664+ TEST_EQ "job pid" "$status_pid" "$pid"
1665+ done
1666+
1667+ TEST_FEATURE "ensure job pid is running with correct uids"
1668+ pid_uids=$(ps --no-headers -p $pid -o euid,ruid)
1669+ for pid_uid in $pid_uids
1670+ do
1671+ TEST_EQ "pid uid" "$pid_uid" "$uid"
1672+ done
1673+
1674+ TEST_FEATURE "ensure job pid is running with correct gids"
1675+ pid_gids=$(ps --no-headers -p $pid -o egid,rgid)
1676+ for pid_gid in $pid_gids
1677+ do
1678+ TEST_EQ "pid gid" "$pid_gid" "$gid"
1679+ done
1680+
1681+ TEST_FEATURE "ensure process is running in correct directory"
1682+ cwd=$(readlink /proc/$pid/cwd)
1683+ TEST_EQ "cwd" "$cwd" "$HOME"
1684+
1685+ TEST_FEATURE "ensure job can be stopped"
1686+ cmd="stop ${job}"
1687+ output=$(eval "$cmd")
1688+ rc=$?
1689+ TEST_EQ "$cmd" $rc 0
1690+
1691+ TEST_FEATURE "ensure job pid no longer exists"
1692+ pid_ids=$(ps --no-headers -p $pid -o euid,ruid,egid,rgid)
1693+ TEST_EQ "pid uids+gids" "$pid_ids" ""
1694+ fi
1695+
1696+ remove_job_file "$job_file"
1697+ ensure_job_gone "$job" "$job_name" "$env"
1698+}
1699+
1700+remove_job_file()
1701+{
1702+ job_file="$1"
1703+
1704+ [ -z "$job_file" ] && die "no job file"
1705+ [ ! -f "$job_file" ] && TEST_FAILED "job file '$job_file' does not exist"
1706+
1707+ cmd="rm $job_file"
1708+ eval "$cmd"
1709+ TEST_EQ "$cmd" $? 0
1710+}
1711+
1712+ensure_job_gone()
1713+{
1714+ job="$1"
1715+ job_name="$2"
1716+ env="$3"
1717+
1718+ # XXX: no check on env since it can be empty
1719+ [ -z "$job" ] && die "no job"
1720+ [ -z "$job_name" ] && die "no job name"
1721+
1722+ TEST_FEATURE "ensure 'initctl' no longer recognises job"
1723+ initctl list|grep -q "^$job " && \
1724+ TEST_FAILED "deleted job $job_name still known to initctl"
1725+
1726+ TEST_FEATURE "ensure 'status' no longer recognises job"
1727+ cmd="status ${job}"
1728+ eval "$cmd"
1729+ rc=$?
1730+ TEST_NE "$cmd" $rc 0
1731+}
1732+
1733+test_user_job()
1734+{
1735+ test_group="$1"
1736+ job_name="$2"
1737+ script="$3"
1738+ task="$4"
1739+ env="$5"
1740+
1741+ # XXX: no test on script or env since they might be empty
1742+ [ -z "$test_group" ] && die "no test group"
1743+ [ -z "$job_name" ] && die "no job name"
1744+ [ -z "$task" ] && die "no task"
1745+
1746+ TEST_GROUP "$test_group"
1747+
1748+ job_file="${test_dir}/${job_name}.conf"
1749+
1750+ echo "$script" > $job_file
1751+
1752+ run_user_job_tests "$job_name" "$job_file" "$task" "$env"
1753+}
1754+
1755+test_user_job_binary()
1756+{
1757+ group="user job running a binary"
1758+ job_name="binary_test"
1759+ script="exec sleep 999"
1760+ test_user_job "$group" "$job_name" "$script" no ""
1761+}
1762+
1763+test_user_job_binary_task()
1764+{
1765+ group="user job running a binary task"
1766+ job_name="binary_task_test"
1767+ OUTFILE=$(mktemp)
1768+
1769+ script="\
1770+task
1771+exec true > $OUTFILE"
1772+
1773+ test_user_job "$group" "$job_name" "$script" yes "OUTFILE=$OUTFILE"
1774+ rm -f $OUTFILE
1775+}
1776+
1777+test_user_job_single_line_script()
1778+{
1779+ group="user job running a single-line script"
1780+ job_name="single_line_script_test"
1781+ script="\
1782+script
1783+ sleep 999
1784+end script"
1785+ test_user_job "$group" "$job_name" "$script" no ""
1786+}
1787+
1788+test_user_job_single_line_script_task()
1789+{
1790+ group="user job running a single-line script task"
1791+ job_name="single_line_script_task_test"
1792+ OUTFILE=$(mktemp)
1793+
1794+ script="\
1795+task
1796+script
1797+ exec true > $OUTFILE
1798+end script"
1799+ test_user_job "$group" "$job_name" "$script" yes "OUTFILE=$OUTFILE"
1800+ rm -f $OUTFILE
1801+}
1802+
1803+test_user_job_multi_line_script()
1804+{
1805+ group="user job running a multi-line script"
1806+ job_name="multi_line_script_test"
1807+ script="\
1808+script
1809+
1810+ true
1811+ true;true
1812+ sleep 999
1813+
1814+end script"
1815+ test_user_job "$group" "$job_name" "$script" no ""
1816+}
1817+
1818+test_user_job_multi_line_script_task()
1819+{
1820+ group="user job running a multi-line script task"
1821+ job_name="multi_line_script_task_test"
1822+ OUTFILE=$(mktemp)
1823+
1824+ script="\
1825+task
1826+script
1827+
1828+ true
1829+ true
1830+ true
1831+
1832+end script"
1833+ test_user_job "$group" "$job_name" "$script" yes "OUTFILE=$OUTFILE"
1834+ rm -f $OUTFILE
1835+}
1836+
1837+test_user_emit_events()
1838+{
1839+ job_name="start_on_foo"
1840+
1841+ TEST_GROUP "user emitting an event"
1842+ initctl emit foo || TEST_FAILED "failed to emit event as user"
1843+
1844+ TEST_GROUP "user emitting an event to start a job"
1845+ script="\
1846+ start on foo BAR=2
1847+ stop on baz cow=moo or hello
1848+ exec sleep 999"
1849+
1850+ job_file="${test_dir}/${job_name}.conf"
1851+ job="${test_dir_suffix}/${job_name}"
1852+
1853+ echo "$script" > $job_file
1854+
1855+ ensure_job_known "$job" "$job_name"
1856+
1857+ initctl list|grep -q "^$job stop/waiting" || \
1858+ TEST_FAILED "job $job_name not stopped"
1859+
1860+ TEST_FEATURE "ensure job can be started with event"
1861+ initctl emit foo BAR=2 || \
1862+ TEST_FAILED "failed to emit event for user job"
1863+
1864+ initctl status "$job"|grep -q "^$job start/running" || \
1865+ TEST_FAILED "job $job_name failed to start"
1866+
1867+ TEST_FEATURE "ensure job can be stopped with event"
1868+ initctl emit baz cow=moo || \
1869+ TEST_FAILED "failed to emit event for user job"
1870+
1871+ initctl list|grep -q "^$job stop/waiting" || \
1872+ TEST_FAILED "job $job_name not stopped"
1873+
1874+ rm -f "$job_file"
1875+}
1876+
1877+test_user_jobs()
1878+{
1879+ test_user_job_binary
1880+ test_user_job_single_line_script
1881+ test_user_job_multi_line_script
1882+
1883+ test_user_job_binary_task
1884+ test_user_job_single_line_script_task
1885+ test_user_job_multi_line_script_task
1886+
1887+ test_user_emit_events
1888+}
1889+
1890+tests()
1891+{
1892+ echo
1893+ echo -n "Running user session tests as user '`whoami`'"
1894+ echo " (uid $uid, gid $gid) in directory '$test_dir'"
1895+ echo
1896+
1897+ test_user_jobs
1898+
1899+ echo
1900+ echo "All tests completed successfully"
1901+ echo
1902+}
1903+
1904+usage()
1905+{
1906+cat <<EOT
1907+USAGE: $script_name [options]
1908+
1909+OPTIONS:
1910+
1911+ -a : Actually run this script.
1912+ -h : Show this help.
1913+ -u <user> : Specify name of test user to create.
1914+
1915+DESCRIPTION: Run simple set of Upstart user session tests.
1916+
1917+WARNING: Note that this script is unavoidably invasive, so read what
1918+WARNING: follows before running!
1919+
1920+If run as a non-root user, this script will create a uniquely-named
1921+subdirectory below "\$HOME/.init/" to run its tests in. On successful
1922+completion of these tests, the unique subdirectory and its contents will
1923+be removed.
1924+
1925+If however, this script is invoked as the root user, the script will
1926+refuse to run until given the name of a test user to create via the "-u"
1927+option. If the user specified to this option already exists, this script
1928+will exit with an error. If the user does not already exist, it will be
1929+created, the script then run *as that user* and assuming successful
1930+completion of the tests, the test user and their home directory will
1931+then be deleted.
1932+
1933+EOT
1934+}
1935+
1936+#---------------------------------------------------------------------
1937+# main
1938+#---------------------------------------------------------------------
1939+
1940+while getopts "hu:" opt
1941+do
1942+ case "$opt" in
1943+ h)
1944+ usage
1945+ exit 0
1946+ ;;
1947+
1948+ u)
1949+ user_to_create="$OPTARG"
1950+ ;;
1951+ esac
1952+done
1953+
1954+setup
1955+tests
1956+cleanup
1957+exit 0

Subscribers

People subscribed via source and target branches

to all changes: