Merge lp:~xnox/upstart/systemd-local-bridge into lp:ubuntu/vivid/upstart

Proposed by Dimitri John Ledkov
Status: Merged
Merged at revision: 1605
Proposed branch: lp:~xnox/upstart/systemd-local-bridge
Merge into: lp:ubuntu/vivid/upstart
Diff against target: 1265 lines (+636/-233) (has conflicts)
15 files modified
ChangeLog (+12/-0)
debian/changelog (+21/-1)
debian/control (+2/-2)
debian/rules (+0/-1)
debian/upstart-bin.install (+4/-0)
debian/upstart.install (+0/-4)
extra/Makefile.am (+40/-4)
extra/com.ubuntu.Upstart.xml (+29/-0)
extra/conf-session/upstart-udev-bridge.conf (+22/-0)
extra/conf/upstart-event-bridge.conf (+0/-15)
extra/org.freedesktop.systemd1.xml (+19/-0)
extra/upstart-event-bridge.c (+40/-4)
extra/upstart-local-bridge.c (+322/-181)
extra/upstart-udev-bridge.c (+63/-5)
util/telinit.c (+62/-16)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~xnox/upstart/systemd-local-bridge
Reviewer Review Type Date Requested Status
James Hunt Pending
Ubuntu branches Pending
Review via email: mp+246772@code.launchpad.net
To post a comment you must log in.
1599. By Dimitri John Ledkov

* debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct
  into session init, by-passing system upstart & session
* extra/upstart-local-bridge: implement systemd pid1 logic.
* extra/upstart-event-bridge: make it re-emit upstart-local-bridge
  events direct.
