Merge authors:
  James Hunt (jamesodhunt)
Related merge proposals:
  https://code.launchpad.net/~jamesodhunt/upstart/bug-1083723/+merge/136959
  proposed by: James Hunt (jamesodhunt)
------------------------------------------------------------
revno: 1399 [merge]
fixes bug: https://launchpad.net/bugs/1083723
committer: Steve Langasek <[email protected]>
branch nick: upstream
timestamp: Thu 2012-12-06 09:30:31 -0800
message:
  Merge fix for bug #1083723
modified:
  ChangeLog
  dbus/com.ubuntu.Upstart.xml
  init/control.c
  init/control.h
  util/Makefile.am
  util/man/telinit.8
  util/telinit.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	2012-12-06 16:40:17 +0000
+++ ChangeLog	2012-12-06 17:30:31 +0000
@@ -2,7 +2,7 @@
 
 	* init/job_class.c:
 	  - job_class_add_safe(): Don't assert on name collisions for jobs
-	    associated with a different session.  (LP: #109715).
+	    associated with a different session.  (LP: #1079715).
 	  - job_class_serialise(): Explicitly disallow user and chroot
 	    sessions from being serialised since this scenario is not
 	    supported (due to our not serialising ConfSource objects yet).
@@ -44,6 +44,15 @@
 	  'GetState' method.
 	* init/tests/data/upstart-1.6.json: Test data used by test_state.c
 	  for upgrade testing the upstart 1.6 serialization format.
+	* dbus/com.ubuntu.Upstart.xml: New 'Restart' method.
+	* init/control.c: control_restart(): New function to request Upstart
+	  restart itself.
+	* util/telinit.c: use the new dbus interface for restarts;
+	  'telinit u' now fails with an error when PID 1 is not upstart,
+	  instead of sending it a signal with undefined behavior.
+	  (LP: #1083723)
+	* util/man/telinit.8: Update for 'telinit u' behaviour if PID 1 is
+	  not Upstart.
 
 2012-11-23  James Hunt  <[email protected]>
 

=== modified file 'dbus/com.ubuntu.Upstart.xml'
--- dbus/com.ubuntu.Upstart.xml	2012-12-04 16:09:18 +0000
+++ dbus/com.ubuntu.Upstart.xml	2012-12-06 17:30:31 +0000
@@ -38,6 +38,8 @@
       <arg name="state" type="s" direction="out" />
     </method>
 
+    <method name="Restart"/>
+
     <!-- Signals for changes to the job list -->
     <signal name="JobAdded">
       <arg name="job" type="o" />

=== modified file 'init/control.c'
--- init/control.c	2012-12-06 09:40:25 +0000
+++ init/control.c	2012-12-06 17:30:31 +0000
@@ -1011,3 +1011,59 @@
 			_("Out of Memory"));
 	return -1;
 }
+
+/**
+ * control_restart:
+ *
+ * @data: not used,
+ * @message: D-Bus connection and message received.
+ *
+ * Implements the Restart method of the com.ubuntu.Upstart
+ * interface.
+ *
+ * Called to request that Upstart performs a stateful re-exec.
+ *
+ * Returns: zero on success, negative value on raised error.
+ **/
+int
+control_restart (void           *data,
+		 NihDBusMessage *message)
+{
+	Session  *session;
+	uid_t     uid;
+
+	nih_assert (message != NULL);
+
+	uid = getuid ();
+
+	/* Get the relevant session */
+	session = session_from_dbus (NULL, message);
+
+	/* Chroot sessions must not be able to influence
+	 * the outside system.
+	 *
+	 * Making this a NOP is safe since it is the Upstart outside the
+	 * chroot which manages all chroot jobs.
+	 */
+	if (session && session->chroot) {
+		nih_warn (_("Ignoring restart request from chroot session"));
+		return 0;
+	}
+
+	/* Disallow users from restarting Upstart, unless they happen to
+	 * own this process (which they may do in the test scenario and
+	 * when running Upstart as a non-privileged user).
+	 */
+	if (session && session->user != uid) {
+		nih_dbus_error_raise_printf (
+			DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
+			_("You do not have permission to request restart"));
+		return -1;
+	}
+
+	nih_info (_("Restarting"));
+
+	stateful_reexec ();
+
+	return 0;
+}

=== modified file 'init/control.h'
--- init/control.h	2012-12-04 16:09:18 +0000
+++ init/control.h	2012-12-06 17:30:31 +0000
@@ -110,6 +110,9 @@
 		   char           **state)
 	__attribute__ ((warn_unused_result));
 
+int  control_restart (void *data, NihDBusMessage *message)
+	__attribute__ ((warn_unused_result));
+
 NIH_END_EXTERN
 
 #endif /* INIT_CONTROL_H */

=== modified file 'util/Makefile.am'
--- util/Makefile.am	2011-06-01 11:13:42 +0000
+++ util/Makefile.am	2012-11-28 16:33:58 +0000
@@ -71,7 +71,8 @@
 	utmp.c utmp.h \
 	sysv.c sysv.h
 nodist_telinit_SOURCES = \
