Merge authors:
  James Hunt (jamesodhunt)
Related merge proposals:
  https://code.launchpad.net/~jamesodhunt/upstart/bug-1235649/+merge/192703
  proposed by: James Hunt (jamesodhunt)
  review: Approve - Dmitrijs Ledkovs (xnox)
------------------------------------------------------------
revno: 1554 [merge]
committer: James Hunt <[email protected]>
branch nick: upstart
timestamp: Mon 2013-11-04 11:45:30 +0000
message:
  * Merge lp:~jamesodhunt/upstart/bug-1235649.
modified:
  ChangeLog
  dbus/com.ubuntu.Upstart.xml
  init/control.c
  init/control.h
  init/main.c
  init/tests/test_control.c
  util/initctl.c
  util/man/initctl.8
  util/tests/test_initctl.c


--
lp:upstart
https://code.launchpad.net/~upstart-devel/upstart/trunk

Your team Upstart Reviewers is subscribed to branch lp:upstart.
To unsubscribe from this branch go to 
https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'ChangeLog'
--- ChangeLog	2013-11-03 02:56:57 +0000
+++ ChangeLog	2013-11-04 11:43:30 +0000
@@ -1,10 +1,3 @@
-2013-10-25  Steve Langasek  <[email protected]>
-
-	* init/main.c, init/system.c, init/system.h: allow mount options
-	  to be passed to system_mount(), and pass the right options when
-	  mounting /dev/pts to match the permissions set by either
-	  initramfs-tools or mountall.  LP: #1244763.
-
 2013-11-03  James Hunt  <[email protected]>
 
 	* init/job_class.c:
@@ -59,6 +52,44 @@
 	* scripts/tests/test_pyupstart_session_init.py: Added file bridge tests
 	  for directory creation, modification and deletion.
 