* util/telinit: Revert to synchronous behaviour coupled with unavoidable
  poll to ensure telinit only returns once a re-exec has completed (LP:
  #901038).

1600. By Dimitri John Ledkov

Add control xml bindings.

1601. By Dimitri John Ledkov

Drop event-bridge

1602. By Dimitri John Ledkov

move udev & local bridges to upstart-bin package.

1603. By Dimitri John Ledkov

Drop local option, use systemd_booted detection instead.

1604. By Dimitri John Ledkov

releasing package upstart version 1.13.2-0ubuntu6

1605. By Dimitri John Ledkov

Correct upstart-udev-bridge session job start/stop on conditions.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

This merge proposal is in SILO 01

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2014-09-04 11:29:54 +0000
+++ ChangeLog 2015-01-17 15:39:44 +0000
@@ -1,3 +1,15 @@
12014-09-08 James Hunt <james.hunt@ubuntu.com>
2
3 * util/telinit.c: Remove UPSTART_TELINIT_U_NO_WAIT check as it
4 shouldn't realistically be needed.
5
62014-08-21 James Hunt <james.hunt@ubuntu.com>
7
8 * util/telinit.c: restart_upstart():
9 - Revert to synchronous behaviour coupled with unavoidable
10 poll to ensure telinit only returns once a re-exec has
11 completed (LP: #901038).
12
12014-09-04 James Hunt <james.hunt@ubuntu.com>132014-09-04 James Hunt <james.hunt@ubuntu.com>
214
3 * NEWS: Release 1.13.215 * NEWS: Release 1.13.2
416
=== modified file 'debian/changelog'
--- debian/changelog 2015-01-16 19:15:46 +0000
+++ debian/changelog 2015-01-17 15:39:44 +0000
@@ -1,13 +1,33 @@
1<<<<<<< TREE
1upstart (1.13.2-0ubuntu6) UNRELEASED; urgency=medium2upstart (1.13.2-0ubuntu6) UNRELEASED; urgency=medium
23
3 * debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct4 * debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct
4 into session init, by-passing system upstart & session5 into session init, by-passing system upstart & session
6=======
7upstart (1.13.2-0ubuntu7) UNRELEASED; urgency=medium
8
9 * Correct upstart-udev-bridge session job start/stop on conditions.
10
11 -- Dimitri John Ledkov <dimitri.j.ledkov@linux.intel.com> Sat, 17 Jan 2015 15:38:35 +0000
12
13upstart (1.13.2-0ubuntu6) vivid; urgency=medium
14
15 * debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct
16 into session init, by-passing system upstart & session
17>>>>>>> MERGE-SOURCE
5 event-bridge. This way session logs will be rotated, even upstart is18 event-bridge. This way session logs will be rotated, even upstart is
6 not system init.19 not system init.
7 * debian/control: make upstart-monitor & upstart-dconf-bridge be20 * debian/control: make upstart-monitor & upstart-dconf-bridge be
8 installable with just session init, upstart-bin.21 installable with just session init, upstart-bin.
22 * extra/upstart-local-bridge: implement systemd pid1 logic.
23 * extra/upstart-event-bridge: make it re-emit upstart-local-bridge
24 events direct.
25 * util/telinit: Revert to synchronous behaviour coupled with unavoidable
26 poll to ensure telinit only returns once a re-exec has completed (LP:
27 #901038).
28 * move udev & local bridges to upstart-bin package.
929
10 -- Dimitri John Ledkov <dimitri.j.ledkov@linux.intel.com> Sun, 11 Jan 2015 01:15:34 +000030 -- Dimitri John Ledkov <dimitri.j.ledkov@linux.intel.com> Sat, 17 Jan 2015 01:59:42 +0000
1131
12upstart (1.13.2-0ubuntu5) vivid; urgency=medium32upstart (1.13.2-0ubuntu5) vivid; urgency=medium
1333
1434
=== modified file 'debian/control'
--- debian/control 2015-01-11 01:19:24 +0000
+++ debian/control 2015-01-17 15:39:44 +0000
@@ -33,8 +33,8 @@
33Architecture: any33Architecture: any
34Depends: ${shlibs:Depends}, ${misc:Depends}, sysvinit-utils, initscripts, libjson0 (>= 0.10-1.1ubuntu1), debianutils (>= 4)34Depends: ${shlibs:Depends}, ${misc:Depends}, sysvinit-utils, initscripts, libjson0 (>= 0.10-1.1ubuntu1), debianutils (>= 4)
35Suggests: python3, graphviz, bash-completion, upstart-monitor35Suggests: python3, graphviz, bash-completion, upstart-monitor
36Replaces: upstart (<< 1.13.2-0ubuntu3)36Replaces: upstart (<< 1.13.2-0ubuntu6)
37Breaks: upstart (<< 1.13.2-0ubuntu3)37Breaks: upstart (<< 1.13.2-0ubuntu6)
38Multi-Arch: foreign38Multi-Arch: foreign
39Description: event-based init daemon - essential binaries39Description: event-based init daemon - essential binaries
40 upstart is a replacement for the /sbin/init daemon which handles40 upstart is a replacement for the /sbin/init daemon which handles
4141
=== modified file 'debian/rules'
--- debian/rules 2014-11-19 11:52:17 +0000
+++ debian/rules 2015-01-17 15:39:44 +0000
@@ -52,7 +52,6 @@
52 install -m 644 debian/upstart-bin.apport \52 install -m 644 debian/upstart-bin.apport \
53 debian/upstart-bin/usr/share/apport/package-hooks/source_upstart.py53 debian/upstart-bin/usr/share/apport/package-hooks/source_upstart.py
54 rm debian/upstart-bin/usr/share/upstart/sessions/upstart-dconf-bridge.conf54 rm debian/upstart-bin/usr/share/upstart/sessions/upstart-dconf-bridge.conf
55 rm debian/upstart/etc/init/upstart-event-bridge.conf
56 rm debian/upstart/etc/init/upstart-dbus-bridge.conf55 rm debian/upstart/etc/init/upstart-dbus-bridge.conf
5756
58override_dh_installcron:57override_dh_installcron:
5958
=== modified file 'debian/upstart-bin.install'
--- debian/upstart-bin.install 2014-11-19 11:52:17 +0000
+++ debian/upstart-bin.install 2015-01-17 15:39:44 +0000
@@ -11,6 +11,8 @@
11sbin/upstart-dbus-bridge11sbin/upstart-dbus-bridge
12sbin/upstart-event-bridge12sbin/upstart-event-bridge
13sbin/upstart-file-bridge13sbin/upstart-file-bridge
14sbin/upstart-local-bridge
15sbin/upstart-udev-bridge
14debian/running-in-container bin/16debian/running-in-container bin/
15debian/apparmor-profile-load lib/init/17debian/apparmor-profile-load lib/init/
16usr/share/upstart/sessions/*18usr/share/upstart/sessions/*
@@ -31,6 +33,8 @@
31usr/share/man/man8/upstart.833usr/share/man/man8/upstart.8
32usr/share/man/man8/upstart-file-bridge.834usr/share/man/man8/upstart-file-bridge.8
33usr/share/man/man8/upstart-dbus-bridge.835usr/share/man/man8/upstart-dbus-bridge.8
36usr/share/man/man8/upstart-local-bridge.8
37usr/share/man/man8/upstart-udev-bridge.8
34usr/share/man/man8/initctl2dot.838usr/share/man/man8/initctl2dot.8
35usr/share/man/man8/initctl.839usr/share/man/man8/initctl.8
36usr/share/man/man5/upstart.540usr/share/man/man5/upstart.5
3741
=== modified file 'debian/upstart.install'
--- debian/upstart.install 2014-11-19 11:52:17 +0000
+++ debian/upstart.install 2015-01-17 15:39:44 +0000
@@ -6,9 +6,7 @@
6sbin/reboot6sbin/reboot
7sbin/runlevel7sbin/runlevel
8sbin/shutdown8sbin/shutdown
9sbin/upstart-local-bridge
10sbin/upstart-socket-bridge9sbin/upstart-socket-bridge
11sbin/upstart-udev-bridge
12debian/upstart-job lib/init/10debian/upstart-job lib/init/
13debian/migrate-inittab.pl usr/lib/upstart/11debian/migrate-inittab.pl usr/lib/upstart/
14usr/share/man/man7/control-alt-delete.712usr/share/man/man7/control-alt-delete.7
@@ -17,8 +15,6 @@
17usr/share/man/man7/socket-event.715usr/share/man/man7/socket-event.7
18usr/share/man/man7/power-status-changed.716usr/share/man/man7/power-status-changed.7
19usr/share/man/man8/shutdown.817usr/share/man/man8/shutdown.8
20usr/share/man/man8/upstart-local-bridge.8
21usr/share/man/man8/upstart-udev-bridge.8
22usr/share/man/man8/runlevel.818usr/share/man/man8/runlevel.8
23usr/share/man/man8/reboot.819usr/share/man/man8/reboot.8
24usr/share/man/man8/upstart-socket-bridge.820usr/share/man/man8/upstart-socket-bridge.8
2521
=== modified file 'extra/Makefile.am'
--- extra/Makefile.am 2013-11-14 17:41:01 +0000
+++ extra/Makefile.am 2015-01-17 15:39:44 +0000
@@ -23,6 +23,7 @@
23 conf-session/upstart-event-bridge.conf \23 conf-session/upstart-event-bridge.conf \
24 conf-session/upstart-file-bridge.conf \24 conf-session/upstart-file-bridge.conf \
25 conf-session/re-exec.conf \25 conf-session/re-exec.conf \
26 conf-session/upstart-udev-bridge.conf \
26 conf-session/upstart-dbus-session-bridge.conf \27 conf-session/upstart-dbus-session-bridge.conf \
27 conf-session/upstart-dbus-system-bridge.conf28 conf-session/upstart-dbus-system-bridge.conf
2829
@@ -33,7 +34,6 @@
3334
34dist_init_DATA = \35dist_init_DATA = \
35 conf/upstart-socket-bridge.conf \36 conf/upstart-socket-bridge.conf \
36 conf/upstart-event-bridge.conf \
37 conf/upstart-file-bridge.conf \37 conf/upstart-file-bridge.conf \
38 conf/upstart-dbus-bridge.conf38 conf/upstart-dbus-bridge.conf
3939
@@ -106,8 +106,9 @@
106upstart_local_bridge_SOURCES = \106upstart_local_bridge_SOURCES = \
107 upstart-local-bridge.c107 upstart-local-bridge.c
108nodist_upstart_local_bridge_SOURCES = \108nodist_upstart_local_bridge_SOURCES = \
109 $(org_freedesktop_systemd1_OUTPUTS) \
109 $(com_ubuntu_Upstart_OUTPUTS) \110 $(com_ubuntu_Upstart_OUTPUTS) \
110 $(com_ubuntu_Upstart_Job_OUTPUTS)111 $(control_com_ubuntu_Upstart_OUTPUTS)
111upstart_local_bridge_LDADD = \112upstart_local_bridge_LDADD = \
112 $(LTLIBINTL) \113 $(LTLIBINTL) \
113 $(NIH_LIBS) \114 $(NIH_LIBS) \
@@ -224,15 +225,50 @@
224 --output=$@ $<225 --output=$@ $<
225226
226227
228org_freedesktop_systemd1_OUTPUTS = \
229 org.freedesktop.systemd1.c \
230 org.freedesktop.systemd1.h
231
232org_freedesktop_systemd1_XML = \
233 org.freedesktop.systemd1.xml
234
235$(org_freedesktop_systemd1_OUTPUTS): $(org_freedesktop_systemd1_XML)
236 $(AM_V_GEN)$(NIH_DBUS_TOOL) \
237 --package=$(PACKAGE) \
238 --mode=proxy --prefix=systemd \
239 --default-interface=org.freedesktop.systemd1.Manager \
240 --output=$@ $<
241
242# Server for upstart-local-bridge
243control_com_ubuntu_Upstart_OUTPUTS = \
244 control_com.ubuntu.Upstart.c \
245 control_com.ubuntu.Upstart.h
246
247control_com_ubuntu_Upstart_XML = \
248 com.ubuntu.Upstart.xml
249
250$(control_com_ubuntu_Upstart_OUTPUTS): $(control_com_ubuntu_Upstart_XML)
251 $(AM_V_GEN)$(NIH_DBUS_TOOL) \
252 --package=$(PACKAGE) \
253 --mode=object --prefix=control \
254 --default-interface=com.ubuntu.Upstart0_6 \
255 --output=$@ $<
256
257
258
227# These have to be built sources because we can't compile object files259# These have to be built sources because we can't compile object files
228# without the header file existing first260# without the header file existing first
229BUILT_SOURCES = \261BUILT_SOURCES = \
230 $(com_ubuntu_Upstart_OUTPUTS) \262 $(com_ubuntu_Upstart_OUTPUTS) \
231 $(com_ubuntu_Upstart_Job_OUTPUTS)263 $(control_com_ubuntu_Upstart_OUTPUTS) \
264 $(com_ubuntu_Upstart_Job_OUTPUTS) \
265 $(org_freedesktop_systemd1_OUTPUTS)
232266
233CLEANFILES = \267CLEANFILES = \
234 $(com_ubuntu_Upstart_OUTPUTS) \268 $(com_ubuntu_Upstart_OUTPUTS) \
235 $(com_ubuntu_Upstart_Job_OUTPUTS)269 $(control_com_ubuntu_Upstart_OUTPUTS) \
270 $(com_ubuntu_Upstart_Job_OUTPUTS) \
271 $(org_freedesktop_systemd1_OUTPUTS)
236272
237273
238clean-local:274clean-local:
239275
=== added file 'extra/com.ubuntu.Upstart.xml'
--- extra/com.ubuntu.Upstart.xml 1970-01-01 00:00:00 +0000
+++ extra/com.ubuntu.Upstart.xml 2015-01-17 15:39:44 +0000
@@ -0,0 +1,29 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2<!-- upstart
3
4 com.ubuntu.Upstart.xml - interface definition for manager object
5
6 Copyright © 2009 Canonical Ltd.
7 Author: Scott James Remnant <scott@netsplit.com>.
8
9 This file is free software; Canonical Ltd gives unlimited permission
10 to copy and/or distribute it, with or without modifications, as long
11 as this notice is preserved.
12
13 Communication and interaction with Upstart through this interface is
14 permitted without restriction.
15 -->
16
17<!DOCTYPE node PUBLIC
18 "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
19 "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
20
21<node name="/com/ubuntu/Upstart">
22 <interface name="com.ubuntu.Upstart0_6">
23 <!-- Signal for events being emitted -->
24 <signal name="EventEmitted">
25 <arg name="name" type="s" />
26 <arg name="env" type="as" />
27 </signal>
28 </interface>
29</node>
030
=== added file 'extra/conf-session/upstart-udev-bridge.conf'
--- extra/conf-session/upstart-udev-bridge.conf 1970-01-01 00:00:00 +0000
+++ extra/conf-session/upstart-udev-bridge.conf 2015-01-17 15:39:44 +0000
@@ -0,0 +1,22 @@
1# upstart-udev-bridge - Bridge udev events into session upstart
2#
3# This helper daemon receives udev events from the netlink socket and
4# emits equivalent Upstart events.
5
6description "Bridge udev events into upstart"
7
8# From upstart-udev-bridge itself
9emits *-device-added
10emits *-device-removed
11emits *-device-changed
12# From http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/libudev-udev-device.html
13emits *-device-online
14emits *-device-offline
15
16start on startup
17stop on desktop-end
18
19expect daemon
20respawn
21
22exec upstart-udev-bridge --daemon --user
023
=== removed file 'extra/conf/upstart-event-bridge.conf'
--- extra/conf/upstart-event-bridge.conf 2013-01-22 20:08:29 +0000
+++ extra/conf/upstart-event-bridge.conf 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1# upstart-event-bridge - Bridge system upstarts events into session upstart
2#
3# This helper daemon receives system upstart events from the DBus system bus
4# and emits equivalent events (with a :sys:) prefix to the session bus
5
6description "Bridge Upstart system events into session Upstart"
7
8emits :sys:*
9
10start on started dbus
11stop on stopped dbus
12
13respawn
14
15exec upstart-event-bridge
160
=== added file 'extra/org.freedesktop.systemd1.xml'
--- extra/org.freedesktop.systemd1.xml 1970-01-01 00:00:00 +0000
+++ extra/org.freedesktop.systemd1.xml 2015-01-17 15:39:44 +0000
@@ -0,0 +1,19 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2<!--
3 org.freedesktop.systemd1- interface definition for systemd manager object
4
5 Public Domain
6
7 Generated file using gdbus introspect call against systemd1 instance
8 -->
9<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
10"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
11<node>
12 <interface name="org.freedesktop.systemd1.Manager">
13 <method name="StartUnit">
14 <arg name="name" type="s" direction="in"/>
15 <arg name="mode" type="s" direction="in"/>
16 <arg name="job" type="o" direction="out"/>
17 </method>
18 </interface>
19</node>
020
=== modified file 'extra/upstart-event-bridge.c'
--- extra/upstart-event-bridge.c 2013-07-05 08:44:00 +0000
+++ extra/upstart-event-bridge.c 2015-01-17 15:39:44 +0000
@@ -26,6 +26,9 @@
26#include <stdlib.h>26#include <stdlib.h>
27#include <string.h>27#include <string.h>
28#include <ctype.h>28#include <ctype.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <unistd.h>
2932
30#include <nih/macros.h>33#include <nih/macros.h>
31#include <nih/alloc.h>34#include <nih/alloc.h>
@@ -42,8 +45,10 @@
42#include "dbus/upstart.h"45#include "dbus/upstart.h"
43#include "com.ubuntu.Upstart.h"46#include "com.ubuntu.Upstart.h"
4447
48#define DBUS_ADDRESS_LOCAL "unix:abstract=/com/ubuntu/upstart/local/bridge"
4549
46/* Prototypes for static functions */50/* Prototypes for static functions */
51static int systemd_booted (void);
47static void upstart_disconnected (DBusConnection *connection);52static void upstart_disconnected (DBusConnection *connection);
48static void upstart_forward_event (void *data, NihDBusMessage *message,53static void upstart_forward_event (void *data, NihDBusMessage *message,
49 const char *path);54 const char *path);
@@ -60,6 +65,14 @@
60static int daemonise = FALSE;65static int daemonise = FALSE;
6166
62/**67/**
68 * local:
69 *
70 * Set to TRUE if we should connect to upstart-local-bridge instead of
71 * the system init.
72 **/
73static int local = FALSE;
74
75/**
63 * system_upstart:76 * system_upstart:
64 *77 *
65 * Proxy to system Upstart daemon.78 * Proxy to system Upstart daemon.
@@ -119,9 +132,14 @@
119 exit (1);132 exit (1);
120 }133 }
121134
135 local = systemd_booted ();
136
122 /* Initialise the connection to system Upstart */137 /* Initialise the connection to system Upstart */
123 system_connection = NIH_SHOULD (nih_dbus_bus (DBUS_BUS_SYSTEM, upstart_disconnected));138 if (local) {
124139 system_connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_LOCAL, upstart_disconnected));
140 } else {
141 system_connection = NIH_SHOULD (nih_dbus_bus (DBUS_BUS_SYSTEM, upstart_disconnected));
142 }
125 if (! system_connection) {143 if (! system_connection) {
126 NihError *err;144 NihError *err;
127145
@@ -134,7 +152,7 @@
134 }152 }
135153
136 system_upstart = NIH_SHOULD (nih_dbus_proxy_new (NULL, system_connection,154 system_upstart = NIH_SHOULD (nih_dbus_proxy_new (NULL, system_connection,
137 DBUS_SERVICE_UPSTART, DBUS_PATH_UPSTART,155 NULL, DBUS_PATH_UPSTART,
138 NULL, NULL));156 NULL, NULL));
139 if (! system_upstart) {157 if (! system_upstart) {
140 NihError *err;158 NihError *err;
@@ -259,6 +277,20 @@
259 return ret;277 return ret;
260}278}
261279
280static int
281systemd_booted (void)
282{
283 struct stat st;
284
285 if (lstat ("/run/systemd/system/", &st) == 0) {
286 if (S_ISDIR(st.st_mode)) {
287 return TRUE;
288 }
289 }
290
291 return FALSE;
292}
293
262static void294static void
263upstart_disconnected (DBusConnection *connection)295upstart_disconnected (DBusConnection *connection)
264{296{
@@ -293,7 +325,11 @@
293 nih_assert (event_name != NULL);325 nih_assert (event_name != NULL);
294326
295 /* Build the new event name */327 /* Build the new event name */
296 NIH_MUST (nih_strcat_sprintf (&new_event_name, NULL, ":sys:%s", event_name));328 if (local) {
329 new_event_name = NIH_MUST (nih_strdup (NULL, event_name));
330 } else {
331 new_event_name = NIH_MUST (nih_sprintf (NULL, ":sys:%s", event_name));
332 }
297333
298 /* Re-transmit the event */334 /* Re-transmit the event */
299 pending_call = upstart_emit_event (user_upstart,335 pending_call = upstart_emit_event (user_upstart,
300336
=== modified file 'extra/upstart-local-bridge.c'
--- extra/upstart-local-bridge.c 2013-11-14 17:41:01 +0000
+++ extra/upstart-local-bridge.c 2015-01-17 15:39:44 +0000
@@ -22,10 +22,14 @@
22#endif /* HAVE_CONFIG_H */22#endif /* HAVE_CONFIG_H */
2323
24#include <sys/types.h>24#include <sys/types.h>
25#include <sys/stat.h>
25#include <sys/socket.h>26#include <sys/socket.h>
26#include <sys/un.h>27#include <sys/un.h>
28#include <sys/types.h>
29#include <sys/wait.h>
2730
28#include <errno.h>31#include <errno.h>
32#include <stdio.h>
29#include <stdlib.h>33#include <stdlib.h>
30#include <string.h>34#include <string.h>
31#include <syslog.h>35#include <syslog.h>
@@ -45,24 +49,17 @@
4549
46#include <nih-dbus/dbus_connection.h>50#include <nih-dbus/dbus_connection.h>
47#include <nih-dbus/dbus_proxy.h>51#include <nih-dbus/dbus_proxy.h>
52#include <nih-dbus/dbus_object.h>
4853
49#include "dbus/upstart.h"54#include "dbus/upstart.h"
50#include "com.ubuntu.Upstart.h"55#include "com.ubuntu.Upstart.h"
51#include "com.ubuntu.Upstart.Job.h"56#include "org.freedesktop.systemd1.h"
57#include "control_com.ubuntu.Upstart.h"
5258
53/**59#define DBUS_ADDRESS_SYSTEMD "unix:path=/run/systemd/private"
54 * Job:60#define DBUS_PATH_SYSTEMD "/org/freedesktop/systemd1"
55 *61#define DBUS_SERVICE_SYSTEMD "org.freedesktop.systemd1"
56 * @entry: list header,62#define DBUS_ADDRESS_LOCAL "unix:abstract=/com/ubuntu/upstart/local/bridge"
57 * @path: D-Bus path for a job.
58 *
59 * Representation of an Upstart Job.
60 *
61 **/
62typedef struct job {
63 NihList entry;
64 char *path;
65} Job;
6663
67/**64/**
68 * Socket:65 * Socket:
@@ -100,12 +97,14 @@
100 struct ucred ucred;97 struct ucred ucred;
101} ClientConnection;98} ClientConnection;
10299
103static void upstart_job_added (void *data, NihDBusMessage *message,
104 const char *job);
105static void upstart_job_removed (void *data, NihDBusMessage *message,
106 const char *job);
107static void upstart_connect (void);100static void upstart_connect (void);
108static void upstart_disconnected (DBusConnection *connection);101static void systemd_connect (void);
102static int systemd_booted (void);
103static int control_server_open (void);
104static int control_server_connect (DBusServer *server,
105 DBusConnection *conn);
106static void control_disconnected (DBusConnection *conn);
107static void init_disconnected (DBusConnection *connection);
109108
110static Socket *create_socket (void *parent);109static Socket *create_socket (void *parent);
111110
@@ -121,6 +120,8 @@
121120
122static void emit_event (ClientConnection *client, const char *pair, size_t len);121static void emit_event (ClientConnection *client, const char *pair, size_t len);
123122
123static void process_event (ClientConnection *client, const char *pair, size_t len);
124
124static void signal_handler (void *data, NihSignal *signal);125static void signal_handler (void *data, NihSignal *signal);
125126
126static void cleanup (void);127static void cleanup (void);
@@ -134,13 +135,6 @@
134static int daemonise = FALSE;135static int daemonise = FALSE;
135136
136/**137/**
137 * jobs:
138 *
139 * Jobs that we're monitoring.
140 **/
141static NihHash *jobs = NULL;
142
143/**
144 * upstart:138 * upstart:
145 *139 *
146 * Proxy to Upstart daemon.140 * Proxy to Upstart daemon.
@@ -148,9 +142,32 @@
148static NihDBusProxy *upstart = NULL;142static NihDBusProxy *upstart = NULL;
149143
150/**144/**
145 * systemd:
146 *
147 * Proxy to systemd daemon.
148 **/
149static NihDBusProxy *systemd = NULL;
150
151/**
152 * control_server
153 *
154 * D-Bus server listening for new direct connections.
155 **/
156DBusServer *control_server = NULL;
157
158/**
159 * control_conns:
160 *
161 * Open control connections, including the connection to a D-Bus
162 * bus and any private client connections.
163 **/
164NihList *control_conns = NULL;
165
166/**
151 * event_name:167 * event_name:
152 *168 *
153 * Name of event this bridge emits.169 * upstart: Name of event this bridge emits.
170 * systmed: Name of target this generator creates.
154 **/171 **/
155static char *event_name = NULL;172static char *event_name = NULL;
156173
@@ -202,7 +219,7 @@
202 { 0, "daemon", N_("Detach and run in the background"),219 { 0, "daemon", N_("Detach and run in the background"),
203 NULL, NULL, &daemonise, NULL },220 NULL, NULL, &daemonise, NULL },
204221
205 { 0, "event", N_("specify name of event to emit on receipt of name=value pair"),222 { 0, "event", N_("specify name of event to emit / target to generate on receipt of name=value pair"),
206 NULL, "EVENT", &event_name, NULL },223 NULL, "EVENT", &event_name, NULL },
207224
208 { 0, "any-user", N_("allow any user to connect"),225 { 0, "any-user", N_("allow any user to connect"),
@@ -258,7 +275,7 @@
258275
259 nih_main_init (argv[0]);276 nih_main_init (argv[0]);
260277
261 nih_option_set_synopsis (_("Local socket Upstart Bridge"));278 nih_option_set_synopsis (_("Local socket Upstart Bridge & systemd generator"));
262 nih_option_set_help (279 nih_option_set_help (
263 _("By default, this bridge does not detach from the "280 _("By default, this bridge does not detach from the "
264 "console and remains in the foreground. Use the --daemon "281 "console and remains in the foreground. Use the --daemon "
@@ -273,9 +290,6 @@
273 exit (1);290 exit (1);
274 }291 }
275292
276 /* Allocate jobs hash table */
277 jobs = NIH_MUST (nih_hash_string_new (NULL, 0));
278
279 sock = create_socket (NULL);293 sock = create_socket (NULL);
280 if (! sock) {294 if (! sock) {
281 nih_fatal ("%s %s",295 nih_fatal ("%s %s",
@@ -286,7 +300,26 @@
286300
287 nih_debug ("Connected to socket '%s' on fd %d", socket_name, sock->sock);301 nih_debug ("Connected to socket '%s' on fd %d", socket_name, sock->sock);
288302
289 upstart_connect ();303 if (systemd_booted() == TRUE) {
304 systemd_connect ();
305 } else {
306 upstart_connect ();
307 }
308
309 control_conns = NIH_MUST (nih_list_new (NULL));
310
311 while ((ret = control_server_open ()) < 0) {
312 NihError *err;
313
314 err = nih_error_get ();
315 if (err->number != ENOMEM) {
316 nih_warn ("%s: %s", _("Unable to listen for private"
317 "connections"), err->message);
318 nih_free (err);
319 break;
320 }
321 nih_free (err);
322 }
290323
291 /* Become daemon */324 /* Become daemon */
292 if (daemonise) {325 if (daemonise) {
@@ -326,103 +359,14 @@
326 return ret;359 return ret;
327}360}
328361
329static void
330upstart_job_added (void *data,
331 NihDBusMessage *message,
332 const char *job_class_path)
333{
334 nih_local NihDBusProxy *job_class = NULL;
335 nih_local char ***start_on = NULL;
336 nih_local char ***stop_on = NULL;
337 Job *job;
338
339 nih_assert (job_class_path != NULL);
340
341 /* Obtain a proxy to the job */
342 job_class = nih_dbus_proxy_new (NULL, upstart->connection,
343 upstart->name, job_class_path,
344 NULL, NULL);
345 if (! job_class) {
346 NihError *err;
347
348 err = nih_error_get ();
349 nih_error ("Could not create proxy for job %s: %s",
350 job_class_path, err->message);
351 nih_free (err);
352
353 return;
354 }
355
356 job_class->auto_start = FALSE;
357
358 /* Obtain the start_on and stop_on properties of the job */
359 if (job_class_get_start_on_sync (NULL, job_class, &start_on) < 0) {
360 NihError *err;
361
362 err = nih_error_get ();
363 nih_error ("Could not obtain job start condition %s: %s",
364 job_class_path, err->message);
365 nih_free (err);
366
367 return;
368 }
369
370 if (job_class_get_stop_on_sync (NULL, job_class, &stop_on) < 0) {
371 NihError *err;
372
373 err = nih_error_get ();
374 nih_error ("Could not obtain job stop condition %s: %s",
375 job_class_path, err->message);
376 nih_free (err);
377
378 return;
379 }
380
381 /* Free any existing record for the job (should never happen,
382 * but worth being safe).
383 */
384 job = (Job *)nih_hash_lookup (jobs, job_class_path);
385 if (job)
386 nih_free (job);
387
388 /* Create new record for the job */
389 job = NIH_MUST (nih_new (NULL, Job));
390 job->path = NIH_MUST (nih_strdup (job, job_class_path));
391
392 nih_list_init (&job->entry);
393
394 nih_debug ("Job got added %s", job_class_path);
395
396 nih_alloc_set_destructor (job, nih_list_destroy);
397
398 /* Add all jobs */
399 nih_hash_add (jobs, &job->entry);
400}
401
402static void
403upstart_job_removed (void *data,
404 NihDBusMessage *message,
405 const char *job_path)
406{
407 Job *job;
408
409 nih_assert (job_path != NULL);
410
411 job = (Job *)nih_hash_lookup (jobs, job_path);
412 if (job) {
413 nih_debug ("Job went away %s", job_path);
414 nih_free (job);
415 }
416}
417362
418static void363static void
419upstart_connect (void)364upstart_connect (void)
420{365{
421 DBusConnection *connection;366 DBusConnection *connection;
422 char **job_class_paths;
423367
424 /* Initialise the connection to Upstart */368 /* Initialise the connection to Upstart */
425 connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_UPSTART, upstart_disconnected));369 connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_UPSTART, init_disconnected));
426 if (! connection) {370 if (! connection) {
427 NihError *err;371 NihError *err;
428372
@@ -449,59 +393,169 @@
449 }393 }
450394
451 nih_debug ("Connected to Upstart");395 nih_debug ("Connected to Upstart");
452396}
453 /* Connect signals to be notified when jobs come and go */397
454 if (! nih_dbus_proxy_connect (upstart, &upstart_com_ubuntu_Upstart0_6, "JobAdded",398static void
455 (NihDBusSignalHandler)upstart_job_added, NULL)) {399systemd_connect (void)
456 NihError *err;400{
457401 DBusConnection *connection;
458 err = nih_error_get ();402
459 nih_fatal ("%s: %s", _("Could not create JobAdded signal connection"),403 /* Initialise the connection to systemd */
460 err->message);404 /* /run/systemd/private is supposedly "private" end-point
461 nih_free (err);405 * which systemctl & libsystemd use */
462406 connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_SYSTEMD, init_disconnected));
463 exit (1);407 if (! connection) {
464 }408 NihError *err;
465409
466 if (! nih_dbus_proxy_connect (upstart, &upstart_com_ubuntu_Upstart0_6, "JobRemoved",410 err = nih_error_get ();
467 (NihDBusSignalHandler)upstart_job_removed, NULL)) {411 nih_fatal ("%s: %s", _("Could not connect to systemd"),
468 NihError *err;412 err->message);
469413 nih_free (err);
470 err = nih_error_get ();414
471 nih_fatal ("%s: %s", _("Could not create JobRemoved signal connection"),415 exit (1);
472 err->message);416 }
473 nih_free (err);417
474418 systemd = NIH_SHOULD (nih_dbus_proxy_new (NULL, connection,
475 exit (1);419 NULL, DBUS_PATH_SYSTEMD,
476 }420 NULL, NULL));
477421 if (! systemd) {
478 /* Request a list of all current jobs */422 NihError *err;
479 if (upstart_get_all_jobs_sync (NULL, upstart, &job_class_paths) < 0) {423
480 NihError *err;424 err = nih_error_get ();
481425 nih_fatal ("%s: %s", _("Could not create systemd proxy"),
482 err = nih_error_get ();426 err->message);
483 nih_fatal ("%s: %s", _("Could not obtain job list"),427 nih_free (err);
484 err->message);428
485 nih_free (err);429 exit (1);
486430 }
487 exit (1);431
488 }432 FILE *fp = NULL;
489433 nih_local char *template_name = NULL;
490 for (char **job_class_path = job_class_paths;434
491 job_class_path && *job_class_path; job_class_path++)435 template_name = NIH_MUST (nih_sprintf (NULL, "/run/systemd/system/%s@.target", event_name));
492 upstart_job_added (NULL, NULL, *job_class_path);436
493437 fp = NIH_SHOULD (fopen(template_name, "we"));
494 nih_free (job_class_paths);438 if (!fp) {
495}439 nih_fatal ("%s %s", _("Failed to create target template"),
496440 strerror (errno));
497static void441 exit (1);
498upstart_disconnected (DBusConnection *connection)442 }
499{443 fprintf (fp,
500 nih_fatal (_("Disconnected from Upstart"));444 "# Automatically generated by %s\n\n"
445 "[Unit]\n"
446 "Description=Local bridge key value pairs\n"
447 "Documentation=man:%s\n",
448 program_name, program_name);
449 fflush (fp);
450 if (ferror (fp)) {
451 nih_fatal ("%s %s", _("Failed to write target template"),
452 strerror (errno));
453 exit (1);
454 }
455 fclose (fp);
456
457 nih_debug ("Connected to systemd");
458}
459
460static int
461systemd_booted (void)
462{
463 struct stat st;
464
465 if (lstat ("/run/systemd/system/", &st) == 0) {
466 if (S_ISDIR(st.st_mode)) {
467 return TRUE;
468 }
469 }
470
471 return FALSE;
472}
473
474static void
475init_disconnected (DBusConnection *connection)
476{
477 nih_fatal (_("Disconnected from init"));
501 nih_main_loop_exit (1);478 nih_main_loop_exit (1);
502}479}
503480
504/**481/**
482 * control_server_open:
483 *
484 * Open a listening D-Bus server and store it in the control_server global.
485 * New connections are permitted from the root user, and handled
486 * automatically in the main loop.
487 *
488 * Returns: zero on success, negative value on raised error.
489 **/
490
491int
492control_server_open (void)
493{
494 nih_assert (control_server == NULL);
495
496 control_server = nih_dbus_server (DBUS_ADDRESS_LOCAL,
497 control_server_connect,
498 control_disconnected);
499 if (! control_server)
500 return -1;
501
502 nih_debug("D-Bus server started at address: %s", DBUS_ADDRESS_LOCAL);
503
504 return 0;
505}
506
507/**
508 * control_server_connect:
509 *
510 * Called when a new client connects to our server and is used to register
511 * objects on the new connection.
512 *
513 * Returns: always TRUE.
514 **/
515static int
516control_server_connect (DBusServer *server,
517 DBusConnection *conn)
518{
519 nih_assert (server != NULL);
520 nih_assert (server == control_server);
521 nih_assert (conn != NULL);
522 NihListEntry *entry = NULL;
523
524 /* Register objects on the connection. */
525 NIH_MUST (nih_dbus_object_new (NULL, conn, DBUS_PATH_UPSTART,
526 control_interfaces, NULL));
527
528
529 entry = NIH_MUST (nih_list_entry_new (NULL));
530 entry->data = conn;
531 nih_list_add (control_conns, &entry->entry);
532 nih_debug("Connection from private client");
533
534 return TRUE;
535}
536
537/**
538 * control_disconnected:
539 *
540 * This function is called when the connection to the D-Bus system bus,
541 * or a client connection to our D-Bus server, is dropped and our reference
542 * is about to be list. We clear the connection from our current list
543 * and drop the control_bus global if relevant.
544 **/
545static void
546control_disconnected (DBusConnection *conn)
547{
548 nih_assert (conn != NULL);
549 /* Remove from the connections list */
550 NIH_LIST_FOREACH_SAFE (control_conns, iter) {
551 NihListEntry *entry = (NihListEntry *)iter;
552
553 if (entry->data == conn)
554 nih_free (entry);
555 }
556}
557
558/**
505 * socket_watcher:559 * socket_watcher:
506 *560 *
507 * @sock: Socket,561 * @sock: Socket,
@@ -645,7 +699,7 @@
645 if (used_len < min_len)699 if (used_len < min_len)
646 continue;700 continue;
647701
648 emit_event (client, pair, used_len);702 process_event (client, pair, used_len);
649 }703 }
650704
651 /* Consume the entire length */705 /* Consume the entire length */
@@ -724,6 +778,8 @@
724 /* Handle abstract names */778 /* Handle abstract names */
725 if (sock->sun_addr.sun_path[0] == '@')779 if (sock->sun_addr.sun_path[0] == '@')
726 sock->sun_addr.sun_path[0] = '\0';780 sock->sun_addr.sun_path[0] = '\0';
781 else
782 (void) unlink(sock->sun_addr.sun_path);
727783
728 sock->sock = socket (sock->addr.sa_family, SOCK_STREAM, 0);784 sock->sock = socket (sock->addr.sa_family, SOCK_STREAM, 0);
729 if (sock->sock < 0) {785 if (sock->sock < 0) {
@@ -830,17 +886,102 @@
830 /* Add the name=value pair */886 /* Add the name=value pair */
831 NIH_MUST (nih_str_array_addn (&env, NULL, NULL, pair, len));887 NIH_MUST (nih_str_array_addn (&env, NULL, NULL, pair, len));
832888
833 pending_call = upstart_emit_event (upstart,889 if (upstart) {
834 event_name, env, FALSE,890 pending_call = upstart_emit_event (upstart,
835 NULL, emit_event_error, NULL,891 event_name, env, FALSE,
836 NIH_DBUS_TIMEOUT_NEVER);892 NULL, emit_event_error, NULL,
837893 NIH_DBUS_TIMEOUT_NEVER);
838 if (! pending_call) {894
895 if (! pending_call) {
896 NihError *err;
897 err = nih_error_get ();
898 nih_warn ("%s", err->message);
899 nih_free (err);
900 }
901
902 dbus_pending_call_unref (pending_call);
903 }
904
905 NIH_LIST_FOREACH (control_conns, iter) {
906 NihListEntry *entry = (NihListEntry *)iter;
907 DBusConnection *conn = (DBusConnection *)entry->data;
908
909 NIH_ZERO (control_emit_event_emitted (conn, DBUS_PATH_UPSTART,
910 event_name, env));
911 }
912
913}
914
915static void
916systemd_launch_instance (ClientConnection *client,
917 const char *pair,
918 size_t len)
919{
920 nih_local char *safe_pair = NULL;
921 nih_local char **key_value = NULL;
922 nih_local char *group_name = NULL;
923 nih_local char *unit_name = NULL;
924 nih_local char *job_name = NULL;
925
926 nih_assert (client);
927 nih_assert (pair);
928 nih_assert (len);
929
930 /* Why is pair not null-terminated?! */
931 safe_pair = NIH_MUST (nih_strndup (NULL, pair, len));
932
933 /* Get key val from the key=val pair */
934 key_value = NIH_MUST (nih_str_split (NULL, safe_pair, "=", TRUE));
935
936 /* Construct systemd event@key=*.target group name */
937 group_name = NIH_MUST (nih_sprintf (NULL, "%s@%s=*.target",
938 event_name, key_value[0]));
939
940 /* Construct systemd event@key=value.target unit name */
941 unit_name = NIH_MUST (nih_sprintf (NULL, "%s@%s\\x3d%s.target",
942 event_name, key_value[0],
943 key_value[1]));
944
945 /* Stop group */
946 int pid = -1;
947 siginfo_t info;
948 do {
949 pid = fork ();
950 } while (pid < 0);
951
952 if (pid) {
953 info.si_code = 0;
954 info.si_status = 0;
955 if (waitid (P_PID, pid, &info, WEXITED)) {
956 nih_fatal ("%s %s", _("Failed to wait for systemctl"),
957 strerror (errno));
958 }
959 if (info.si_code != CLD_EXITED || info.si_status) {
960 nih_fatal ("Bad systemctl exit code %i and status %i\n", info.si_code, info.si_status);
961 }
962 } else {
963 /* Create and submit stop state transition, do not wait to complete */
964 execlp ("systemctl", "systemctl", "--no-block", "stop", group_name, (char *)NULL);
965 }
966
967 /* Create and submit start state transition, do not wait to complete */
968 if (systemd_start_unit_sync (NULL, systemd, unit_name, "replace", &job_name)) {
839 NihError *err;969 NihError *err;
840 err = nih_error_get ();970 err = nih_error_get ();
841 nih_warn ("%s", err->message);971 nih_warn ("%s", err->message);
842 nih_free (err);972 nih_free (err);
843 }973 }
844974}
845 dbus_pending_call_unref (pending_call);975
976
977static void
978process_event (ClientConnection *client,
979 const char *pair,
980 size_t len)
981{
982 emit_event (client, pair, len);
983
984 if (systemd) {
985 systemd_launch_instance (client, pair, len);
986 }
846}987}
847988
=== modified file 'extra/upstart-udev-bridge.c'
--- extra/upstart-udev-bridge.c 2013-10-18 15:02:34 +0000
+++ extra/upstart-udev-bridge.c 2015-01-17 15:39:44 +0000
@@ -69,6 +69,15 @@
69static NihDBusProxy *upstart = NULL;69static NihDBusProxy *upstart = NULL;
7070
71/**71/**
72 * user:
73 *
74 * If TRUE, run in User Session mode connecting to the Session Init
75 * rather than PID 1. In this mode, certain relative paths are also
76 * expanded.
77 **/
78static int user = FALSE;
79
80/**
72 * no_strip_udev_data:81 * no_strip_udev_data:
73 *82 *
74 * If TRUE, do not modify any udev message data (old behaviour).83 * If TRUE, do not modify any udev message data (old behaviour).
@@ -86,6 +95,8 @@
86 NULL, NULL, &daemonise, NULL },95 NULL, NULL, &daemonise, NULL },
87 { 0, "no-strip", N_("Do not strip non-printable bytes from udev message data"),96 { 0, "no-strip", N_("Do not strip non-printable bytes from udev message data"),
88 NULL, NULL, &no_strip_udev_data, NULL },97 NULL, NULL, &no_strip_udev_data, NULL },
98 { 0, "user", N_("Connect to user session"),
99 NULL, NULL, &user, NULL },
89100
90 NIH_OPTION_LAST101 NIH_OPTION_LAST
91};102};
@@ -97,6 +108,11 @@
97{108{
98 char ** args;109 char ** args;
99 DBusConnection * connection;110 DBusConnection * connection;
111 char * pidfile_path = NULL;
112 char * pidfile = NULL;
113 char *user_session_addr = NULL;
114 nih_local char ** user_session_path = NULL;
115 char * path_element = NULL;
100 struct udev * udev;116 struct udev * udev;
101 struct udev_monitor *udev_monitor;117 struct udev_monitor *udev_monitor;
102 int ret;118 int ret;
@@ -113,8 +129,19 @@
113 if (! args)129 if (! args)
114 exit (1);130 exit (1);
115131
132 if (user) {
133 user_session_addr = getenv ("UPSTART_SESSION");
134 if (! user_session_addr) {
135 nih_fatal (_("UPSTART_SESSION isn't set in environment"));
136 exit (EXIT_FAILURE);
137 }
138 }
139
116 /* Initialise the connection to Upstart */140 /* Initialise the connection to Upstart */
117 connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_UPSTART, upstart_disconnected));141 connection = NIH_SHOULD (nih_dbus_connect (user
142 ? user_session_addr
143 : DBUS_ADDRESS_UPSTART,
144 upstart_disconnected));
118 if (! connection) {145 if (! connection) {
119 NihError *err;146 NihError *err;
120147
@@ -153,6 +180,35 @@
153180
154 /* Become daemon */181 /* Become daemon */
155 if (daemonise) {182 if (daemonise) {
183 /* Deal with the pidfile location when becoming a daemon.
184 * We need to be able to run one bridge per upstart daemon.
185 * Store the PID file in XDG_RUNTIME_DIR or HOME and include the pid of
186 * the Upstart instance (last part of the DBus path) in the filename.
187 */
188
189 if (user) {
190 /* Extract PID from UPSTART_SESSION */
191 user_session_path = nih_str_split (NULL, user_session_addr, "/", TRUE);
192
193 for (int i = 0; user_session_path && user_session_path[i]; i++)
194 path_element = user_session_path[i];
195
196 if (! path_element) {
197 nih_fatal (_("Invalid value for UPSTART_SESSION"));
198 exit (1);
199 }
200
201 pidfile_path = getenv ("XDG_RUNTIME_DIR");
202 if (!pidfile_path)
203 pidfile_path = getenv ("HOME");
204
205 if (pidfile_path) {
206 NIH_MUST (nih_strcat_sprintf (&pidfile, NULL, "%s/%s.%s.pid",
207 pidfile_path, program_invocation_short_name, path_element));
208 nih_main_set_pidfile (pidfile);
209 }
210 }
211
156 if (nih_main_daemonise () < 0) {212 if (nih_main_daemonise () < 0) {
157 NihError *err;213 NihError *err;
158214
@@ -163,10 +219,12 @@
163219
164 exit (1);220 exit (1);
165 }221 }
166222
167 /* Send all logging output to syslog */223 if (!user) {
168 openlog (program_name, LOG_PID, LOG_DAEMON);224 /* Send all logging output to syslog for system bridge */
169 nih_log_set_logger (nih_logger_syslog);225 openlog (program_name, LOG_PID, LOG_DAEMON);
226 nih_log_set_logger (nih_logger_syslog);
227 }
170 }228 }
171229
172 /* Handle TERM and INT signals gracefully */230 /* Handle TERM and INT signals gracefully */
173231
=== modified file 'util/telinit.c'
--- util/telinit.c 2014-03-10 13:43:50 +0000
+++ util/telinit.c 2015-01-17 15:39:44 +0000
@@ -160,27 +160,73 @@
160int160int
161restart_upstart (void)161restart_upstart (void)
162{162{
163 nih_local NihDBusProxy *upstart = NULL;163 nih_local NihDBusProxy *upstart = NULL;
164 DBusPendingCall *ret;164 NihError *err;
165 int ret;
165166
166 upstart = upstart_open (NULL);167 upstart = upstart_open (NULL);
167 if (! upstart)168 if (! upstart)
168 return -1;169 return -1;
169170
170 /* Fire and forget:171 /* Ask Upstart to restart itself.
171 *172 *
172 * Ask Upstart to restart itself using the async interface to173 * Since it is not possible to serialise a D-Bus connection,
173 * avoid the client-side complaining if and when it detects that174 * Upstart is forced to sever all D-Bus client connections,
174 * Upstart has severed all connections to perform the re-exec.175 * including this one.
175 */176 *
176 ret = upstart_restart (upstart, NULL, NULL, NULL, 0);177 * Further, since the user expects telinit to block _until the
177 dbus_connection_flush(upstart->connection);178 * re-exec has finished and Upstart is accepting connections
178179 * once again_, the only solution is to wait for the forced
179 /* We don't care about the return code, but we have to keep180 * disconnect, then poll until it is possible to create a new
180 * the compiler happy.181 * connection.
181 */182 *
182 if (ret != (DBusPendingCall *)TRUE)183 * Note that we don't (can't) care about the return code since
183 return 0;184 * it's not reliable:
185 *
186 * - either the re-exec request completed and D-Bus returned zero
187 * before Upstart started the re-exec.
188 *
189 * - or the re-exec request completed but upstart started the
190 * re-exec (severing all D-Bus connections) before D-Bus got a
191 * chance to finish cleanly meaning we receive a return of -1.
192 *
193 * We cannot know exactly what happened so have to allow for
194 * both scenarios. Note the implicit assumption that the re-exec
195 * request itself was accepted. If this assumption is incorrect
196 * (should not be possible), the worst case scenario is that
197 * upstart does not re-exec and then we quickly drop out of the
198 * reconnect block since it never went offline.
199 */
200 ret = upstart_restart_sync (NULL, upstart);
201
202 if (ret < 0) {
203 err = nih_error_get ();
204 nih_free (err);
205 }
206
207 nih_free (upstart);
208
209 nih_debug ("Waiting for upstart to finish re-exec");
210
211 /* We believe Upstart is now in the process of
212 * re-exec'ing so attempt forever to reconnect.
213 *
214 * This sounds dangerous but there is no other option,
215 * and a connection must be possible unless the system
216 * is completely broken.
217 */
218 while (TRUE) {
219
220 upstart = upstart_open (NULL);
221 if (upstart)
222 break;
223
224 err = nih_error_get ();
225 nih_free (err);
226
227 /* Avoid DoS'ing the system whilst we wait */
228 usleep (100000);
229 }
184230
185 return 0;231 return 0;
186}232}

Subscribers

People subscribed via source and target branches