-	$(com_ubuntu_Upstart_OUTPUTS)
+	$(com_ubuntu_Upstart_OUTPUTS) \
+	$(com_ubuntu_Upstart_Instance_OUTPUTS)
 telinit_LDADD = \
 	$(LTLIBINTL) \
 	$(NIH_LIBS) \

=== modified file 'util/man/telinit.8'
--- util/man/telinit.8	2012-11-07 14:28:34 +0000
+++ util/man/telinit.8	2012-11-28 16:33:58 +0000
@@ -71,10 +71,16 @@
 .BR U " or " u
 to request that the
 .BR init (8)
-daemon re-execute itself.  This is necessary when upgrading the
+daemon re-execute itself.  This is necessary when upgrading the Upstart
 .BR init (8)
 daemon itself or any of its dependent system libraries
 to ensure disks can be unmounted cleanly on shutdown.
+
+Note that if the init daemon is
+.I not
+Upstart, this option will have no effect on the running
+.BR init (8)
+daemon.
 .\"
 .SH OPTIONS
 .TP

=== modified file 'util/telinit.c'
--- util/telinit.c	2009-07-09 11:50:19 +0000
+++ util/telinit.c	2012-12-06 11:38:02 +0000
@@ -38,12 +38,27 @@
 #include <nih/logging.h>
 #include <nih/error.h>
 
+#include <nih-dbus/dbus_error.h>
+#include <nih-dbus/dbus_proxy.h>
+#include <nih-dbus/errors.h>
+#include <nih-dbus/dbus_connection.h>
+
+#include "dbus/upstart.h"
+
+#include "com.ubuntu.Upstart.h"
+
 #include "sysv.h"
 
 
 /* Prototypes for option functions */
 int env_option (NihOption *option, const char *arg);
 
+NihDBusProxy * upstart_open (const void *parent)
+	__attribute__ ((warn_unused_result));
+
+int restart_upstart (void)
+	__attribute__ ((warn_unused_result));
+
 
 /**
  * extra_env:
@@ -83,6 +98,79 @@
 	return 0;
 }
 
+/**
+ * upstart_open:
+ * @parent: parent object for new proxy.
+ *
+ * Opens a connection to the Upstart init daemon and returns a proxy
+ * to the manager object. If @dest_name is not NULL, a connection is
+ * instead opened to the system bus and the proxy linked to the
+ * well-known name given.
+ *
+ * If @parent is not NULL, it should be a pointer to another object
+ * which will be used as a parent for the returned proxy.  When all
+ * parents of the returned proxy are freed, the returned proxy will
+ * also be freed.
+ *
+ * Returns: newly allocated D-Bus proxy or NULL on raised error.
+ **/
+NihDBusProxy *
+upstart_open (const void *parent)
+{
+	DBusError       dbus_error;
+	DBusConnection *connection;
+	NihDBusProxy *  upstart;
+
+	dbus_error_init (&dbus_error);
+
+	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
+	if (! connection) {
+		nih_dbus_error_raise (dbus_error.name, dbus_error.message);
+		dbus_error_free (&dbus_error);
+		return NULL;
+	}
+
+	dbus_connection_set_exit_on_disconnect (connection, FALSE);
+	dbus_error_free (&dbus_error);
+
+	upstart = nih_dbus_proxy_new (parent, connection,
+				      DBUS_SERVICE_UPSTART,
+				      DBUS_PATH_UPSTART,
+				      NULL, NULL);
+	if (! upstart) {
+		dbus_connection_unref (connection);
+		return NULL;
+	}
+
+	upstart->auto_start = FALSE;
+
+	/* Drop initial reference now the proxy holds one */
+	dbus_connection_unref (connection);
+
+	return upstart;
+}
+
+/**
+ * restart_upstart:
+ *
+ * Request Upstart restart itself.
+ *
+ * Returns: 0 on SUCCESS, -1 on raised error.
+ **/
+int
+restart_upstart (void)
+{
+	nih_local NihDBusProxy *upstart = NULL;
+
+	upstart = upstart_open (NULL);
+	if (! upstart)
+		return -1;
+
+	if (upstart_restart_sync (NULL, upstart) < 0)
+		return -1;
+
+	return 0;
+}
 
 #ifndef TEST
 /**
@@ -107,7 +195,7 @@
 {
 	char **args;
 	int    runlevel;
-	int    ret;
+	int    ret = 0;
 
 	nih_main_init (argv[0]);
 
@@ -174,9 +262,8 @@
 		break;
 	case 'U':
 	case 'u':
-		ret = kill (1, SIGTERM);
-		if (ret < 0)
-			nih_error_raise_system ();
+		/* If /sbin/init is not Upstart, just exit non-zero */
+		ret = restart_upstart ();
 		break;
 	default:
 		nih_assert_not_reached ();

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

Reply via email to