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

Proposed by James Hunt
Status: Merged
Merged at revision: 1399
Proposed branch: lp:~jamesodhunt/upstart/bug-1083723
Merge into: lp:upstart
Diff against target: 258 lines (+160/-6)
6 files modified
dbus/com.ubuntu.Upstart.xml (+2/-0)
init/control.c (+55/-0)
init/control.h (+3/-0)
util/Makefile.am (+2/-1)
util/man/telinit.8 (+7/-1)
util/telinit.c (+91/-4)
To merge this branch: bzr merge lp:~jamesodhunt/upstart/bug-1083723
Reviewer Review Type Date Requested Status
Upstart Reviewers Pending
Review via email: mp+136959@code.launchpad.net

Description of the change

Stop 'telinit u' causing problems for non-Upstart init (LP: #1083723).

To post a comment you must log in.
lp:~jamesodhunt/upstart/bug-1083723 updated
1394. By James Hunt

* dbus/com.ubuntu.Upstart.xml: New 'Restart' method.
* init/control.c: control_restart(): New function to request Upstart
  restart itself.
* init/control.c: Added prototype for control_restart().

1395. By James Hunt

* util/telinit.c:
  - upstart_open(): Return raised error on failure.
  - init_is_upstart(): Consume raised error on failure.
  - restart_upstart(): New function to request re-exec.
  - main(): Rather than sending PID 1 a SIGTERM in the 'telinit u' scenario,
    request via D-Bus that it restart itself iff it is Upstart. Although
    this could all be handled with the single "Restart" D-Bus method request,
    check PID 1 is Upstart first since this way, it is possible to detect
    and report that the restart request failed.

1396. By James Hunt

* init/control.c: control_restart():
  - Simplified session check.
* util/telinit.c:
  - init_is_upstart(): Removed as redundant.
  - upstart_open(): Removed erroneous comment.
  - restart_upstart(): Changed return values for consistency with other
    calls in main() where an error is expected to set ret to < 0.
  - main(): Just call restart_upstart() in re-exec scenario to avoid the
    creation of a second D-Bus connection.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dbus/com.ubuntu.Upstart.xml'
2--- dbus/com.ubuntu.Upstart.xml 2012-09-09 21:22:06 +0000
3+++ dbus/com.ubuntu.Upstart.xml 2012-12-06 11:40:26 +0000
4@@ -34,6 +34,8 @@
5 <arg name="jobs" type="ao" direction="out" />
6 </method>
7
8+ <method name="Restart"/>
9+
10 <!-- Signals for changes to the job list -->
11 <signal name="JobAdded">
12 <arg name="job" type="o" />
13
14=== modified file 'init/control.c'
15--- init/control.c 2012-09-20 15:16:52 +0000
16+++ init/control.c 2012-12-06 11:40:26 +0000
17@@ -949,3 +949,58 @@
18
19 return 0;
20 }
21+
22+/**
23+ * control_restart:
24+ * @data: not used,
25+ * @message: D-Bus connection and message received.
26+ *
27+ * Implements the Restart method of the com.ubuntu.Upstart
28+ * interface.
29+ *
30+ * Called to request that Upstart performs a stateful re-exec.
31+ *
32+ * Returns: zero on success, negative value on raised error.
33+ **/
34+int
35+control_restart (void *data,
36+ NihDBusMessage *message)
37+{
38+ Session *session;
39+ uid_t uid;
40+
41+ nih_assert (message != NULL);
42+
43+ uid = getuid ();
44+
45+ /* Get the relevant session */
46+ session = session_from_dbus (NULL, message);
47+
48+ /* Chroot sessions must not be able to influence
49+ * the outside system.
50+ *
51+ * Making this a NOP is safe since it is the Upstart outside the
52+ * chroot which manages all chroot jobs.
53+ */
54+ if (session && session->chroot) {
55+ nih_warn (_("Ignoring restart request from chroot session"));
56+ return 0;
57+ }
58+
59+ /* Disallow users from restarting Upstart, unless they happen to
60+ * own this process (which they may do in the test scenario and
61+ * when running Upstart as a non-privileged user).
62+ */
63+ if (session && session->user != uid) {
64+ nih_dbus_error_raise_printf (
65+ DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
66+ _("You do not have permission to request restart"));
67+ return -1;
68+ }
69+
70+ nih_info (_("Restarting"));
71+
72+ stateful_reexec ();
73+
74+ return 0;
75+}
76
77=== modified file 'init/control.h'
78--- init/control.h 2012-09-11 14:59:40 +0000
79+++ init/control.h 2012-12-06 11:40:26 +0000
80@@ -105,6 +105,9 @@
81 int control_bus_release_name (void)
82 __attribute__ ((warn_unused_result));
83
84+int control_restart (void *data, NihDBusMessage *message)
85+ __attribute__ ((warn_unused_result));
86+
87 NIH_END_EXTERN
88
89 #endif /* INIT_CONTROL_H */
90
91=== modified file 'util/Makefile.am'
92--- util/Makefile.am 2011-06-01 11:13:42 +0000
93+++ util/Makefile.am 2012-12-06 11:40:26 +0000
94@@ -71,7 +71,8 @@
95 utmp.c utmp.h \
96 sysv.c sysv.h
97 nodist_telinit_SOURCES = \
98- $(com_ubuntu_Upstart_OUTPUTS)
99+ $(com_ubuntu_Upstart_OUTPUTS) \
100+ $(com_ubuntu_Upstart_Instance_OUTPUTS)
101 telinit_LDADD = \
102 $(LTLIBINTL) \
103 $(NIH_LIBS) \
104
105=== modified file 'util/man/telinit.8'
106--- util/man/telinit.8 2012-11-07 14:28:34 +0000
107+++ util/man/telinit.8 2012-12-06 11:40:26 +0000
108@@ -71,10 +71,16 @@
109 .BR U " or " u
110 to request that the
111 .BR init (8)
112-daemon re-execute itself. This is necessary when upgrading the
113+daemon re-execute itself. This is necessary when upgrading the Upstart
114 .BR init (8)
115 daemon itself or any of its dependent system libraries
116 to ensure disks can be unmounted cleanly on shutdown.
117+
118+Note that if the init daemon is
119+.I not
120+Upstart, this option will have no effect on the running
121+.BR init (8)
122+daemon.
123 .\"
124 .SH OPTIONS
125 .TP
126
127=== modified file 'util/telinit.c'
128--- util/telinit.c 2009-07-09 11:50:19 +0000
129+++ util/telinit.c 2012-12-06 11:40:26 +0000
130@@ -38,12 +38,27 @@
131 #include <nih/logging.h>
132 #include <nih/error.h>
133
134+#include <nih-dbus/dbus_error.h>
135+#include <nih-dbus/dbus_proxy.h>
136+#include <nih-dbus/errors.h>
137+#include <nih-dbus/dbus_connection.h>
138+
139+#include "dbus/upstart.h"
140+
141+#include "com.ubuntu.Upstart.h"
142+
143 #include "sysv.h"
144
145
146 /* Prototypes for option functions */
147 int env_option (NihOption *option, const char *arg);
148
149+NihDBusProxy * upstart_open (const void *parent)
150+ __attribute__ ((warn_unused_result));
151+
152+int restart_upstart (void)
153+ __attribute__ ((warn_unused_result));
154+
155
156 /**
157 * extra_env:
158@@ -83,6 +98,79 @@
159 return 0;
160 }
161
162+/**
163+ * upstart_open:
164+ * @parent: parent object for new proxy.
165+ *
166+ * Opens a connection to the Upstart init daemon and returns a proxy
167+ * to the manager object. If @dest_name is not NULL, a connection is
168+ * instead opened to the system bus and the proxy linked to the
169+ * well-known name given.
170+ *
171+ * If @parent is not NULL, it should be a pointer to another object
172+ * which will be used as a parent for the returned proxy. When all
173+ * parents of the returned proxy are freed, the returned proxy will
174+ * also be freed.
175+ *
176+ * Returns: newly allocated D-Bus proxy or NULL on raised error.
177+ **/
178+NihDBusProxy *
179+upstart_open (const void *parent)
180+{
181+ DBusError dbus_error;
182+ DBusConnection *connection;
183+ NihDBusProxy * upstart;
184+
185+ dbus_error_init (&dbus_error);
186+
187+ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
188+ if (! connection) {
189+ nih_dbus_error_raise (dbus_error.name, dbus_error.message);
190+ dbus_error_free (&dbus_error);
191+ return NULL;
192+ }
193+
194+ dbus_connection_set_exit_on_disconnect (connection, FALSE);
195+ dbus_error_free (&dbus_error);
196+
197+ upstart = nih_dbus_proxy_new (parent, connection,
198+ DBUS_SERVICE_UPSTART,
199+ DBUS_PATH_UPSTART,
200+ NULL, NULL);
201+ if (! upstart) {
202+ dbus_connection_unref (connection);
203+ return NULL;
204+ }
205+
206+ upstart->auto_start = FALSE;
207+
208+ /* Drop initial reference now the proxy holds one */
209+ dbus_connection_unref (connection);
210+
211+ return upstart;
212+}
213+
214+/**
215+ * restart_upstart:
216+ *
217+ * Request Upstart restart itself.
218+ *
219+ * Returns: 0 on SUCCESS, -1 on raised error.
220+ **/
221+int
222+restart_upstart (void)
223+{
224+ nih_local NihDBusProxy *upstart = NULL;
225+
226+ upstart = upstart_open (NULL);
227+ if (! upstart)
228+ return -1;
229+
230+ if (upstart_restart_sync (NULL, upstart) < 0)
231+ return -1;
232+
233+ return 0;
234+}
235
236 #ifndef TEST
237 /**
238@@ -107,7 +195,7 @@
239 {
240 char **args;
241 int runlevel;
242- int ret;
243+ int ret = 0;
244
245 nih_main_init (argv[0]);
246
247@@ -174,9 +262,8 @@
248 break;
249 case 'U':
250 case 'u':
251- ret = kill (1, SIGTERM);
252- if (ret < 0)
253- nih_error_raise_system ();
254+ /* If /sbin/init is not Upstart, just exit non-zero */
255+ ret = restart_upstart ();
256 break;
257 default:
258 nih_assert_not_reached ();

Subscribers

People subscribed via source and target branches