+2013-10-25  James Hunt  <[email protected]>
+
+	* dbus/com.ubuntu.Upstart.xml: Added 'NotifyDBusAddress' method.
+	* init/control.c:
+	  - control_bus_open(): Connect to the D-Bus bus specified
+	    by control_bus_address when running as a Session Init (LP: #1203595, #1235649).
+	  - control_disconnected(): Display calculated bus type rather than hard-coding.
+	  - control_handle_bus_type(): Removed.
+	  - control_get_bus_type(): Determine type of D-Bus bus that will be used.
+	  - control_notify_dbus_address(): Implementation of D-Bus 'NotifyDBusAddress' method
+	    that sets control_bus_address.
+	* init/main.c:
+	  - main():
+	    - Just check USE_SESSION_BUS_ENV variable rather than calling
+	      control_handle_bus_type().
+	    - Don't register SIGUSR1 handler for Session Init.
+	  - usr1_handler(): Display calculated bus type rather than hard-coding.
+	* init/test_control.c: Updated strings used by tests which check error
+	  messages to include 'D-Bus'.
+	* util/initctl.c: Added new 'notify-dbus-address' command.
+	* util/man/initctl.8:
+	  - Documentation for new 'notify-dbus-address' command.
+	  - reset-env: Troff fix.
+	  - Explain '--user' implicit in user mode.
+	* util/tests/test_initctl.c: test_dbus_connection(): New function providing
+	  the following new tests:
+	  - "ensure non-priv non-Session Init connects to D-Bus session bus on startup".
+	  - "ensure Session Init does not connect to D-Bus session bus on startup".
+	  - "ensure Session Init connects to D-Bus session bus when notified".
+	  - "ensure Session Init does not connect to another bus when notified twice".
+
+2013-10-25  Steve Langasek  <[email protected]>
+
+	* init/main.c, init/system.c, init/system.h: allow mount options
+	  to be passed to system_mount(), and pass the right options when
+	  mounting /dev/pts to match the permissions set by either
+	  initramfs-tools or mountall.  LP: #1244763.
+
 2013-10-24  James Hunt  <[email protected]>
 
 	* init/environ.c: Comment.
@@ -79,7 +110,7 @@
 
 2013-10-23  Dmitrijs Ledkovs  <[email protected]>
 
- 	* extra/upstart-socket-bridge.c: use SOCKET_PATH in our event
+	* extra/upstart-socket-bridge.c: use SOCKET_PATH in our event
 	  environment, instead of clobbering PATH.  (LP: #1235480)
 
 2013-10-23  James Hunt  <[email protected]>

=== modified file 'dbus/com.ubuntu.Upstart.xml'
--- dbus/com.ubuntu.Upstart.xml	2013-02-08 16:15:23 +0000
+++ dbus/com.ubuntu.Upstart.xml	2013-10-25 13:49:49 +0000
@@ -103,6 +103,10 @@
     <method name="NotifyDiskWriteable">
     </method>
 
+    <method name="NotifyDBusAddress">
+      <arg name="address" type="s" direction="in" />
+    </method>
+
     <method name="EndSession"/>
 
     <!-- Basic information about Upstart -->

=== modified file 'init/control.c'
--- init/control.c	2013-04-22 10:30:09 +0000
+++ init/control.c	2013-10-25 13:49:49 +0000
@@ -81,11 +81,19 @@
  *
  * If TRUE, connect to the D-Bus session bus rather than the system bus.
  *
- * Used for testing.
+ * Used for testing to simulate (as far as possible) a system-like init
+ * when running as a non-priv user (but not as a Session Init).
  **/
 int use_session_bus = FALSE;
 
 /**
+ * dbus_bus_type:
+ *
+ * Type of D-Bus bus to connect to.
+ **/
+DBusBusType dbus_bus_type;
+
+/**
  * control_server_address:
  *
  * Address on which the control server may be reached.
@@ -100,6 +108,13 @@
 DBusServer *control_server = NULL;
 
 /**
+ * control_bus_address:
+ *
+ * Address on which the control bus may be reached.
+ **/
+char *control_bus_address = NULL;
+
+/**
  * control_bus:
  *
  * Open connection to a D-Bus bus.  The connection may be opened with
@@ -236,7 +251,6 @@
 	control_server = NULL;
 }
 
-
 /**
  * control_bus_open:
  *
@@ -256,17 +270,37 @@
 
 	nih_assert (control_bus == NULL);
 
+	dbus_error_init (&error);
+
 	control_init ();
 
-	control_handle_bus_type ();
+	dbus_bus_type = control_get_bus_type ();
 
-	/* Connect to the D-Bus System Bus and hook everything up into
+	/* Connect to the appropriate D-Bus bus and hook everything up into
 	 * our own main loop automatically.
 	 */
-	conn = nih_dbus_bus (use_session_bus ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM,
-			     control_disconnected);
-	if (! conn)
-		return -1;
+	if (user_mode && control_bus_address) {
+		conn = nih_dbus_connect (control_bus_address, control_disconnected);
+		if (! conn)
+			return -1;
+
+		if (! dbus_bus_register (conn, &error)) {
+			nih_dbus_error_raise (error.name, error.message);
+			dbus_error_free (&error);
+			return -1;
+		}
+
+		nih_debug ("Connected to notified D-Bus bus");
+	} else {
+		conn = nih_dbus_bus (use_session_bus ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM,
+				control_disconnected);
+		if (! conn)
+			return -1;
+
+		nih_debug ("Connected to D-Bus %s bus",
+				dbus_bus_type == DBUS_BUS_SESSION
+				? "session" : "system");
+	}
 
 	/* Register objects on the bus. */
 	control_register_all (conn);
@@ -275,7 +309,6 @@
 	 * appears on the bus, clients can assume we're ready to talk to
 	 * them.
 	 */
-	dbus_error_init (&error);
 	ret = dbus_bus_request_name (conn, DBUS_SERVICE_UPSTART,
 				     DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
 	if (ret < 0) {
@@ -345,7 +378,13 @@
 
 		dbus_error_init (&error);
 
-		nih_warn (_("Disconnected from system bus"));
+		if (user_mode && control_bus_address) {
+			nih_warn (_("Disconnected from notified D-Bus bus"));
+		} else {
+			nih_warn (_("Disconnected from D-Bus %s bus"),
+					dbus_bus_type == DBUS_BUS_SESSION
+					? "session" : "system");
+		}
 
 		control_bus = NULL;
 	}
@@ -817,19 +856,20 @@
 }
 
 /**
- * control_handle_bus_type:
+ * control_get_bus_type:
  *
  * Determine D-Bus bus type to connect to.
+ *
+ * Returns: Type of D-Bus bus to connect to.
  **/
-void
-control_handle_bus_type (void)
+DBusBusType
+control_get_bus_type (void)
 {
-	if (getenv (USE_SESSION_BUS_ENV))
-		use_session_bus = TRUE;
+	return (use_session_bus || user_mode) 
+		? DBUS_BUS_SESSION
+		: DBUS_BUS_SYSTEM;
+}
 
-	if (use_session_bus)
-		nih_debug ("Using session bus");
-}
 /**
  * control_notify_disk_writeable:
  * @data: not used,
@@ -882,6 +922,59 @@
 }
 
 /**
+ * control_notify_dbus_address:
+ * @data: not used,
+ * @message: D-Bus connection and message received,
+ * @address: Address of D-Bus to connect to.
+ *
+ * Implements the NotifyDBusAddress method of the
+ * com.ubuntu.Upstart interface.
+ *
+ * Called to allow the Session Init to connect to the D-Bus
+ * Session Bus when available.
+ *
+ * Returns: zero on success, negative value on raised error.
+ **/
+int
+control_notify_dbus_address (void            *data,
+			     NihDBusMessage  *message,
+			     const char      *address)
+{
+	nih_assert (message);
+	nih_assert (address);
+
+	if (getpid () == 1) {
+		nih_dbus_error_raise_printf (
+			DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
+			_("Not permissible to notify D-Bus address for PID 1"));
+		return -1;
+	}
+
+	if (! control_check_permission (message)) {
+		nih_dbus_error_raise_printf (
+			DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
+			_("You do not have permission to notify D-Bus address"));
+		return -1;
+	}
+
+	/* Ignore as already connected */
+	if (control_bus)
+		return 0;
+
+	control_bus_address = nih_strdup (NULL, address);
+	if (! control_bus_address) {
+		nih_dbus_error_raise_printf (DBUS_ERROR_NO_MEMORY,
+				_("Out of Memory"));
+		return -1;
+	}
+
+	if (control_bus_open () < 0)
+		return -1;
+
+	return 0;
+}
+
+/**
  * control_bus_flush:
  *
  * Drain any remaining messages in the D-Bus queue.

=== modified file 'init/control.h'
--- init/control.h	2013-05-08 16:21:08 +0000
+++ init/control.h	2013-10-25 13:49:49 +0000
@@ -134,7 +134,8 @@
 				   const char *log_priority)
 	__attribute__ ((warn_unused_result));
 
-void control_handle_bus_type      (void);
+DBusBusType control_get_bus_type (void)
+	__attribute__ ((warn_unused_result));
 
 void control_prepare_reexec       (void);
 
@@ -157,8 +158,18 @@
 	__attribute__ ((warn_unused_result));
 
 void control_notify_event_emitted (Event *event);
+
 void control_notify_restarted (void);
 
+int control_notify_disk_writeable (void   *data,
+		     NihDBusMessage *message)
+	__attribute__ ((warn_unused_result));
+
+int control_notify_dbus_address (void   *data,
+		     NihDBusMessage *message,
+		     const char *address)
+	__attribute__ ((warn_unused_result));
+
 int control_set_env (void           *data,
 		 NihDBusMessage *message,
 		 char * const    *job_details,

=== modified file 'init/main.c'
--- init/main.c	2013-11-03 02:56:57 +0000
+++ init/main.c	2013-11-04 11:43:30 +0000
@@ -128,6 +128,7 @@
 extern int          default_console;
 extern int          write_state_file;
 extern char        *log_dir;
+extern DBusBusType  dbus_bus_type;
 extern mode_t       initial_umask;
 
 /**
@@ -213,7 +214,8 @@
 	if (disable_job_logging)
 		nih_debug ("Job logging disabled");
 
-	control_handle_bus_type ();
+	if (getenv (USE_SESSION_BUS_ENV))
+		use_session_bus = TRUE;
 
 	if (! user_mode)
 		no_inherit_env = TRUE;
@@ -447,9 +449,14 @@
 	nih_signal_set_handler (SIGHUP, nih_signal_handler);
 	NIH_MUST (nih_signal_add_handler (NULL, SIGHUP, hup_handler, NULL));
 
-	/* SIGUSR1 instructs us to reconnect to D-Bus */
-	nih_signal_set_handler (SIGUSR1, nih_signal_handler);
-	NIH_MUST (nih_signal_add_handler (NULL, SIGUSR1, usr1_handler, NULL));
+	/* Session Inits only reconnect to D-Bus when notified
+	 * via their private socket.
+	 */
+	if (! user_mode) {
+		/* SIGUSR1 instructs us to reconnect to D-Bus */
+		nih_signal_set_handler (SIGUSR1, nih_signal_handler);
+		NIH_MUST (nih_signal_add_handler (NULL, SIGUSR1, usr1_handler, NULL));
+	}
 
 	/* SIGTERM instructs us to re-exec ourselves when running as PID
 	 * 1, or to exit when running as a Session Init; this signal should
@@ -941,15 +948,23 @@
 usr1_handler (void      *data,
 	      NihSignal *signal)
 {
+	nih_assert (! user_mode);
+
 	if (! control_bus) {
-		nih_info (_("Reconnecting to system bus"));
+		char *dbus_bus_name;
+
+		dbus_bus_name = dbus_bus_type == DBUS_BUS_SESSION
+			? "session" : "system";
+
+		nih_info (_("Reconnecting to D-Bus %s bus"),
+				dbus_bus_name);
 
 		if (control_bus_open () < 0) {
 			NihError *err;
 
 			err = nih_error_get ();
-			nih_warn ("%s: %s", _("Unable to connect to the system bus"),
-				  err->message);
+			nih_warn (_("Unable to connect to the D-Bus %s bus: %s"),
+					dbus_bus_name, err->message);
 			nih_free (err);
 		}
 	}

=== modified file 'init/tests/test_control.c'
--- init/tests/test_control.c	2012-09-09 21:27:24 +0000
+++ init/tests/test_control.c	2013-10-25 13:49:49 +0000
@@ -821,7 +821,7 @@
 
 	TEST_LIST_EMPTY (control_conns);
 
-	TEST_FILE_EQ (output, "test: Disconnected from system bus\n");
+	TEST_FILE_EQ (output, "test: Disconnected from D-Bus system bus\n");
 	TEST_FILE_END (output);
 	TEST_FILE_RESET (output);
 
@@ -879,7 +879,7 @@
 
 	TEST_LIST_EMPTY (control_conns);
 
-	TEST_FILE_EQ (output, "test: Disconnected from system bus\n");
+	TEST_FILE_EQ (output, "test: Disconnected from D-Bus system bus\n");
 	TEST_FILE_END (output);
 	TEST_FILE_RESET (output);
 

=== modified file 'util/initctl.c'
--- util/initctl.c	2013-07-21 23:54:16 +0000
+++ util/initctl.c	2013-10-25 13:49:49 +0000
@@ -342,8 +342,7 @@
 			use_dbus = getuid () ? TRUE : FALSE;
 		if (use_dbus >= 0 && dbus_bus_type < 0)
 			dbus_bus_type = DBUS_BUS_SYSTEM;
-	}
-	else {
+	} else {
 		if (! user_addr) {
 			nih_error ("UPSTART_SESSION isn't set in the environment. "
 				       "Unable to locate the Upstart instance.");
@@ -353,7 +352,6 @@
 		use_dbus = FALSE;
 	}
 
-
 	dbus_error_init (&dbus_error);
 	if (use_dbus) {
 		if (! dest_name)
@@ -387,6 +385,7 @@
 			return NULL;
 		}
 	}
+
 	dbus_error_free (&dbus_error);
 
 	upstart = nih_dbus_proxy_new (parent, connection,
@@ -1987,6 +1986,51 @@
 
 
 /**
+ * notify_dbus_address_action:
+ * @command: NihCommand invoked,
+ * @args: command-line arguments.
+ *
+ * This function is called for the "notify-dbus-address" command.
+ *
+ * Returns: command exit status.
+ **/
+int
+notify_dbus_address_action (NihCommand    *command,
+			    char * const  *args)
+{
+	nih_local NihDBusProxy   *upstart = NULL;
+	NihError                 *err;
+	char                     *address = NULL;
+
+	nih_assert (command != NULL);
+	nih_assert (args != NULL);
+
+	if (! args[0]) {
+		fprintf (stderr, _("%s: missing D-Bus address\n"), program_name);
+		nih_main_suggest_help ();
+		return 1;
+	}
+
+	address = args[0];
+
+	upstart = upstart_open (NULL);
+	if (! upstart)
+		return 1;
+
+	if (upstart_notify_dbus_address_sync (NULL, upstart, address) < 0)
+		goto error;
+
+	return 0;
+
+error:
+	err = nih_error_get ();
+	nih_error ("%s", err->message);
+	nih_free (err);
+
+	return 1;
+}
+
+/**
  * list_sessions_action:
  * @command: NihCommand invoked,
  * @args: command-line arguments.
@@ -2827,7 +2871,7 @@
  * Command-line options accepted for all arguments.
  **/
 static NihOption options[] = {
-	{ 0, "session", N_("use D-Bus session bus to connect to init daemon (for testing)"),
+	{ 0, "session", N_("use existing D-Bus session bus to connect to init daemon (for testing)"),
 	  NULL, NULL, NULL, dbus_bus_type_setter },
 	{ 0, "system", N_("use D-Bus system bus to connect to init daemon"),
 	  NULL, NULL, NULL, dbus_bus_type_setter },
@@ -3193,6 +3237,11 @@
 	  N_("JOB is the name of the job which usage is to be shown.\n" ),
 	  NULL, usage_options, usage_action },
 
+	{ "notify-dbus-address", NULL,
+	  N_("Inform Upstart of D-Bus address to connect to."),
+	  N_("Run to allow Upstart to provide services over D-Bus."),
+	  NULL, NULL, notify_dbus_address_action},
+
 	{ "notify-disk-writeable", NULL,
 	  N_("Inform Upstart that disk is now writeable."),
 	  N_("Run to ensure output from jobs ending before "

=== modified file 'util/man/initctl.8'
--- util/man/initctl.8	2013-05-31 15:41:20 +0000
+++ util/man/initctl.8	2013-10-25 13:49:49 +0000
@@ -42,14 +42,19 @@
 .B \-\-user
 User mode. In this mode, initctl will talk to the
 .BR init (8)
-daemon using the D\-Bus private socket defined in the UPSTART_SESSION
+daemon using the D\-Bus private socket defined in the
+.B UPSTART_SESSION
 environment variable.
+
+Note that if the
+.B UPSTART_SESSION
+variable is defined, this option is implied.
 .\"
 .TP
 .B \-\-session
 Connect to
 .BR init (8)
-daemon using the D\-Bus session bus (for testing purposes only).
+daemon using the existing D\-Bus session bus (for testing purposes only).
 .\"
 .TP
 .B \-\-system
@@ -555,6 +560,18 @@
 .RE
 .\"
 .TP
+.B notify\-dbus\-address
+Notify the
+.BR init (8)
+daemon of the D\-Bus address it should use to connect to.
+
+This command is only permitted when running in
+.B User Session Mode.
+See 
+.BR init (5)
+for further details.
+.\"
+.TP
 .B list\-env
 .RI [ OPTIONS "]
 
@@ -608,7 +625,7 @@
 Adds or updates a variable in a job environment table. Variables set
 in this way will apply to all subsequently-starting jobs.
 
-This command is only permitted When running in
+This command is only permitted when running in
 .B User Session Mode.
 See 
 .BR init (5)
@@ -640,7 +657,7 @@
 Remove the specified variable from a job environment table. If the
 variable does not already exist in the table, no change will be made.
 
-This command is only permitted When running in
+This command is only permitted when running in
 .B User Session Mode.
 See 
 .BR init (5)
@@ -667,12 +684,12 @@
 .\"
 .TP
 .B reset\-env
-.R [ OPTIONS ]
+.RI [ OPTIONS ]
 
 Discards all changes make to a job environment table, setting it back
 to its default set of variables and values.
 
-This command is only permitted When running in
+This command is only permitted when running in
 .B User Session Mode.
 See 
 .BR init (5)

=== modified file 'util/tests/test_initctl.c'
--- util/tests/test_initctl.c	2013-10-18 09:13:36 +0000
+++ util/tests/test_initctl.c	2013-11-04 11:43:30 +0000
@@ -16790,6 +16790,215 @@
         TEST_EQ (rmdir (logdir), 0);
 }
 
+void
+test_dbus_connection (void)
+{
+	size_t           lines;
+	pid_t            dbus_pid = 0;
+	pid_t            dbus_pid2 = 0;
+	pid_t            upstart_pid = 0;
+	nih_local char  *cmd = NULL;
+	char           **output;
+	nih_local char  *dbus_session_address = NULL;
+	nih_local char  *dbus_session_address2 = NULL;
+	nih_local char  *upstart_session = NULL;
+	char            *address;
+
+	TEST_GROUP ("D-Bus connection");
+
+	/*********************************************************************/
+	TEST_FEATURE ("ensure non-priv non-Session Init connects to D-Bus session bus on startup");
+
+	/* Start a dbus-daemon */
+	TEST_DBUS (dbus_pid);
+
+	/* Not required */
+	assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
+
+	TEST_TRUE (getenv ("DBUS_SESSION_BUS_ADDRESS"));
+
+	START_UPSTART (upstart_pid, FALSE);
+
+	cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
+	nih_free (output);
+
+	STOP_UPSTART (upstart_pid);
+	TEST_DBUS_END (dbus_pid);
+
+	/*********************************************************************/
+	TEST_FEATURE ("ensure Session Init does not connect to D-Bus session bus on startup");
+
+	/* Start a dbus-daemon */
+	TEST_DBUS (dbus_pid);
+
+	/* Not required */
+	assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
+
+	TEST_TRUE (getenv ("DBUS_SESSION_BUS_ADDRESS"));
+
+	START_UPSTART (upstart_pid, TRUE);
+
+	address = getenv ("DBUS_SESSION_BUS_ADDRESS");
+	TEST_NE_P (address, NULL);
+	dbus_session_address = nih_strdup (NULL, address);
+	TEST_NE_P (dbus_session_address, NULL);
+
+	/* Stop initctl using this route */
+	assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS"));
+
+	/* Check we can query the version via the private socket */
+	cmd = nih_sprintf (NULL, "%s version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
+	nih_free (output);
+
+	/* Unset to stop initctl finding upstart via this route */
+	assert0 (unsetenv ("UPSTART_SESSION"));
+
+	/* Re-apply in the test environment */
+	assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1));
+
+	/* Although there is a D-Bus session bus available, the Session
+	 * Init should not connect to it. Check this by trying to query
+	 * the running version via the D-Bus session bus.
+	 */
+	cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "initctl: Name \"com.ubuntu.Upstart\" does not exist*");
+	nih_free (output);
+
+	STOP_UPSTART (upstart_pid);
+	TEST_DBUS_END (dbus_pid);
+
+	/*********************************************************************/
+	TEST_FEATURE ("ensure Session Init connects to D-Bus session bus when notified");
+
+	/* Start a dbus-daemon */
+	TEST_DBUS (dbus_pid);
+
+	address = getenv ("DBUS_SESSION_BUS_ADDRESS");
+	TEST_NE_P (address, NULL);
+	dbus_session_address = nih_strdup (NULL, address);
+	TEST_NE_P (dbus_session_address, NULL);
+
+	/* Not required */
+	assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
+	assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS"));
+
+	START_UPSTART (upstart_pid, TRUE);
+
+	/* Pass the D-Bus session bus address to the Session Init */
+	cmd = nih_sprintf (NULL, "%s notify-dbus-address \"%s\" 2>&1",
+			get_initctl_binary (), dbus_session_address);
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 0);
+
+	/* Re-apply in the test environment */
+	assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1));
+
+	/* It should now be possible to query the running version via
+	 * the D-Bus session bus.
+	 */
+	cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
+	nih_free (output);
+
+	STOP_UPSTART (upstart_pid);
+	TEST_DBUS_END (dbus_pid);
+
+	/*********************************************************************/
+	TEST_FEATURE ("ensure Session Init does not connect to another bus when notified twice");
+
+	/* Start first dbus-daemon */
+	TEST_DBUS (dbus_pid);
+
+	/* Save its address */
+	address = getenv ("DBUS_SESSION_BUS_ADDRESS");
+	TEST_NE_P (address, NULL);
+	dbus_session_address = nih_strdup (NULL, address);
+	TEST_NE_P (dbus_session_address, NULL);
+
+	/* Start second dbus-daemon */
+	TEST_DBUS (dbus_pid2);
+
+	/* Save its address */
+	address = getenv ("DBUS_SESSION_BUS_ADDRESS");
+	TEST_NE_P (address, NULL);
+	dbus_session_address2 = nih_strdup (NULL, address);
+	TEST_NE_P (dbus_session_address2, NULL);
+
+	assert0 (unsetenv ("DBUS_SYSTEM_BUS_ADDRESS"));
+	assert0 (unsetenv ("DBUS_SESSION_BUS_ADDRESS"));
+
+	START_UPSTART (upstart_pid, TRUE);
+
+	/* Pass the first D-Bus session bus address to the Session Init */
+	cmd = nih_sprintf (NULL, "%s notify-dbus-address \"%s\" 2>&1",
+			get_initctl_binary (), dbus_session_address);
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 0);
+
+	/* Re-apply in the test environment */
+	assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address, 1));
+
+	/* It should now be possible to query the running version via
+	 * the D-Bus session bus.
+	 */
+	cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
+	nih_free (output);
+
+	/* Pass the second D-Bus session bus address to the Session Init */
+	cmd = nih_sprintf (NULL, "%s notify-dbus-address \"%s\" 2>&1",
+			get_initctl_binary (), dbus_session_address2);
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 0);
+
+	/* Check that the Session Init still responds on the first address */
+	cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "init (upstart [0-9.][0-9.]*");
+	nih_free (output);
+
+	/* Stop the 1st daemon */
+	TEST_DBUS_END (dbus_pid);
+
+	/* Switch to the 2nd daemon */
+	assert0 (setenv ("DBUS_SESSION_BUS_ADDRESS", dbus_session_address2, 1));
+
+	/* Ensure the Session Init isn't responding on this address */
+	cmd = nih_sprintf (NULL, "%s --session version 2>&1", get_initctl_binary ());
+	TEST_NE_P (cmd, NULL);
+	RUN_COMMAND (NULL, cmd, &output, &lines);
+	TEST_EQ (lines, 1);
+	TEST_STR_MATCH (output[0], "initctl: Name \"com.ubuntu.Upstart\" does not exist*");
+	nih_free (output);
+
+	STOP_UPSTART (upstart_pid);
+
+	/* Stop the 2nd daemon */
+	TEST_DBUS_END (dbus_pid2);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -16834,5 +17043,7 @@
 		test_notify_disk_writeable ();
 	}
 
+	test_dbus_connection ();
+
 	return 0;
 }

-- 
upstart-devel mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/upstart-devel

Reply via email to