Merge lp:~jamesodhunt/upstart/bug-1235649 into lp:upstart

Proposed by James Hunt on 2013-10-25
Status: Merged
Merged at revision: 1554
Proposed branch: lp:~jamesodhunt/upstart/bug-1235649
Merge into: lp:upstart
Diff against target: 817 lines (+477/-46)
9 files modified
ChangeLog (+39/-8)
dbus/com.ubuntu.Upstart.xml (+4/-0)
init/control.c (+111/-18)
init/control.h (+12/-1)
init/main.c (+22/-7)
init/tests/test_control.c (+2/-2)
util/initctl.c (+53/-4)
util/man/initctl.8 (+23/-6)
util/tests/test_initctl.c (+211/-0)
To merge this branch: bzr merge lp:~jamesodhunt/upstart/bug-1235649
Reviewer Review Type Date Requested Status
Dimitri John Ledkov 2013-10-25 Approve on 2013-11-04
Review via email: mp+192703@code.launchpad.net
To post a comment you must log in.
Dimitri John Ledkov (xnox) wrote :

So we are adding a DBus API, to tell session init which session DBus to connect to, once and only once. This message will then be delivered via private socket. Yet this method will be exposed as public api over DBus, which will always do nothing. Will it be possible to publish method call NotifyDBusAddress over Private socket only? I guess it's a very minor point.

User-session init integration question, will it be expected for user-session dbus job to invoke initctl notify-dbus-address in post-start?

Other than that, works as advertised.

James Hunt (jamesodhunt) wrote :

Hi Dmitrijs,

> Will it be possible to publish method call NotifyDBusAddress over Private socket only
Aside from modifying the way we auto-generate the D-Bus bindings, I'm not sure. It is admittedly an annoyance, but harmless.

> User-session init integration question, will it be expected for user-session dbus job to invoke
> initctl notify-dbus-address in post-start?
Yes, we simply need to add the following to dbus.conf:

    initctl notify-dbus-address $DBUS_SESSION_BUS_ADDRESS

Dimitri John Ledkov (xnox) :
review: Approve
lp:~jamesodhunt/upstart/bug-1235649 updated on 2013-11-04
1548. By James Hunt on 2013-11-04

* Sync with lp:upstart.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2013-11-03 02:56:57 +0000
3+++ ChangeLog 2013-11-04 11:44:32 +0000
4@@ -1,10 +1,3 @@
5-2013-10-25 Steve Langasek <steve.langasek@ubuntu.com>
6-
7- * init/main.c, init/system.c, init/system.h: allow mount options
8- to be passed to system_mount(), and pass the right options when
9- mounting /dev/pts to match the permissions set by either
10- initramfs-tools or mountall. LP: #1244763.
11-
12 2013-11-03 James Hunt <james.hunt@ubuntu.com>
13
14 * init/job_class.c:
15@@ -59,6 +52,44 @@
16 * scripts/tests/test_pyupstart_session_init.py: Added file bridge tests
17 for directory creation, modification and deletion.
18
19+2013-10-25 James Hunt <james.hunt@ubuntu.com>
20+
21+ * dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
22+ * init/control.c:
23+ - control_bus_open(): Connect to the D-Bus bus specified
24+ by control_bus_address when running as a Session Init (LP: #1203595, #1235649).
25+ - control_disconnected(): Display calculated bus type rather than hard-coding.
26+ - control_handle_bus_type(): Removed.
27+ - control_get_bus_type(): Determine type of D-Bus bus that will be used.
28+ - control_notify_dbus_address(): Implementation of D-Bus 'NotifyDBusAddress' method
29+ that sets control_bus_address.
30+ * init/main.c:
31+ - main():
32+ - Just check USE_SESSION_BUS_ENV variable rather than calling
33+ control_handle_bus_type().
34+ - Don't register SIGUSR1 handler for Session Init.
35+ - usr1_handler(): Display calculated bus type rather than hard-coding.
36+ * init/test_control.c: Updated strings used by tests which check error
37+ messages to include 'D-Bus'.
38+ * util/initctl.c: Added new 'notify-dbus-address' command.
39+ * util/man/initctl.8:
40+ - Documentation for new 'notify-dbus-address' command.
41+ - reset-env: Troff fix.
42+ - Explain '--user' implicit in user mode.
43+ * util/tests/test_initctl.c: test_dbus_connection(): New function providing
44+ the following new tests:
45+ - "ensure non-priv non-Session Init connects to D-Bus session bus on startup".
46+ - "ensure Session Init does not connect to D-Bus session bus on startup".
47+ - "ensure Session Init connects to D-Bus session bus when notified".
48+ - "ensure Session Init does not connect to another bus when notified twice".
49+
50+2013-10-25 Steve Langasek <steve.langasek@ubuntu.com>
51+
52+ * init/main.c, init/system.c, init/system.h: allow mount options
53+ to be passed to system_mount(), and pass the right options when
54+ mounting /dev/pts to match the permissions set by either
55+ initramfs-tools or mountall. LP: #1244763.
56+
57 2013-10-24 James Hunt <james.hunt@ubuntu.com>
58
59 * init/environ.c: Comment.
60@@ -79,7 +110,7 @@
61
62 2013-10-23 Dmitrijs Ledkovs <xnox@ubuntu.com>
63
64- * extra/upstart-socket-bridge.c: use SOCKET_PATH in our event
65+ * extra/upstart-socket-bridge.c: use SOCKET_PATH in our event
66 environment, instead of clobbering PATH. (LP: #1235480)
67
68 2013-10-23 James Hunt <james.hunt@ubuntu.com>
69
70=== modified file 'dbus/com.ubuntu.Upstart.xml'
71--- dbus/com.ubuntu.Upstart.xml 2013-02-08 16:15:23 +0000
72+++ dbus/com.ubuntu.Upstart.xml 2013-11-04 11:44:32 +0000
73@@ -103,6 +103,10 @@
74 <method name="NotifyDiskWriteable">
75 </method>
76
77+ <method name="NotifyDBusAddress">
78+ <arg name="address" type="s" direction="in" />
79+ </method>
80+
81 <method name="EndSession"/>
82
83 <!-- Basic information about Upstart -->
84
85=== modified file 'init/control.c'
86--- init/control.c 2013-04-22 10:30:09 +0000
87+++ init/control.c 2013-11-04 11:44:32 +0000
88@@ -81,11 +81,19 @@
89 *
90 * If TRUE, connect to the D-Bus session bus rather than the system bus.
91 *
92- * Used for testing.
93+ * Used for testing to simulate (as far as possible) a system-like init
94+ * when running as a non-priv user (but not as a Session Init).
95 **/
96 int use_session_bus = FALSE;
97
98 /**
99+ * dbus_bus_type:
100+ *
101+ * Type of D-Bus bus to connect to.
102+ **/
103+DBusBusType dbus_bus_type;
104+
105+/**
106 * control_server_address:
107 *
108 * Address on which the control server may be reached.
109@@ -100,6 +108,13 @@
110 DBusServer *control_server = NULL;
111
112 /**
113+ * control_bus_address:
114+ *
115+ * Address on which the control bus may be reached.
116+ **/
117+char *control_bus_address = NULL;
118+
119+/**
120 * control_bus:
121 *
122 * Open connection to a D-Bus bus. The connection may be opened with
123@@ -236,7 +251,6 @@
124 control_server = NULL;
125 }
126
127-
128 /**
129 * control_bus_open:
130 *
131@@ -256,17 +270,37 @@
132
133 nih_assert (control_bus == NULL);
134
135+ dbus_error_init (&error);
136+
137 control_init ();
138
139- control_handle_bus_type ();
140+ dbus_bus_type = control_get_bus_type ();
141
142- /* Connect to the D-Bus System Bus and hook everything up into
143+ /* Connect to the appropriate D-Bus bus and hook everything up into
144 * our own main loop automatically.
145 */
146- conn = nih_dbus_bus (use_session_bus ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM,
147- control_disconnected);
148- if (! conn)
149- return -1;
150+ if (user_mode && control_bus_address) {
151+ conn = nih_dbus_connect (control_bus_address, control_disconnected);
152+ if (! conn)
153+ return -1;
154+
155+ if (! dbus_bus_register (conn, &error)) {
156+ nih_dbus_error_raise (error.name, error.message);
157+ dbus_error_free (&error);
158+ return -1;
159+ }
160+
161+ nih_debug ("Connected to notified D-Bus bus");
162+ } else {
163+ conn = nih_dbus_bus (use_session_bus ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM,
164+ control_disconnected);
165+ if (! conn)
166+ return -1;
167+
168+ nih_debug ("Connected to D-Bus %s bus",
169+ dbus_bus_type == DBUS_BUS_SESSION
170+ ? "session" : "system");
171+ }
172
173 /* Register objects on the bus. */
174 control_register_all (conn);
175@@ -275,7 +309,6 @@
176 * appears on the bus, clients can assume we're ready to talk to
177 * them.
178 */
179- dbus_error_init (&error);
180 ret = dbus_bus_request_name (conn, DBUS_SERVICE_UPSTART,
181 DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
182 if (ret < 0) {
183@@ -345,7 +378,13 @@
184
185 dbus_error_init (&error);
186
187- nih_warn (_("Disconnected from system bus"));
188+ if (user_mode && control_bus_address) {
189+ nih_warn (_("Disconnected from notified D-Bus bus"));
190+ } else {
191+ nih_warn (_("Disconnected from D-Bus %s bus"),
192+ dbus_bus_type == DBUS_BUS_SESSION
193+ ? "session" : "system");
194+ }
195
196 control_bus = NULL;
197 }
198@@ -817,19 +856,20 @@
199 }
200
201 /**
202- * control_handle_bus_type:
203+ * control_get_bus_type:
204 *
205 * Determine D-Bus bus type to connect to.
206+ *
207+ * Returns: Type of D-Bus bus to connect to.
208 **/
209-void
210-control_handle_bus_type (void)
211+DBusBusType
212+control_get_bus_type (void)
213 {
214- if (getenv (USE_SESSION_BUS_ENV))
215- use_session_bus = TRUE;
216+ return (use_session_bus || user_mode)
217+ ? DBUS_BUS_SESSION
218+ : DBUS_BUS_SYSTEM;
219+}
220
221- if (use_session_bus)
222- nih_debug ("Using session bus");
223-}
224 /**
225 * control_notify_disk_writeable:
226 * @data: not used,
227@@ -882,6 +922,59 @@
228 }
229
230 /**
231+ * control_notify_dbus_address:
232+ * @data: not used,
233+ * @message: D-Bus connection and message received,
234+ * @address: Address of D-Bus to connect to.
235+ *
236+ * Implements the NotifyDBusAddress method of the
237+ * com.ubuntu.Upstart interface.
238+ *
239+ * Called to allow the Session Init to connect to the D-Bus
240+ * Session Bus when available.
241+ *
242+ * Returns: zero on success, negative value on raised error.
243+ **/
244+int
245+control_notify_dbus_address (void *data,
246+ NihDBusMessage *message,
247+ const char *address)
248+{
249+ nih_assert (message);
250+ nih_assert (address);
251+
252+ if (getpid () == 1) {
253+ nih_dbus_error_raise_printf (
254+ DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
255+ _("Not permissible to notify D-Bus address for PID 1"));
256+ return -1;
257+ }
258+
259+ if (! control_check_permission (message)) {
260+ nih_dbus_error_raise_printf (
261+ DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
262+ _("You do not have permission to notify D-Bus address"));
263+ return -1;
264+ }
265+
266+ /* Ignore as already connected */
267+ if (control_bus)
268+ return 0;
269+
270+ control_bus_address = nih_strdup (NULL, address);
271+ if (! control_bus_address) {
272+ nih_dbus_error_raise_printf (DBUS_ERROR_NO_MEMORY,
273+ _("Out of Memory"));
274+ return -1;
275+ }
276+
277+ if (control_bus_open () < 0)
278+ return -1;
279+
280+ return 0;
281+}
282+
283+/**
284 * control_bus_flush:
285 *
286 * Drain any remaining messages in the D-Bus queue.
287
288=== modified file 'init/control.h'
289--- init/control.h 2013-05-08 16:21:08 +0000
290+++ init/control.h 2013-11-04 11:44:32 +0000
291@@ -134,7 +134,8 @@
292 const char *log_priority)
293 __attribute__ ((warn_unused_result));
294
295-void control_handle_bus_type (void);
296+DBusBusType control_get_bus_type (void)
297+ __attribute__ ((warn_unused_result));
298
299 void control_prepare_reexec (void);
300
301@@ -157,8 +158,18 @@
302 __attribute__ ((warn_unused_result));
303
304 void control_notify_event_emitted (Event *event);
305+
306 void control_notify_restarted (void);
307
308+int control_notify_disk_writeable (void *data,
309+ NihDBusMessage *message)
310+ __attribute__ ((warn_unused_result));
311+
312+int control_notify_dbus_address (void *data,
313+ NihDBusMessage *message,
314+ const char *address)
315+ __attribute__ ((warn_unused_result));
316+
317 int control_set_env (void *data,
318 NihDBusMessage *message,
319 char * const *job_details,
320
321=== modified file 'init/main.c'
322--- init/main.c 2013-11-03 02:56:57 +0000
323+++ init/main.c 2013-11-04 11:44:32 +0000
324@@ -128,6 +128,7 @@
325 extern int default_console;
326 extern int write_state_file;
327 extern char *log_dir;
328+extern DBusBusType dbus_bus_type;
329 extern mode_t initial_umask;
330
331 /**
332@@ -213,7 +214,8 @@
333 if (disable_job_logging)
334 nih_debug ("Job logging disabled");
335
336- control_handle_bus_type ();
337+ if (getenv (USE_SESSION_BUS_ENV))
338+ use_session_bus = TRUE;
339
340 if (! user_mode)
341 no_inherit_env = TRUE;
342@@ -447,9 +449,14 @@
343 nih_signal_set_handler (SIGHUP, nih_signal_handler);
344 NIH_MUST (nih_signal_add_handler (NULL, SIGHUP, hup_handler, NULL));
345
346- /* SIGUSR1 instructs us to reconnect to D-Bus */
347- nih_signal_set_handler (SIGUSR1, nih_signal_handler);
348- NIH_MUST (nih_signal_add_handler (NULL, SIGUSR1, usr1_handler, NULL));
349+ /* Session Inits only reconnect to D-Bus when notified
350+ * via their private socket.
351+ */
352+ if (! user_mode) {
353+ /* SIGUSR1 instructs us to reconnect to D-Bus */
354+ nih_signal_set_handler (SIGUSR1, nih_signal_handler);
355+ NIH_MUST (nih_signal_add_handler (NULL, SIGUSR1, usr1_handler, NULL));
356+ }
357
358 /* SIGTERM instructs us to re-exec ourselves when running as PID
359 * 1, or to exit when running as a Session Init; this signal should
360@@ -941,15 +948,23 @@
361 usr1_handler (void *data,
362 NihSignal *signal)
363 {
364+ nih_assert (! user_mode);
365+
366 if (! control_bus) {
367- nih_info (_("Reconnecting to system bus"));
368+ char *dbus_bus_name;
369+
370+ dbus_bus_name = dbus_bus_type == DBUS_BUS_SESSION
371+ ? "session" : "system";
372+
373+ nih_info (_("Reconnecting to D-Bus %s bus"),
374+ dbus_bus_name);
375
376 if (control_bus_open () < 0) {
377 NihError *err;
378
379 err = nih_error_get ();
380- nih_warn ("%s: %s", _("Unable to connect to the system bus"),
381- err->message);
382+ nih_warn (_("Unable to connect to the D-Bus %s bus: %s"),
383+ dbus_bus_name, err->message);
384 nih_free (err);
385 }
386 }
387
388=== modified file 'init/tests/test_control.c'
389--- init/tests/test_control.c 2012-09-09 21:27:24 +0000
390+++ init/tests/test_control.c 2013-11-04 11:44:32 +0000
391@@ -821,7 +821,7 @@
392
393 TEST_LIST_EMPTY (control_conns);
394
395- TEST_FILE_EQ (output, "test: Disconnected from system bus\n");
396+ TEST_FILE_EQ (output, "test: Disconnected from D-Bus system bus\n");
397 TEST_FILE_END (output);
398 TEST_FILE_RESET (output);
399
400@@ -879,7 +879,7 @@
401
402 TEST_LIST_EMPTY (control_conns);
403
404- TEST_FILE_EQ (output, "test: Disconnected from system bus\n");
405+ TEST_FILE_EQ (output, "test: Disconnected from D-Bus system bus\n");
406 TEST_FILE_END (output);
407 TEST_FILE_RESET (output);
408
409
410=== modified file 'util/initctl.c'
411--- util/initctl.c 2013-07-21 23:54:16 +0000
412+++ util/initctl.c 2013-11-04 11:44:32 +0000
413@@ -342,8 +342,7 @@
414 use_dbus = getuid () ? TRUE : FALSE;
415 if (use_dbus >= 0 && dbus_bus_type < 0)
416 dbus_bus_type = DBUS_BUS_SYSTEM;
417- }
418- else {
419+ } else {
420 if (! user_addr) {
421 nih_error ("UPSTART_SESSION isn't set in the environment. "
422 "Unable to locate the Upstart instance.");
423@@ -353,7 +352,6 @@
424 use_dbus = FALSE;
425 }
426
427-
428 dbus_error_init (&dbus_error);
429 if (use_dbus) {
430 if (! dest_name)
431@@ -387,6 +385,7 @@
432 return NULL;
433 }
434 }
435+
436 dbus_error_free (&dbus_error);
437
438 upstart = nih_dbus_proxy_new (parent, connection,
439@@ -1987,6 +1986,51 @@
440
441
442 /**
443+ * notify_dbus_address_action:
444+ * @command: NihCommand invoked,
445+ * @args: command-line arguments.
446+ *
447+ * This function is called for the "notify-dbus-address" command.
448+ *
449+ * Returns: command exit status.
450+ **/
451+int
452+notify_dbus_address_action (NihCommand *command,
453+ char * const *args)
454+{
455+ nih_local NihDBusProxy *upstart = NULL;
456+ NihError *err;
457+ char *address = NULL;
458+
459+ nih_assert (command != NULL);
460+ nih_assert (args != NULL);
461+
462+ if (! args[0]) {
463+ fprintf (stderr, _("%s: missing D-Bus address\n"), program_name);
464+ nih_main_suggest_help ();
465+ return 1;
466+ }
467+
468+ address = args[0];
469+
470+ upstart = upstart_open (NULL);
471+ if (! upstart)
472+ return 1;
473+
474+ if (upstart_notify_dbus_address_sync (NULL, upstart, address) < 0)
475+ goto error;
476+
477+ return 0;
478+
479+error:
480+ err = nih_error_get ();
481+ nih_error ("%s", err->message);
482+ nih_free (err);
483+
484+ return 1;
485+}
486+
487+/**
488 * list_sessions_action:
489 * @command: NihCommand invoked,
490 * @args: command-line arguments.
491@@ -2827,7 +2871,7 @@
492 * Command-line options accepted for all arguments.
493 **/
494 static NihOption options[] = {
495- { 0, "session", N_("use D-Bus session bus to connect to init daemon (for testing)"),
496+ { 0, "session", N_("use existing D-Bus session bus to connect to init daemon (for testing)"),
497 NULL, NULL, NULL, dbus_bus_type_setter },
498 { 0, "system", N_("use D-Bus system bus to connect to init daemon"),
499 NULL, NULL, NULL, dbus_bus_type_setter },
500@@ -3193,6 +3237,11 @@
501 N_("JOB is the name of the job which usage is to be shown.\n" ),
502 NULL, usage_options, usage_action },
503
504+ { "notify-dbus-address", NULL,
505+ N_("Inform Upstart of D-Bus address to connect to."),
506+ N_("Run to allow Upstart to provide services over D-Bus."),
507+ NULL, NULL, notify_dbus_address_action},
508+
509 { "notify-disk-writeable", NULL,
510 N_("Inform Upstart that disk is now writeable."),
511 N_("Run to ensure output from jobs ending before "
512
513=== modified file 'util/man/initctl.8'
514--- util/man/initctl.8 2013-05-31 15:41:20 +0000
515+++ util/man/initctl.8 2013-11-04 11:44:32 +0000
516@@ -42,14 +42,19 @@
517 .B \-\-user
518 User mode. In this mode, initctl will talk to the
519 .BR init (8)
520-daemon using the D\-Bus private socket defined in the UPSTART_SESSION
521+daemon using the D\-Bus private socket defined in the
522+.B UPSTART_SESSION
523 environment variable.
524+
525+Note that if the
526+.B UPSTART_SESSION
527+variable is defined, this option is implied.
528 .\"
529 .TP
530 .B \-\-session
531 Connect to
532 .BR init (8)
533-daemon using the D\-Bus session bus (for testing purposes only).
534+daemon using the existing D\-Bus session bus (for testing purposes only).
535 .\"
536 .TP
537 .B \-\-system
538@@ -555,6 +560,18 @@
539 .RE
540 .\"
541 .TP
542+.B notify\-dbus\-address
543+Notify the
544+.BR init (8)
545+daemon of the D\-Bus address it should use to connect to.
546+
547+This command is only permitted when running in
548+.B User Session Mode.
549+See
550+.BR init (5)
551+for further details.
552+.\"
553+.TP
554 .B list\-env
555 .RI [ OPTIONS "]
556
557@@ -608,7 +625,7 @@
558 Adds or updates a variable in a job environment table. Variables set
559 in this way will apply to all subsequently-starting jobs.
560
561-This command is only permitted When running in
562+This command is only permitted when running in
563 .B User Session Mode.
564 See
565 .BR init (5)
566@@ -640,7 +657,7 @@
567 Remove the specified variable from a job environment table. If the
568 variable does not already exist in the table, no change will be made.
569
570-This command is only permitted When running in
571+This command is only permitted when running in
572 .B User Session Mode.
573 See
574 .BR init (5)
575@@ -667,12 +684,12 @@
576 .\"
577 .TP
578 .B reset\-env
579-.R [ OPTIONS ]
580+.RI [ OPTIONS ]
581
582 Discards all changes make to a job environment table, setting it back
583 to its default set of variables and values.
584
585-This command is only permitted When running in
586+This command is only permitted when running in
587 .B User Session Mode.
588 See
589 .BR init (5)
590
591=== modified file 'util/tests/test_initctl.c'
592--- util/tests/test_initctl.c 2013-10-18 09:13:36 +0000
593+++ util/tests/test_initctl.c 2013-11-04 11:44:32 +0000
594@@ -16790,6 +16790,215 @@
595 TEST_EQ (rmdir (logdir), 0);
596 }
597
598+void
599+test_dbus_connection (void)
600+{
601+ size_t lines;
602+ pid_t dbus_pid = 0;
603+ pid_t dbus_pid2 = 0;
604+ pid_t upstart_pid = 0;
605+ nih_local char *cmd = NULL;
606+ char **output;
607+ nih_local char *dbus_session_address = NULL;
608+ nih_local char *dbus_session_address2 = NULL;
609+ nih_local char *upstart_session = NULL;
610+ char *address;
611+
612+ TEST_GROUP ("D-Bus connection");
613+
614+ /*********************************************************************/
615+ TEST_FEATURE ("ensure non-priv non-Session Init connects to D-Bus session bus on startup");
616+
617+ /* Start a dbus-daemon */
618+ TEST_DBUS (dbus_pid);
619+
620+ /* Not required */
621+ assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
622+
623+ TEST_TRUE (getenv ("DBUS_SESSION_BUS_ADDRESS"));
624+
625+ START_UPSTART (upstart_pid, FALSE);
626+
627+ cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
628+ TEST_NE_P (cmd, NULL);
629+ RUN_COMMAND (NULL, cmd, &output, &lines);
630+ TEST_EQ (lines, 1);
631+ TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
632+ nih_free (output);
633+
634+ STOP_UPSTART (upstart_pid);
635+ TEST_DBUS_END (dbus_pid);
636+
637+ /*********************************************************************/
638+ TEST_FEATURE ("ensure Session Init does not connect to D-Bus session bus on startup");
639+
640+ /* Start a dbus-daemon */
641+ TEST_DBUS (dbus_pid);
642+
643+ /* Not required */
644+ assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
645+
646+ TEST_TRUE (getenv ("DBUS_SESSION_BUS_ADDRESS"));
647+
648+ START_UPSTART (upstart_pid, TRUE);
649+
650+ address = getenv ("DBUS_SESSION_BUS_ADDRESS");
651+ TEST_NE_P (address, NULL);
652+ dbus_session_address = nih_strdup (NULL, address);
653+ TEST_NE_P (dbus_session_address, NULL);
654+
655+ /* Stop initctl using this route */
656+ assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS"));
657+
658+ /* Check we can query the version via the private socket */
659+ cmd = nih_sprintf (NULL, "%s version 2>&1", get_initctl_binary ());
660+ TEST_NE_P (cmd, NULL);
661+ RUN_COMMAND (NULL, cmd, &output, &lines);
662+ TEST_EQ (lines, 1);
663+ TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
664+ nih_free (output);
665+
666+ /* Unset to stop initctl finding upstart via this route */
667+ assert0 (unsetenv ("UPSTART_SESSION"));
668+
669+ /* Re-apply in the test environment */
670+ assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1));
671+
672+ /* Although there is a D-Bus session bus available, the Session
673+ * Init should not connect to it. Check this by trying to query
674+ * the running version via the D-Bus session bus.
675+ */
676+ cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
677+ TEST_NE_P (cmd, NULL);
678+ RUN_COMMAND (NULL, cmd, &output, &lines);
679+ TEST_EQ (lines, 1);
680+ TEST_STR_MATCH (output[0], "initctl: Name \"com.ubuntu.Upstart\" does not exist*");
681+ nih_free (output);
682+
683+ STOP_UPSTART (upstart_pid);
684+ TEST_DBUS_END (dbus_pid);
685+
686+ /*********************************************************************/
687+ TEST_FEATURE ("ensure Session Init connects to D-Bus session bus when notified");
688+
689+ /* Start a dbus-daemon */
690+ TEST_DBUS (dbus_pid);
691+
692+ address = getenv ("DBUS_SESSION_BUS_ADDRESS");
693+ TEST_NE_P (address, NULL);
694+ dbus_session_address = nih_strdup (NULL, address);
695+ TEST_NE_P (dbus_session_address, NULL);
696+
697+ /* Not required */
698+ assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
699+ assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS"));
700+
701+ START_UPSTART (upstart_pid, TRUE);
702+
703+ /* Pass the D-Bus session bus address to the Session Init */
704+ cmd = nih_sprintf (NULL, "%s notify-dbus-address \"%s\" 2>&1",
705+ get_initctl_binary (), dbus_session_address);
706+ TEST_NE_P (cmd, NULL);
707+ RUN_COMMAND (NULL, cmd, &output, &lines);
708+ TEST_EQ (lines, 0);
709+
710+ /* Re-apply in the test environment */
711+ assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1));
712+
713+ /* It should now be possible to query the running version via
714+ * the D-Bus session bus.
715+ */
716+ cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
717+ TEST_NE_P (cmd, NULL);
718+ RUN_COMMAND (NULL, cmd, &output, &lines);
719+ TEST_EQ (lines, 1);
720+ TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
721+ nih_free (output);
722+
723+ STOP_UPSTART (upstart_pid);
724+ TEST_DBUS_END (dbus_pid);
725+
726+ /*********************************************************************/
727+ TEST_FEATURE ("ensure Session Init does not connect to another bus when notified twice");
728+
729+ /* Start first dbus-daemon */
730+ TEST_DBUS (dbus_pid);
731+
732+ /* Save its address */
733+ address = getenv ("DBUS_SESSION_BUS_ADDRESS");
734+ TEST_NE_P (address, NULL);
735+ dbus_session_address = nih_strdup (NULL, address);
736+ TEST_NE_P (dbus_session_address, NULL);
737+
738+ /* Start second dbus-daemon */
739+ TEST_DBUS (dbus_pid2);
740+
741+ /* Save its address */
742+ address = getenv ("DBUS_SESSION_BUS_ADDRESS");
743+ TEST_NE_P (address, NULL);
744+ dbus_session_address2 = nih_strdup (NULL, address);
745+ TEST_NE_P (dbus_session_address2, NULL);
746+
747+ assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
748+ assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS"));
749+
750+ START_UPSTART (upstart_pid, TRUE);
751+
752+ /* Pass the first D-Bus session bus address to the Session Init */
753+ cmd = nih_sprintf (NULL, "%s notify-dbus-address \"%s\" 2>&1",
754+ get_initctl_binary (), dbus_session_address);
755+ TEST_NE_P (cmd, NULL);
756+ RUN_COMMAND (NULL, cmd, &output, &lines);
757+ TEST_EQ (lines, 0);
758+
759+ /* Re-apply in the test environment */
760+ assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1));
761+
762+ /* It should now be possible to query the running version via
763+ * the D-Bus session bus.
764+ */
765+ cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
766+ TEST_NE_P (cmd, NULL);
767+ RUN_COMMAND (NULL, cmd, &output, &lines);
768+ TEST_EQ (lines, 1);
769+ TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
770+ nih_free (output);
771+
772+ /* Pass the second D-Bus session bus address to the Session Init */
773+ cmd = nih_sprintf (NULL, "%s notify-dbus-address \"%s\" 2>&1",
774+ get_initctl_binary (), dbus_session_address2);
775+ TEST_NE_P (cmd, NULL);
776+ RUN_COMMAND (NULL, cmd, &output, &lines);
777+ TEST_EQ (lines, 0);
778+
779+ /* Check that the Session Init still responds on the first address */
780+ cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
781+ TEST_NE_P (cmd, NULL);
782+ RUN_COMMAND (NULL, cmd, &output, &lines);
783+ TEST_EQ (lines, 1);
784+ TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
785+ nih_free (output);
786+
787+ /* Stop the 1st daemon */
788+ TEST_DBUS_END (dbus_pid);
789+
790+ /* Switch to the 2nd daemon */
791+ assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address2, 1));
792+
793+ /* Ensure the Session Init isn't responding on this address */
794+ cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
795+ TEST_NE_P (cmd, NULL);
796+ RUN_COMMAND (NULL, cmd, &output, &lines);
797+ TEST_EQ (lines, 1);
798+ TEST_STR_MATCH (output[0], "initctl: Name \"com.ubuntu.Upstart\" does not exist*");
799+ nih_free (output);
800+
801+ STOP_UPSTART (upstart_pid);
802+
803+ /* Stop the 2nd daemon */
804+ TEST_DBUS_END (dbus_pid2);
805+}
806+
807 int
808 main (int argc,
809 char *argv[])
810@@ -16834,5 +17043,7 @@
811 test_notify_disk_writeable ();
812 }
813
814+ test_dbus_connection ();
815+
816 return 0;
817 }

Subscribers

People subscribed via source and target branches