Merge lp:~xnox/upstart/systemd-local-bridge into lp:ubuntu/vivid/upstart
- systemd-local-bridge
- Merge into vivid
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Hunt | Pending | ||
Ubuntu branches | Pending | ||
Review via email: mp+246772@code.launchpad.net |
Commit message
Description of the change
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 : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ChangeLog' | |||
2 | --- ChangeLog 2014-09-04 11:29:54 +0000 | |||
3 | +++ ChangeLog 2015-01-17 15:39:44 +0000 | |||
4 | @@ -1,3 +1,15 @@ | |||
5 | 1 | 2014-09-08 James Hunt <james.hunt@ubuntu.com> | ||
6 | 2 | |||
7 | 3 | * util/telinit.c: Remove UPSTART_TELINIT_U_NO_WAIT check as it | ||
8 | 4 | shouldn't realistically be needed. | ||
9 | 5 | |||
10 | 6 | 2014-08-21 James Hunt <james.hunt@ubuntu.com> | ||
11 | 7 | |||
12 | 8 | * util/telinit.c: restart_upstart(): | ||
13 | 9 | - Revert to synchronous behaviour coupled with unavoidable | ||
14 | 10 | poll to ensure telinit only returns once a re-exec has | ||
15 | 11 | completed (LP: #901038). | ||
16 | 12 | |||
17 | 1 | 2014-09-04 James Hunt <james.hunt@ubuntu.com> | 13 | 2014-09-04 James Hunt <james.hunt@ubuntu.com> |
18 | 2 | 14 | ||
19 | 3 | * NEWS: Release 1.13.2 | 15 | * NEWS: Release 1.13.2 |
20 | 4 | 16 | ||
21 | === modified file 'debian/changelog' | |||
22 | --- debian/changelog 2015-01-16 19:15:46 +0000 | |||
23 | +++ debian/changelog 2015-01-17 15:39:44 +0000 | |||
24 | @@ -1,13 +1,33 @@ | |||
25 | 1 | <<<<<<< TREE | ||
26 | 1 | upstart (1.13.2-0ubuntu6) UNRELEASED; urgency=medium | 2 | upstart (1.13.2-0ubuntu6) UNRELEASED; urgency=medium |
27 | 2 | 3 | ||
28 | 3 | * debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct | 4 | * debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct |
29 | 4 | into session init, by-passing system upstart & session | 5 | into session init, by-passing system upstart & session |
30 | 6 | ======= | ||
31 | 7 | upstart (1.13.2-0ubuntu7) UNRELEASED; urgency=medium | ||
32 | 8 | |||
33 | 9 | * Correct upstart-udev-bridge session job start/stop on conditions. | ||
34 | 10 | |||
35 | 11 | -- Dimitri John Ledkov <dimitri.j.ledkov@linux.intel.com> Sat, 17 Jan 2015 15:38:35 +0000 | ||
36 | 12 | |||
37 | 13 | upstart (1.13.2-0ubuntu6) vivid; urgency=medium | ||
38 | 14 | |||
39 | 15 | * debian/upstart-bin.upstart.cron.daily: Emit "rotate-logs" event direct | ||
40 | 16 | into session init, by-passing system upstart & session | ||
41 | 17 | >>>>>>> MERGE-SOURCE | ||
42 | 5 | event-bridge. This way session logs will be rotated, even upstart is | 18 | event-bridge. This way session logs will be rotated, even upstart is |
43 | 6 | not system init. | 19 | not system init. |
44 | 7 | * debian/control: make upstart-monitor & upstart-dconf-bridge be | 20 | * debian/control: make upstart-monitor & upstart-dconf-bridge be |
45 | 8 | installable with just session init, upstart-bin. | 21 | installable with just session init, upstart-bin. |
46 | 22 | * extra/upstart-local-bridge: implement systemd pid1 logic. | ||
47 | 23 | * extra/upstart-event-bridge: make it re-emit upstart-local-bridge | ||
48 | 24 | events direct. | ||
49 | 25 | * util/telinit: Revert to synchronous behaviour coupled with unavoidable | ||
50 | 26 | poll to ensure telinit only returns once a re-exec has completed (LP: | ||
51 | 27 | #901038). | ||
52 | 28 | * move udev & local bridges to upstart-bin package. | ||
53 | 9 | 29 | ||
55 | 10 | -- Dimitri John Ledkov <dimitri.j.ledkov@linux.intel.com> Sun, 11 Jan 2015 01:15:34 +0000 | 30 | -- Dimitri John Ledkov <dimitri.j.ledkov@linux.intel.com> Sat, 17 Jan 2015 01:59:42 +0000 |
56 | 11 | 31 | ||
57 | 12 | upstart (1.13.2-0ubuntu5) vivid; urgency=medium | 32 | upstart (1.13.2-0ubuntu5) vivid; urgency=medium |
58 | 13 | 33 | ||
59 | 14 | 34 | ||
60 | === modified file 'debian/control' | |||
61 | --- debian/control 2015-01-11 01:19:24 +0000 | |||
62 | +++ debian/control 2015-01-17 15:39:44 +0000 | |||
63 | @@ -33,8 +33,8 @@ | |||
64 | 33 | Architecture: any | 33 | Architecture: any |
65 | 34 | Depends: ${shlibs:Depends}, ${misc:Depends}, sysvinit-utils, initscripts, libjson0 (>= 0.10-1.1ubuntu1), debianutils (>= 4) | 34 | Depends: ${shlibs:Depends}, ${misc:Depends}, sysvinit-utils, initscripts, libjson0 (>= 0.10-1.1ubuntu1), debianutils (>= 4) |
66 | 35 | Suggests: python3, graphviz, bash-completion, upstart-monitor | 35 | Suggests: python3, graphviz, bash-completion, upstart-monitor |
69 | 36 | Replaces: upstart (<< 1.13.2-0ubuntu3) | 36 | Replaces: upstart (<< 1.13.2-0ubuntu6) |
70 | 37 | Breaks: upstart (<< 1.13.2-0ubuntu3) | 37 | Breaks: upstart (<< 1.13.2-0ubuntu6) |
71 | 38 | Multi-Arch: foreign | 38 | Multi-Arch: foreign |
72 | 39 | Description: event-based init daemon - essential binaries | 39 | Description: event-based init daemon - essential binaries |
73 | 40 | upstart is a replacement for the /sbin/init daemon which handles | 40 | upstart is a replacement for the /sbin/init daemon which handles |
74 | 41 | 41 | ||
75 | === modified file 'debian/rules' | |||
76 | --- debian/rules 2014-11-19 11:52:17 +0000 | |||
77 | +++ debian/rules 2015-01-17 15:39:44 +0000 | |||
78 | @@ -52,7 +52,6 @@ | |||
79 | 52 | install -m 644 debian/upstart-bin.apport \ | 52 | install -m 644 debian/upstart-bin.apport \ |
80 | 53 | debian/upstart-bin/usr/share/apport/package-hooks/source_upstart.py | 53 | debian/upstart-bin/usr/share/apport/package-hooks/source_upstart.py |
81 | 54 | rm debian/upstart-bin/usr/share/upstart/sessions/upstart-dconf-bridge.conf | 54 | rm debian/upstart-bin/usr/share/upstart/sessions/upstart-dconf-bridge.conf |
82 | 55 | rm debian/upstart/etc/init/upstart-event-bridge.conf | ||
83 | 56 | rm debian/upstart/etc/init/upstart-dbus-bridge.conf | 55 | rm debian/upstart/etc/init/upstart-dbus-bridge.conf |
84 | 57 | 56 | ||
85 | 58 | override_dh_installcron: | 57 | override_dh_installcron: |
86 | 59 | 58 | ||
87 | === modified file 'debian/upstart-bin.install' | |||
88 | --- debian/upstart-bin.install 2014-11-19 11:52:17 +0000 | |||
89 | +++ debian/upstart-bin.install 2015-01-17 15:39:44 +0000 | |||
90 | @@ -11,6 +11,8 @@ | |||
91 | 11 | sbin/upstart-dbus-bridge | 11 | sbin/upstart-dbus-bridge |
92 | 12 | sbin/upstart-event-bridge | 12 | sbin/upstart-event-bridge |
93 | 13 | sbin/upstart-file-bridge | 13 | sbin/upstart-file-bridge |
94 | 14 | sbin/upstart-local-bridge | ||
95 | 15 | sbin/upstart-udev-bridge | ||
96 | 14 | debian/running-in-container bin/ | 16 | debian/running-in-container bin/ |
97 | 15 | debian/apparmor-profile-load lib/init/ | 17 | debian/apparmor-profile-load lib/init/ |
98 | 16 | usr/share/upstart/sessions/* | 18 | usr/share/upstart/sessions/* |
99 | @@ -31,6 +33,8 @@ | |||
100 | 31 | usr/share/man/man8/upstart.8 | 33 | usr/share/man/man8/upstart.8 |
101 | 32 | usr/share/man/man8/upstart-file-bridge.8 | 34 | usr/share/man/man8/upstart-file-bridge.8 |
102 | 33 | usr/share/man/man8/upstart-dbus-bridge.8 | 35 | usr/share/man/man8/upstart-dbus-bridge.8 |
103 | 36 | usr/share/man/man8/upstart-local-bridge.8 | ||
104 | 37 | usr/share/man/man8/upstart-udev-bridge.8 | ||
105 | 34 | usr/share/man/man8/initctl2dot.8 | 38 | usr/share/man/man8/initctl2dot.8 |
106 | 35 | usr/share/man/man8/initctl.8 | 39 | usr/share/man/man8/initctl.8 |
107 | 36 | usr/share/man/man5/upstart.5 | 40 | usr/share/man/man5/upstart.5 |
108 | 37 | 41 | ||
109 | === modified file 'debian/upstart.install' | |||
110 | --- debian/upstart.install 2014-11-19 11:52:17 +0000 | |||
111 | +++ debian/upstart.install 2015-01-17 15:39:44 +0000 | |||
112 | @@ -6,9 +6,7 @@ | |||
113 | 6 | sbin/reboot | 6 | sbin/reboot |
114 | 7 | sbin/runlevel | 7 | sbin/runlevel |
115 | 8 | sbin/shutdown | 8 | sbin/shutdown |
116 | 9 | sbin/upstart-local-bridge | ||
117 | 10 | sbin/upstart-socket-bridge | 9 | sbin/upstart-socket-bridge |
118 | 11 | sbin/upstart-udev-bridge | ||
119 | 12 | debian/upstart-job lib/init/ | 10 | debian/upstart-job lib/init/ |
120 | 13 | debian/migrate-inittab.pl usr/lib/upstart/ | 11 | debian/migrate-inittab.pl usr/lib/upstart/ |
121 | 14 | usr/share/man/man7/control-alt-delete.7 | 12 | usr/share/man/man7/control-alt-delete.7 |
122 | @@ -17,8 +15,6 @@ | |||
123 | 17 | usr/share/man/man7/socket-event.7 | 15 | usr/share/man/man7/socket-event.7 |
124 | 18 | usr/share/man/man7/power-status-changed.7 | 16 | usr/share/man/man7/power-status-changed.7 |
125 | 19 | usr/share/man/man8/shutdown.8 | 17 | usr/share/man/man8/shutdown.8 |
126 | 20 | usr/share/man/man8/upstart-local-bridge.8 | ||
127 | 21 | usr/share/man/man8/upstart-udev-bridge.8 | ||
128 | 22 | usr/share/man/man8/runlevel.8 | 18 | usr/share/man/man8/runlevel.8 |
129 | 23 | usr/share/man/man8/reboot.8 | 19 | usr/share/man/man8/reboot.8 |
130 | 24 | usr/share/man/man8/upstart-socket-bridge.8 | 20 | usr/share/man/man8/upstart-socket-bridge.8 |
131 | 25 | 21 | ||
132 | === modified file 'extra/Makefile.am' | |||
133 | --- extra/Makefile.am 2013-11-14 17:41:01 +0000 | |||
134 | +++ extra/Makefile.am 2015-01-17 15:39:44 +0000 | |||
135 | @@ -23,6 +23,7 @@ | |||
136 | 23 | conf-session/upstart-event-bridge.conf \ | 23 | conf-session/upstart-event-bridge.conf \ |
137 | 24 | conf-session/upstart-file-bridge.conf \ | 24 | conf-session/upstart-file-bridge.conf \ |
138 | 25 | conf-session/re-exec.conf \ | 25 | conf-session/re-exec.conf \ |
139 | 26 | conf-session/upstart-udev-bridge.conf \ | ||
140 | 26 | conf-session/upstart-dbus-session-bridge.conf \ | 27 | conf-session/upstart-dbus-session-bridge.conf \ |
141 | 27 | conf-session/upstart-dbus-system-bridge.conf | 28 | conf-session/upstart-dbus-system-bridge.conf |
142 | 28 | 29 | ||
143 | @@ -33,7 +34,6 @@ | |||
144 | 33 | 34 | ||
145 | 34 | dist_init_DATA = \ | 35 | dist_init_DATA = \ |
146 | 35 | conf/upstart-socket-bridge.conf \ | 36 | conf/upstart-socket-bridge.conf \ |
147 | 36 | conf/upstart-event-bridge.conf \ | ||
148 | 37 | conf/upstart-file-bridge.conf \ | 37 | conf/upstart-file-bridge.conf \ |
149 | 38 | conf/upstart-dbus-bridge.conf | 38 | conf/upstart-dbus-bridge.conf |
150 | 39 | 39 | ||
151 | @@ -106,8 +106,9 @@ | |||
152 | 106 | upstart_local_bridge_SOURCES = \ | 106 | upstart_local_bridge_SOURCES = \ |
153 | 107 | upstart-local-bridge.c | 107 | upstart-local-bridge.c |
154 | 108 | nodist_upstart_local_bridge_SOURCES = \ | 108 | nodist_upstart_local_bridge_SOURCES = \ |
155 | 109 | $(org_freedesktop_systemd1_OUTPUTS) \ | ||
156 | 109 | $(com_ubuntu_Upstart_OUTPUTS) \ | 110 | $(com_ubuntu_Upstart_OUTPUTS) \ |
158 | 110 | $(com_ubuntu_Upstart_Job_OUTPUTS) | 111 | $(control_com_ubuntu_Upstart_OUTPUTS) |
159 | 111 | upstart_local_bridge_LDADD = \ | 112 | upstart_local_bridge_LDADD = \ |
160 | 112 | $(LTLIBINTL) \ | 113 | $(LTLIBINTL) \ |
161 | 113 | $(NIH_LIBS) \ | 114 | $(NIH_LIBS) \ |
162 | @@ -224,15 +225,50 @@ | |||
163 | 224 | --output=$@ $< | 225 | --output=$@ $< |
164 | 225 | 226 | ||
165 | 226 | 227 | ||
166 | 228 | org_freedesktop_systemd1_OUTPUTS = \ | ||
167 | 229 | org.freedesktop.systemd1.c \ | ||
168 | 230 | org.freedesktop.systemd1.h | ||
169 | 231 | |||
170 | 232 | org_freedesktop_systemd1_XML = \ | ||
171 | 233 | org.freedesktop.systemd1.xml | ||
172 | 234 | |||
173 | 235 | $(org_freedesktop_systemd1_OUTPUTS): $(org_freedesktop_systemd1_XML) | ||
174 | 236 | $(AM_V_GEN)$(NIH_DBUS_TOOL) \ | ||
175 | 237 | --package=$(PACKAGE) \ | ||
176 | 238 | --mode=proxy --prefix=systemd \ | ||
177 | 239 | --default-interface=org.freedesktop.systemd1.Manager \ | ||
178 | 240 | --output=$@ $< | ||
179 | 241 | |||
180 | 242 | # Server for upstart-local-bridge | ||
181 | 243 | control_com_ubuntu_Upstart_OUTPUTS = \ | ||
182 | 244 | control_com.ubuntu.Upstart.c \ | ||
183 | 245 | control_com.ubuntu.Upstart.h | ||
184 | 246 | |||
185 | 247 | control_com_ubuntu_Upstart_XML = \ | ||
186 | 248 | com.ubuntu.Upstart.xml | ||
187 | 249 | |||
188 | 250 | $(control_com_ubuntu_Upstart_OUTPUTS): $(control_com_ubuntu_Upstart_XML) | ||
189 | 251 | $(AM_V_GEN)$(NIH_DBUS_TOOL) \ | ||
190 | 252 | --package=$(PACKAGE) \ | ||
191 | 253 | --mode=object --prefix=control \ | ||
192 | 254 | --default-interface=com.ubuntu.Upstart0_6 \ | ||
193 | 255 | --output=$@ $< | ||
194 | 256 | |||
195 | 257 | |||
196 | 258 | |||
197 | 227 | # These have to be built sources because we can't compile object files | 259 | # These have to be built sources because we can't compile object files |
198 | 228 | # without the header file existing first | 260 | # without the header file existing first |
199 | 229 | BUILT_SOURCES = \ | 261 | BUILT_SOURCES = \ |
200 | 230 | $(com_ubuntu_Upstart_OUTPUTS) \ | 262 | $(com_ubuntu_Upstart_OUTPUTS) \ |
202 | 231 | $(com_ubuntu_Upstart_Job_OUTPUTS) | 263 | $(control_com_ubuntu_Upstart_OUTPUTS) \ |
203 | 264 | $(com_ubuntu_Upstart_Job_OUTPUTS) \ | ||
204 | 265 | $(org_freedesktop_systemd1_OUTPUTS) | ||
205 | 232 | 266 | ||
206 | 233 | CLEANFILES = \ | 267 | CLEANFILES = \ |
207 | 234 | $(com_ubuntu_Upstart_OUTPUTS) \ | 268 | $(com_ubuntu_Upstart_OUTPUTS) \ |
209 | 235 | $(com_ubuntu_Upstart_Job_OUTPUTS) | 269 | $(control_com_ubuntu_Upstart_OUTPUTS) \ |
210 | 270 | $(com_ubuntu_Upstart_Job_OUTPUTS) \ | ||
211 | 271 | $(org_freedesktop_systemd1_OUTPUTS) | ||
212 | 236 | 272 | ||
213 | 237 | 273 | ||
214 | 238 | clean-local: | 274 | clean-local: |
215 | 239 | 275 | ||
216 | === added file 'extra/com.ubuntu.Upstart.xml' | |||
217 | --- extra/com.ubuntu.Upstart.xml 1970-01-01 00:00:00 +0000 | |||
218 | +++ extra/com.ubuntu.Upstart.xml 2015-01-17 15:39:44 +0000 | |||
219 | @@ -0,0 +1,29 @@ | |||
220 | 1 | <?xml version="1.0" encoding="UTF-8" ?> | ||
221 | 2 | <!-- upstart | ||
222 | 3 | |||
223 | 4 | com.ubuntu.Upstart.xml - interface definition for manager object | ||
224 | 5 | |||
225 | 6 | Copyright © 2009 Canonical Ltd. | ||
226 | 7 | Author: Scott James Remnant <scott@netsplit.com>. | ||
227 | 8 | |||
228 | 9 | This file is free software; Canonical Ltd gives unlimited permission | ||
229 | 10 | to copy and/or distribute it, with or without modifications, as long | ||
230 | 11 | as this notice is preserved. | ||
231 | 12 | |||
232 | 13 | Communication and interaction with Upstart through this interface is | ||
233 | 14 | permitted without restriction. | ||
234 | 15 | --> | ||
235 | 16 | |||
236 | 17 | <!DOCTYPE node PUBLIC | ||
237 | 18 | "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
238 | 19 | "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
239 | 20 | |||
240 | 21 | <node name="/com/ubuntu/Upstart"> | ||
241 | 22 | <interface name="com.ubuntu.Upstart0_6"> | ||
242 | 23 | <!-- Signal for events being emitted --> | ||
243 | 24 | <signal name="EventEmitted"> | ||
244 | 25 | <arg name="name" type="s" /> | ||
245 | 26 | <arg name="env" type="as" /> | ||
246 | 27 | </signal> | ||
247 | 28 | </interface> | ||
248 | 29 | </node> | ||
249 | 0 | 30 | ||
250 | === added file 'extra/conf-session/upstart-udev-bridge.conf' | |||
251 | --- extra/conf-session/upstart-udev-bridge.conf 1970-01-01 00:00:00 +0000 | |||
252 | +++ extra/conf-session/upstart-udev-bridge.conf 2015-01-17 15:39:44 +0000 | |||
253 | @@ -0,0 +1,22 @@ | |||
254 | 1 | # upstart-udev-bridge - Bridge udev events into session upstart | ||
255 | 2 | # | ||
256 | 3 | # This helper daemon receives udev events from the netlink socket and | ||
257 | 4 | # emits equivalent Upstart events. | ||
258 | 5 | |||
259 | 6 | description "Bridge udev events into upstart" | ||
260 | 7 | |||
261 | 8 | # From upstart-udev-bridge itself | ||
262 | 9 | emits *-device-added | ||
263 | 10 | emits *-device-removed | ||
264 | 11 | emits *-device-changed | ||
265 | 12 | # From http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/libudev-udev-device.html | ||
266 | 13 | emits *-device-online | ||
267 | 14 | emits *-device-offline | ||
268 | 15 | |||
269 | 16 | start on startup | ||
270 | 17 | stop on desktop-end | ||
271 | 18 | |||
272 | 19 | expect daemon | ||
273 | 20 | respawn | ||
274 | 21 | |||
275 | 22 | exec upstart-udev-bridge --daemon --user | ||
276 | 0 | 23 | ||
277 | === removed file 'extra/conf/upstart-event-bridge.conf' | |||
278 | --- extra/conf/upstart-event-bridge.conf 2013-01-22 20:08:29 +0000 | |||
279 | +++ extra/conf/upstart-event-bridge.conf 1970-01-01 00:00:00 +0000 | |||
280 | @@ -1,15 +0,0 @@ | |||
281 | 1 | # upstart-event-bridge - Bridge system upstarts events into session upstart | ||
282 | 2 | # | ||
283 | 3 | # This helper daemon receives system upstart events from the DBus system bus | ||
284 | 4 | # and emits equivalent events (with a :sys:) prefix to the session bus | ||
285 | 5 | |||
286 | 6 | description "Bridge Upstart system events into session Upstart" | ||
287 | 7 | |||
288 | 8 | emits :sys:* | ||
289 | 9 | |||
290 | 10 | start on started dbus | ||
291 | 11 | stop on stopped dbus | ||
292 | 12 | |||
293 | 13 | respawn | ||
294 | 14 | |||
295 | 15 | exec upstart-event-bridge | ||
296 | 16 | 0 | ||
297 | === added file 'extra/org.freedesktop.systemd1.xml' | |||
298 | --- extra/org.freedesktop.systemd1.xml 1970-01-01 00:00:00 +0000 | |||
299 | +++ extra/org.freedesktop.systemd1.xml 2015-01-17 15:39:44 +0000 | |||
300 | @@ -0,0 +1,19 @@ | |||
301 | 1 | <?xml version="1.0" encoding="UTF-8" ?> | ||
302 | 2 | <!-- | ||
303 | 3 | org.freedesktop.systemd1- interface definition for systemd manager object | ||
304 | 4 | |||
305 | 5 | Public Domain | ||
306 | 6 | |||
307 | 7 | Generated file using gdbus introspect call against systemd1 instance | ||
308 | 8 | --> | ||
309 | 9 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
310 | 10 | "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
311 | 11 | <node> | ||
312 | 12 | <interface name="org.freedesktop.systemd1.Manager"> | ||
313 | 13 | <method name="StartUnit"> | ||
314 | 14 | <arg name="name" type="s" direction="in"/> | ||
315 | 15 | <arg name="mode" type="s" direction="in"/> | ||
316 | 16 | <arg name="job" type="o" direction="out"/> | ||
317 | 17 | </method> | ||
318 | 18 | </interface> | ||
319 | 19 | </node> | ||
320 | 0 | 20 | ||
321 | === modified file 'extra/upstart-event-bridge.c' | |||
322 | --- extra/upstart-event-bridge.c 2013-07-05 08:44:00 +0000 | |||
323 | +++ extra/upstart-event-bridge.c 2015-01-17 15:39:44 +0000 | |||
324 | @@ -26,6 +26,9 @@ | |||
325 | 26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
326 | 27 | #include <string.h> | 27 | #include <string.h> |
327 | 28 | #include <ctype.h> | 28 | #include <ctype.h> |
328 | 29 | #include <sys/types.h> | ||
329 | 30 | #include <sys/stat.h> | ||
330 | 31 | #include <unistd.h> | ||
331 | 29 | 32 | ||
332 | 30 | #include <nih/macros.h> | 33 | #include <nih/macros.h> |
333 | 31 | #include <nih/alloc.h> | 34 | #include <nih/alloc.h> |
334 | @@ -42,8 +45,10 @@ | |||
335 | 42 | #include "dbus/upstart.h" | 45 | #include "dbus/upstart.h" |
336 | 43 | #include "com.ubuntu.Upstart.h" | 46 | #include "com.ubuntu.Upstart.h" |
337 | 44 | 47 | ||
338 | 48 | #define DBUS_ADDRESS_LOCAL "unix:abstract=/com/ubuntu/upstart/local/bridge" | ||
339 | 45 | 49 | ||
340 | 46 | /* Prototypes for static functions */ | 50 | /* Prototypes for static functions */ |
341 | 51 | static int systemd_booted (void); | ||
342 | 47 | static void upstart_disconnected (DBusConnection *connection); | 52 | static void upstart_disconnected (DBusConnection *connection); |
343 | 48 | static void upstart_forward_event (void *data, NihDBusMessage *message, | 53 | static void upstart_forward_event (void *data, NihDBusMessage *message, |
344 | 49 | const char *path); | 54 | const char *path); |
345 | @@ -60,6 +65,14 @@ | |||
346 | 60 | static int daemonise = FALSE; | 65 | static int daemonise = FALSE; |
347 | 61 | 66 | ||
348 | 62 | /** | 67 | /** |
349 | 68 | * local: | ||
350 | 69 | * | ||
351 | 70 | * Set to TRUE if we should connect to upstart-local-bridge instead of | ||
352 | 71 | * the system init. | ||
353 | 72 | **/ | ||
354 | 73 | static int local = FALSE; | ||
355 | 74 | |||
356 | 75 | /** | ||
357 | 63 | * system_upstart: | 76 | * system_upstart: |
358 | 64 | * | 77 | * |
359 | 65 | * Proxy to system Upstart daemon. | 78 | * Proxy to system Upstart daemon. |
360 | @@ -119,9 +132,14 @@ | |||
361 | 119 | exit (1); | 132 | exit (1); |
362 | 120 | } | 133 | } |
363 | 121 | 134 | ||
364 | 135 | local = systemd_booted (); | ||
365 | 136 | |||
366 | 122 | /* Initialise the connection to system Upstart */ | 137 | /* Initialise the connection to system Upstart */ |
369 | 123 | system_connection = NIH_SHOULD (nih_dbus_bus (DBUS_BUS_SYSTEM, upstart_disconnected)); | 138 | if (local) { |
370 | 124 | 139 | system_connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_LOCAL, upstart_disconnected)); | |
371 | 140 | } else { | ||
372 | 141 | system_connection = NIH_SHOULD (nih_dbus_bus (DBUS_BUS_SYSTEM, upstart_disconnected)); | ||
373 | 142 | } | ||
374 | 125 | if (! system_connection) { | 143 | if (! system_connection) { |
375 | 126 | NihError *err; | 144 | NihError *err; |
376 | 127 | 145 | ||
377 | @@ -134,7 +152,7 @@ | |||
378 | 134 | } | 152 | } |
379 | 135 | 153 | ||
380 | 136 | system_upstart = NIH_SHOULD (nih_dbus_proxy_new (NULL, system_connection, | 154 | system_upstart = NIH_SHOULD (nih_dbus_proxy_new (NULL, system_connection, |
382 | 137 | DBUS_SERVICE_UPSTART, DBUS_PATH_UPSTART, | 155 | NULL, DBUS_PATH_UPSTART, |
383 | 138 | NULL, NULL)); | 156 | NULL, NULL)); |
384 | 139 | if (! system_upstart) { | 157 | if (! system_upstart) { |
385 | 140 | NihError *err; | 158 | NihError *err; |
386 | @@ -259,6 +277,20 @@ | |||
387 | 259 | return ret; | 277 | return ret; |
388 | 260 | } | 278 | } |
389 | 261 | 279 | ||
390 | 280 | static int | ||
391 | 281 | systemd_booted (void) | ||
392 | 282 | { | ||
393 | 283 | struct stat st; | ||
394 | 284 | |||
395 | 285 | if (lstat ("/run/systemd/system/", &st) == 0) { | ||
396 | 286 | if (S_ISDIR(st.st_mode)) { | ||
397 | 287 | return TRUE; | ||
398 | 288 | } | ||
399 | 289 | } | ||
400 | 290 | |||
401 | 291 | return FALSE; | ||
402 | 292 | } | ||
403 | 293 | |||
404 | 262 | static void | 294 | static void |
405 | 263 | upstart_disconnected (DBusConnection *connection) | 295 | upstart_disconnected (DBusConnection *connection) |
406 | 264 | { | 296 | { |
407 | @@ -293,7 +325,11 @@ | |||
408 | 293 | nih_assert (event_name != NULL); | 325 | nih_assert (event_name != NULL); |
409 | 294 | 326 | ||
410 | 295 | /* Build the new event name */ | 327 | /* Build the new event name */ |
412 | 296 | NIH_MUST (nih_strcat_sprintf (&new_event_name, NULL, ":sys:%s", event_name)); | 328 | if (local) { |
413 | 329 | new_event_name = NIH_MUST (nih_strdup (NULL, event_name)); | ||
414 | 330 | } else { | ||
415 | 331 | new_event_name = NIH_MUST (nih_sprintf (NULL, ":sys:%s", event_name)); | ||
416 | 332 | } | ||
417 | 297 | 333 | ||
418 | 298 | /* Re-transmit the event */ | 334 | /* Re-transmit the event */ |
419 | 299 | pending_call = upstart_emit_event (user_upstart, | 335 | pending_call = upstart_emit_event (user_upstart, |
420 | 300 | 336 | ||
421 | === modified file 'extra/upstart-local-bridge.c' | |||
422 | --- extra/upstart-local-bridge.c 2013-11-14 17:41:01 +0000 | |||
423 | +++ extra/upstart-local-bridge.c 2015-01-17 15:39:44 +0000 | |||
424 | @@ -22,10 +22,14 @@ | |||
425 | 22 | #endif /* HAVE_CONFIG_H */ | 22 | #endif /* HAVE_CONFIG_H */ |
426 | 23 | 23 | ||
427 | 24 | #include <sys/types.h> | 24 | #include <sys/types.h> |
428 | 25 | #include <sys/stat.h> | ||
429 | 25 | #include <sys/socket.h> | 26 | #include <sys/socket.h> |
430 | 26 | #include <sys/un.h> | 27 | #include <sys/un.h> |
431 | 28 | #include <sys/types.h> | ||
432 | 29 | #include <sys/wait.h> | ||
433 | 27 | 30 | ||
434 | 28 | #include <errno.h> | 31 | #include <errno.h> |
435 | 32 | #include <stdio.h> | ||
436 | 29 | #include <stdlib.h> | 33 | #include <stdlib.h> |
437 | 30 | #include <string.h> | 34 | #include <string.h> |
438 | 31 | #include <syslog.h> | 35 | #include <syslog.h> |
439 | @@ -45,24 +49,17 @@ | |||
440 | 45 | 49 | ||
441 | 46 | #include <nih-dbus/dbus_connection.h> | 50 | #include <nih-dbus/dbus_connection.h> |
442 | 47 | #include <nih-dbus/dbus_proxy.h> | 51 | #include <nih-dbus/dbus_proxy.h> |
443 | 52 | #include <nih-dbus/dbus_object.h> | ||
444 | 48 | 53 | ||
445 | 49 | #include "dbus/upstart.h" | 54 | #include "dbus/upstart.h" |
446 | 50 | #include "com.ubuntu.Upstart.h" | 55 | #include "com.ubuntu.Upstart.h" |
448 | 51 | #include "com.ubuntu.Upstart.Job.h" | 56 | #include "org.freedesktop.systemd1.h" |
449 | 57 | #include "control_com.ubuntu.Upstart.h" | ||
450 | 52 | 58 | ||
464 | 53 | /** | 59 | #define DBUS_ADDRESS_SYSTEMD "unix:path=/run/systemd/private" |
465 | 54 | * Job: | 60 | #define DBUS_PATH_SYSTEMD "/org/freedesktop/systemd1" |
466 | 55 | * | 61 | #define DBUS_SERVICE_SYSTEMD "org.freedesktop.systemd1" |
467 | 56 | * @entry: list header, | 62 | #define DBUS_ADDRESS_LOCAL "unix:abstract=/com/ubuntu/upstart/local/bridge" |
455 | 57 | * @path: D-Bus path for a job. | ||
456 | 58 | * | ||
457 | 59 | * Representation of an Upstart Job. | ||
458 | 60 | * | ||
459 | 61 | **/ | ||
460 | 62 | typedef struct job { | ||
461 | 63 | NihList entry; | ||
462 | 64 | char *path; | ||
463 | 65 | } Job; | ||
468 | 66 | 63 | ||
469 | 67 | /** | 64 | /** |
470 | 68 | * Socket: | 65 | * Socket: |
471 | @@ -100,12 +97,14 @@ | |||
472 | 100 | struct ucred ucred; | 97 | struct ucred ucred; |
473 | 101 | } ClientConnection; | 98 | } ClientConnection; |
474 | 102 | 99 | ||
475 | 103 | static void upstart_job_added (void *data, NihDBusMessage *message, | ||
476 | 104 | const char *job); | ||
477 | 105 | static void upstart_job_removed (void *data, NihDBusMessage *message, | ||
478 | 106 | const char *job); | ||
479 | 107 | static void upstart_connect (void); | 100 | static void upstart_connect (void); |
481 | 108 | static void upstart_disconnected (DBusConnection *connection); | 101 | static void systemd_connect (void); |
482 | 102 | static int systemd_booted (void); | ||
483 | 103 | static int control_server_open (void); | ||
484 | 104 | static int control_server_connect (DBusServer *server, | ||
485 | 105 | DBusConnection *conn); | ||
486 | 106 | static void control_disconnected (DBusConnection *conn); | ||
487 | 107 | static void init_disconnected (DBusConnection *connection); | ||
488 | 109 | 108 | ||
489 | 110 | static Socket *create_socket (void *parent); | 109 | static Socket *create_socket (void *parent); |
490 | 111 | 110 | ||
491 | @@ -121,6 +120,8 @@ | |||
492 | 121 | 120 | ||
493 | 122 | static void emit_event (ClientConnection *client, const char *pair, size_t len); | 121 | static void emit_event (ClientConnection *client, const char *pair, size_t len); |
494 | 123 | 122 | ||
495 | 123 | static void process_event (ClientConnection *client, const char *pair, size_t len); | ||
496 | 124 | |||
497 | 124 | static void signal_handler (void *data, NihSignal *signal); | 125 | static void signal_handler (void *data, NihSignal *signal); |
498 | 125 | 126 | ||
499 | 126 | static void cleanup (void); | 127 | static void cleanup (void); |
500 | @@ -134,13 +135,6 @@ | |||
501 | 134 | static int daemonise = FALSE; | 135 | static int daemonise = FALSE; |
502 | 135 | 136 | ||
503 | 136 | /** | 137 | /** |
504 | 137 | * jobs: | ||
505 | 138 | * | ||
506 | 139 | * Jobs that we're monitoring. | ||
507 | 140 | **/ | ||
508 | 141 | static NihHash *jobs = NULL; | ||
509 | 142 | |||
510 | 143 | /** | ||
511 | 144 | * upstart: | 138 | * upstart: |
512 | 145 | * | 139 | * |
513 | 146 | * Proxy to Upstart daemon. | 140 | * Proxy to Upstart daemon. |
514 | @@ -148,9 +142,32 @@ | |||
515 | 148 | static NihDBusProxy *upstart = NULL; | 142 | static NihDBusProxy *upstart = NULL; |
516 | 149 | 143 | ||
517 | 150 | /** | 144 | /** |
518 | 145 | * systemd: | ||
519 | 146 | * | ||
520 | 147 | * Proxy to systemd daemon. | ||
521 | 148 | **/ | ||
522 | 149 | static NihDBusProxy *systemd = NULL; | ||
523 | 150 | |||
524 | 151 | /** | ||
525 | 152 | * control_server | ||
526 | 153 | * | ||
527 | 154 | * D-Bus server listening for new direct connections. | ||
528 | 155 | **/ | ||
529 | 156 | DBusServer *control_server = NULL; | ||
530 | 157 | |||
531 | 158 | /** | ||
532 | 159 | * control_conns: | ||
533 | 160 | * | ||
534 | 161 | * Open control connections, including the connection to a D-Bus | ||
535 | 162 | * bus and any private client connections. | ||
536 | 163 | **/ | ||
537 | 164 | NihList *control_conns = NULL; | ||
538 | 165 | |||
539 | 166 | /** | ||
540 | 151 | * event_name: | 167 | * event_name: |
541 | 152 | * | 168 | * |
543 | 153 | * Name of event this bridge emits. | 169 | * upstart: Name of event this bridge emits. |
544 | 170 | * systmed: Name of target this generator creates. | ||
545 | 154 | **/ | 171 | **/ |
546 | 155 | static char *event_name = NULL; | 172 | static char *event_name = NULL; |
547 | 156 | 173 | ||
548 | @@ -202,7 +219,7 @@ | |||
549 | 202 | { 0, "daemon", N_("Detach and run in the background"), | 219 | { 0, "daemon", N_("Detach and run in the background"), |
550 | 203 | NULL, NULL, &daemonise, NULL }, | 220 | NULL, NULL, &daemonise, NULL }, |
551 | 204 | 221 | ||
553 | 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"), |
554 | 206 | NULL, "EVENT", &event_name, NULL }, | 223 | NULL, "EVENT", &event_name, NULL }, |
555 | 207 | 224 | ||
556 | 208 | { 0, "any-user", N_("allow any user to connect"), | 225 | { 0, "any-user", N_("allow any user to connect"), |
557 | @@ -258,7 +275,7 @@ | |||
558 | 258 | 275 | ||
559 | 259 | nih_main_init (argv[0]); | 276 | nih_main_init (argv[0]); |
560 | 260 | 277 | ||
562 | 261 | nih_option_set_synopsis (_("Local socket Upstart Bridge")); | 278 | nih_option_set_synopsis (_("Local socket Upstart Bridge & systemd generator")); |
563 | 262 | nih_option_set_help ( | 279 | nih_option_set_help ( |
564 | 263 | _("By default, this bridge does not detach from the " | 280 | _("By default, this bridge does not detach from the " |
565 | 264 | "console and remains in the foreground. Use the --daemon " | 281 | "console and remains in the foreground. Use the --daemon " |
566 | @@ -273,9 +290,6 @@ | |||
567 | 273 | exit (1); | 290 | exit (1); |
568 | 274 | } | 291 | } |
569 | 275 | 292 | ||
570 | 276 | /* Allocate jobs hash table */ | ||
571 | 277 | jobs = NIH_MUST (nih_hash_string_new (NULL, 0)); | ||
572 | 278 | |||
573 | 279 | sock = create_socket (NULL); | 293 | sock = create_socket (NULL); |
574 | 280 | if (! sock) { | 294 | if (! sock) { |
575 | 281 | nih_fatal ("%s %s", | 295 | nih_fatal ("%s %s", |
576 | @@ -286,7 +300,26 @@ | |||
577 | 286 | 300 | ||
578 | 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); |
579 | 288 | 302 | ||
581 | 289 | upstart_connect (); | 303 | if (systemd_booted() == TRUE) { |
582 | 304 | systemd_connect (); | ||
583 | 305 | } else { | ||
584 | 306 | upstart_connect (); | ||
585 | 307 | } | ||
586 | 308 | |||
587 | 309 | control_conns = NIH_MUST (nih_list_new (NULL)); | ||
588 | 310 | |||
589 | 311 | while ((ret = control_server_open ()) < 0) { | ||
590 | 312 | NihError *err; | ||
591 | 313 | |||
592 | 314 | err = nih_error_get (); | ||
593 | 315 | if (err->number != ENOMEM) { | ||
594 | 316 | nih_warn ("%s: %s", _("Unable to listen for private" | ||
595 | 317 | "connections"), err->message); | ||
596 | 318 | nih_free (err); | ||
597 | 319 | break; | ||
598 | 320 | } | ||
599 | 321 | nih_free (err); | ||
600 | 322 | } | ||
601 | 290 | 323 | ||
602 | 291 | /* Become daemon */ | 324 | /* Become daemon */ |
603 | 292 | if (daemonise) { | 325 | if (daemonise) { |
604 | @@ -326,103 +359,14 @@ | |||
605 | 326 | return ret; | 359 | return ret; |
606 | 327 | } | 360 | } |
607 | 328 | 361 | ||
608 | 329 | static void | ||
609 | 330 | upstart_job_added (void *data, | ||
610 | 331 | NihDBusMessage *message, | ||
611 | 332 | const char *job_class_path) | ||
612 | 333 | { | ||
613 | 334 | nih_local NihDBusProxy *job_class = NULL; | ||
614 | 335 | nih_local char ***start_on = NULL; | ||
615 | 336 | nih_local char ***stop_on = NULL; | ||
616 | 337 | Job *job; | ||
617 | 338 | |||
618 | 339 | nih_assert (job_class_path != NULL); | ||
619 | 340 | |||
620 | 341 | /* Obtain a proxy to the job */ | ||
621 | 342 | job_class = nih_dbus_proxy_new (NULL, upstart->connection, | ||
622 | 343 | upstart->name, job_class_path, | ||
623 | 344 | NULL, NULL); | ||
624 | 345 | if (! job_class) { | ||
625 | 346 | NihError *err; | ||
626 | 347 | |||
627 | 348 | err = nih_error_get (); | ||
628 | 349 | nih_error ("Could not create proxy for job %s: %s", | ||
629 | 350 | job_class_path, err->message); | ||
630 | 351 | nih_free (err); | ||
631 | 352 | |||
632 | 353 | return; | ||
633 | 354 | } | ||
634 | 355 | |||
635 | 356 | job_class->auto_start = FALSE; | ||
636 | 357 | |||
637 | 358 | /* Obtain the start_on and stop_on properties of the job */ | ||
638 | 359 | if (job_class_get_start_on_sync (NULL, job_class, &start_on) < 0) { | ||
639 | 360 | NihError *err; | ||
640 | 361 | |||
641 | 362 | err = nih_error_get (); | ||
642 | 363 | nih_error ("Could not obtain job start condition %s: %s", | ||
643 | 364 | job_class_path, err->message); | ||
644 | 365 | nih_free (err); | ||
645 | 366 | |||
646 | 367 | return; | ||
647 | 368 | } | ||
648 | 369 | |||
649 | 370 | if (job_class_get_stop_on_sync (NULL, job_class, &stop_on) < 0) { | ||
650 | 371 | NihError *err; | ||
651 | 372 | |||
652 | 373 | err = nih_error_get (); | ||
653 | 374 | nih_error ("Could not obtain job stop condition %s: %s", | ||
654 | 375 | job_class_path, err->message); | ||
655 | 376 | nih_free (err); | ||
656 | 377 | |||
657 | 378 | return; | ||
658 | 379 | } | ||
659 | 380 | |||
660 | 381 | /* Free any existing record for the job (should never happen, | ||
661 | 382 | * but worth being safe). | ||
662 | 383 | */ | ||
663 | 384 | job = (Job *)nih_hash_lookup (jobs, job_class_path); | ||
664 | 385 | if (job) | ||
665 | 386 | nih_free (job); | ||
666 | 387 | |||
667 | 388 | /* Create new record for the job */ | ||
668 | 389 | job = NIH_MUST (nih_new (NULL, Job)); | ||
669 | 390 | job->path = NIH_MUST (nih_strdup (job, job_class_path)); | ||
670 | 391 | |||
671 | 392 | nih_list_init (&job->entry); | ||
672 | 393 | |||
673 | 394 | nih_debug ("Job got added %s", job_class_path); | ||
674 | 395 | |||
675 | 396 | nih_alloc_set_destructor (job, nih_list_destroy); | ||
676 | 397 | |||
677 | 398 | /* Add all jobs */ | ||
678 | 399 | nih_hash_add (jobs, &job->entry); | ||
679 | 400 | } | ||
680 | 401 | |||
681 | 402 | static void | ||
682 | 403 | upstart_job_removed (void *data, | ||
683 | 404 | NihDBusMessage *message, | ||
684 | 405 | const char *job_path) | ||
685 | 406 | { | ||
686 | 407 | Job *job; | ||
687 | 408 | |||
688 | 409 | nih_assert (job_path != NULL); | ||
689 | 410 | |||
690 | 411 | job = (Job *)nih_hash_lookup (jobs, job_path); | ||
691 | 412 | if (job) { | ||
692 | 413 | nih_debug ("Job went away %s", job_path); | ||
693 | 414 | nih_free (job); | ||
694 | 415 | } | ||
695 | 416 | } | ||
696 | 417 | 362 | ||
697 | 418 | static void | 363 | static void |
698 | 419 | upstart_connect (void) | 364 | upstart_connect (void) |
699 | 420 | { | 365 | { |
700 | 421 | DBusConnection *connection; | 366 | DBusConnection *connection; |
701 | 422 | char **job_class_paths; | ||
702 | 423 | 367 | ||
703 | 424 | /* Initialise the connection to Upstart */ | 368 | /* Initialise the connection to Upstart */ |
705 | 425 | connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_UPSTART, upstart_disconnected)); | 369 | connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_UPSTART, init_disconnected)); |
706 | 426 | if (! connection) { | 370 | if (! connection) { |
707 | 427 | NihError *err; | 371 | NihError *err; |
708 | 428 | 372 | ||
709 | @@ -449,59 +393,169 @@ | |||
710 | 449 | } | 393 | } |
711 | 450 | 394 | ||
712 | 451 | nih_debug ("Connected to Upstart"); | 395 | nih_debug ("Connected to Upstart"); |
762 | 452 | 396 | } | |
763 | 453 | /* Connect signals to be notified when jobs come and go */ | 397 | |
764 | 454 | if (! nih_dbus_proxy_connect (upstart, &upstart_com_ubuntu_Upstart0_6, "JobAdded", | 398 | static void |
765 | 455 | (NihDBusSignalHandler)upstart_job_added, NULL)) { | 399 | systemd_connect (void) |
766 | 456 | NihError *err; | 400 | { |
767 | 457 | 401 | DBusConnection *connection; | |
768 | 458 | err = nih_error_get (); | 402 | |
769 | 459 | nih_fatal ("%s: %s", _("Could not create JobAdded signal connection"), | 403 | /* Initialise the connection to systemd */ |
770 | 460 | err->message); | 404 | /* /run/systemd/private is supposedly "private" end-point |
771 | 461 | nih_free (err); | 405 | * which systemctl & libsystemd use */ |
772 | 462 | 406 | connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_SYSTEMD, init_disconnected)); | |
773 | 463 | exit (1); | 407 | if (! connection) { |
774 | 464 | } | 408 | NihError *err; |
775 | 465 | 409 | ||
776 | 466 | if (! nih_dbus_proxy_connect (upstart, &upstart_com_ubuntu_Upstart0_6, "JobRemoved", | 410 | err = nih_error_get (); |
777 | 467 | (NihDBusSignalHandler)upstart_job_removed, NULL)) { | 411 | nih_fatal ("%s: %s", _("Could not connect to systemd"), |
778 | 468 | NihError *err; | 412 | err->message); |
779 | 469 | 413 | nih_free (err); | |
780 | 470 | err = nih_error_get (); | 414 | |
781 | 471 | nih_fatal ("%s: %s", _("Could not create JobRemoved signal connection"), | 415 | exit (1); |
782 | 472 | err->message); | 416 | } |
783 | 473 | nih_free (err); | 417 | |
784 | 474 | 418 | systemd = NIH_SHOULD (nih_dbus_proxy_new (NULL, connection, | |
785 | 475 | exit (1); | 419 | NULL, DBUS_PATH_SYSTEMD, |
786 | 476 | } | 420 | NULL, NULL)); |
787 | 477 | 421 | if (! systemd) { | |
788 | 478 | /* Request a list of all current jobs */ | 422 | NihError *err; |
789 | 479 | if (upstart_get_all_jobs_sync (NULL, upstart, &job_class_paths) < 0) { | 423 | |
790 | 480 | NihError *err; | 424 | err = nih_error_get (); |
791 | 481 | 425 | nih_fatal ("%s: %s", _("Could not create systemd proxy"), | |
792 | 482 | err = nih_error_get (); | 426 | err->message); |
793 | 483 | nih_fatal ("%s: %s", _("Could not obtain job list"), | 427 | nih_free (err); |
794 | 484 | err->message); | 428 | |
795 | 485 | nih_free (err); | 429 | exit (1); |
796 | 486 | 430 | } | |
797 | 487 | exit (1); | 431 | |
798 | 488 | } | 432 | FILE *fp = NULL; |
799 | 489 | 433 | nih_local char *template_name = NULL; | |
800 | 490 | for (char **job_class_path = job_class_paths; | 434 | |
801 | 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)); |
802 | 492 | upstart_job_added (NULL, NULL, *job_class_path); | 436 | |
803 | 493 | 437 | fp = NIH_SHOULD (fopen(template_name, "we")); | |
804 | 494 | nih_free (job_class_paths); | 438 | if (!fp) { |
805 | 495 | } | 439 | nih_fatal ("%s %s", _("Failed to create target template"), |
806 | 496 | 440 | strerror (errno)); | |
807 | 497 | static void | 441 | exit (1); |
808 | 498 | upstart_disconnected (DBusConnection *connection) | 442 | } |
809 | 499 | { | 443 | fprintf (fp, |
810 | 500 | nih_fatal (_("Disconnected from Upstart")); | 444 | "# Automatically generated by %s\n\n" |
811 | 445 | "[Unit]\n" | ||
812 | 446 | "Description=Local bridge key value pairs\n" | ||
813 | 447 | "Documentation=man:%s\n", | ||
814 | 448 | program_name, program_name); | ||
815 | 449 | fflush (fp); | ||
816 | 450 | if (ferror (fp)) { | ||
817 | 451 | nih_fatal ("%s %s", _("Failed to write target template"), | ||
818 | 452 | strerror (errno)); | ||
819 | 453 | exit (1); | ||
820 | 454 | } | ||
821 | 455 | fclose (fp); | ||
822 | 456 | |||
823 | 457 | nih_debug ("Connected to systemd"); | ||
824 | 458 | } | ||
825 | 459 | |||
826 | 460 | static int | ||
827 | 461 | systemd_booted (void) | ||
828 | 462 | { | ||
829 | 463 | struct stat st; | ||
830 | 464 | |||
831 | 465 | if (lstat ("/run/systemd/system/", &st) == 0) { | ||
832 | 466 | if (S_ISDIR(st.st_mode)) { | ||
833 | 467 | return TRUE; | ||
834 | 468 | } | ||
835 | 469 | } | ||
836 | 470 | |||
837 | 471 | return FALSE; | ||
838 | 472 | } | ||
839 | 473 | |||
840 | 474 | static void | ||
841 | 475 | init_disconnected (DBusConnection *connection) | ||
842 | 476 | { | ||
843 | 477 | nih_fatal (_("Disconnected from init")); | ||
844 | 501 | nih_main_loop_exit (1); | 478 | nih_main_loop_exit (1); |
845 | 502 | } | 479 | } |
846 | 503 | 480 | ||
847 | 504 | /** | 481 | /** |
848 | 482 | * control_server_open: | ||
849 | 483 | * | ||
850 | 484 | * Open a listening D-Bus server and store it in the control_server global. | ||
851 | 485 | * New connections are permitted from the root user, and handled | ||
852 | 486 | * automatically in the main loop. | ||
853 | 487 | * | ||
854 | 488 | * Returns: zero on success, negative value on raised error. | ||
855 | 489 | **/ | ||
856 | 490 | |||
857 | 491 | int | ||
858 | 492 | control_server_open (void) | ||
859 | 493 | { | ||
860 | 494 | nih_assert (control_server == NULL); | ||
861 | 495 | |||
862 | 496 | control_server = nih_dbus_server (DBUS_ADDRESS_LOCAL, | ||
863 | 497 | control_server_connect, | ||
864 | 498 | control_disconnected); | ||
865 | 499 | if (! control_server) | ||
866 | 500 | return -1; | ||
867 | 501 | |||
868 | 502 | nih_debug("D-Bus server started at address: %s", DBUS_ADDRESS_LOCAL); | ||
869 | 503 | |||
870 | 504 | return 0; | ||
871 | 505 | } | ||
872 | 506 | |||
873 | 507 | /** | ||
874 | 508 | * control_server_connect: | ||
875 | 509 | * | ||
876 | 510 | * Called when a new client connects to our server and is used to register | ||
877 | 511 | * objects on the new connection. | ||
878 | 512 | * | ||
879 | 513 | * Returns: always TRUE. | ||
880 | 514 | **/ | ||
881 | 515 | static int | ||
882 | 516 | control_server_connect (DBusServer *server, | ||
883 | 517 | DBusConnection *conn) | ||
884 | 518 | { | ||
885 | 519 | nih_assert (server != NULL); | ||
886 | 520 | nih_assert (server == control_server); | ||
887 | 521 | nih_assert (conn != NULL); | ||
888 | 522 | NihListEntry *entry = NULL; | ||
889 | 523 | |||
890 | 524 | /* Register objects on the connection. */ | ||
891 | 525 | NIH_MUST (nih_dbus_object_new (NULL, conn, DBUS_PATH_UPSTART, | ||
892 | 526 | control_interfaces, NULL)); | ||
893 | 527 | |||
894 | 528 | |||
895 | 529 | entry = NIH_MUST (nih_list_entry_new (NULL)); | ||
896 | 530 | entry->data = conn; | ||
897 | 531 | nih_list_add (control_conns, &entry->entry); | ||
898 | 532 | nih_debug("Connection from private client"); | ||
899 | 533 | |||
900 | 534 | return TRUE; | ||
901 | 535 | } | ||
902 | 536 | |||
903 | 537 | /** | ||
904 | 538 | * control_disconnected: | ||
905 | 539 | * | ||
906 | 540 | * This function is called when the connection to the D-Bus system bus, | ||
907 | 541 | * or a client connection to our D-Bus server, is dropped and our reference | ||
908 | 542 | * is about to be list. We clear the connection from our current list | ||
909 | 543 | * and drop the control_bus global if relevant. | ||
910 | 544 | **/ | ||
911 | 545 | static void | ||
912 | 546 | control_disconnected (DBusConnection *conn) | ||
913 | 547 | { | ||
914 | 548 | nih_assert (conn != NULL); | ||
915 | 549 | /* Remove from the connections list */ | ||
916 | 550 | NIH_LIST_FOREACH_SAFE (control_conns, iter) { | ||
917 | 551 | NihListEntry *entry = (NihListEntry *)iter; | ||
918 | 552 | |||
919 | 553 | if (entry->data == conn) | ||
920 | 554 | nih_free (entry); | ||
921 | 555 | } | ||
922 | 556 | } | ||
923 | 557 | |||
924 | 558 | /** | ||
925 | 505 | * socket_watcher: | 559 | * socket_watcher: |
926 | 506 | * | 560 | * |
927 | 507 | * @sock: Socket, | 561 | * @sock: Socket, |
928 | @@ -645,7 +699,7 @@ | |||
929 | 645 | if (used_len < min_len) | 699 | if (used_len < min_len) |
930 | 646 | continue; | 700 | continue; |
931 | 647 | 701 | ||
933 | 648 | emit_event (client, pair, used_len); | 702 | process_event (client, pair, used_len); |
934 | 649 | } | 703 | } |
935 | 650 | 704 | ||
936 | 651 | /* Consume the entire length */ | 705 | /* Consume the entire length */ |
937 | @@ -724,6 +778,8 @@ | |||
938 | 724 | /* Handle abstract names */ | 778 | /* Handle abstract names */ |
939 | 725 | if (sock->sun_addr.sun_path[0] == '@') | 779 | if (sock->sun_addr.sun_path[0] == '@') |
940 | 726 | sock->sun_addr.sun_path[0] = '\0'; | 780 | sock->sun_addr.sun_path[0] = '\0'; |
941 | 781 | else | ||
942 | 782 | (void) unlink(sock->sun_addr.sun_path); | ||
943 | 727 | 783 | ||
944 | 728 | sock->sock = socket (sock->addr.sa_family, SOCK_STREAM, 0); | 784 | sock->sock = socket (sock->addr.sa_family, SOCK_STREAM, 0); |
945 | 729 | if (sock->sock < 0) { | 785 | if (sock->sock < 0) { |
946 | @@ -830,17 +886,102 @@ | |||
947 | 830 | /* Add the name=value pair */ | 886 | /* Add the name=value pair */ |
948 | 831 | NIH_MUST (nih_str_array_addn (&env, NULL, NULL, pair, len)); | 887 | NIH_MUST (nih_str_array_addn (&env, NULL, NULL, pair, len)); |
949 | 832 | 888 | ||
956 | 833 | pending_call = upstart_emit_event (upstart, | 889 | if (upstart) { |
957 | 834 | event_name, env, FALSE, | 890 | pending_call = upstart_emit_event (upstart, |
958 | 835 | NULL, emit_event_error, NULL, | 891 | event_name, env, FALSE, |
959 | 836 | NIH_DBUS_TIMEOUT_NEVER); | 892 | NULL, emit_event_error, NULL, |
960 | 837 | 893 | NIH_DBUS_TIMEOUT_NEVER); | |
961 | 838 | if (! pending_call) { | 894 | |
962 | 895 | if (! pending_call) { | ||
963 | 896 | NihError *err; | ||
964 | 897 | err = nih_error_get (); | ||
965 | 898 | nih_warn ("%s", err->message); | ||
966 | 899 | nih_free (err); | ||
967 | 900 | } | ||
968 | 901 | |||
969 | 902 | dbus_pending_call_unref (pending_call); | ||
970 | 903 | } | ||
971 | 904 | |||
972 | 905 | NIH_LIST_FOREACH (control_conns, iter) { | ||
973 | 906 | NihListEntry *entry = (NihListEntry *)iter; | ||
974 | 907 | DBusConnection *conn = (DBusConnection *)entry->data; | ||
975 | 908 | |||
976 | 909 | NIH_ZERO (control_emit_event_emitted (conn, DBUS_PATH_UPSTART, | ||
977 | 910 | event_name, env)); | ||
978 | 911 | } | ||
979 | 912 | |||
980 | 913 | } | ||
981 | 914 | |||
982 | 915 | static void | ||
983 | 916 | systemd_launch_instance (ClientConnection *client, | ||
984 | 917 | const char *pair, | ||
985 | 918 | size_t len) | ||
986 | 919 | { | ||
987 | 920 | nih_local char *safe_pair = NULL; | ||
988 | 921 | nih_local char **key_value = NULL; | ||
989 | 922 | nih_local char *group_name = NULL; | ||
990 | 923 | nih_local char *unit_name = NULL; | ||
991 | 924 | nih_local char *job_name = NULL; | ||
992 | 925 | |||
993 | 926 | nih_assert (client); | ||
994 | 927 | nih_assert (pair); | ||
995 | 928 | nih_assert (len); | ||
996 | 929 | |||
997 | 930 | /* Why is pair not null-terminated?! */ | ||
998 | 931 | safe_pair = NIH_MUST (nih_strndup (NULL, pair, len)); | ||
999 | 932 | |||
1000 | 933 | /* Get key val from the key=val pair */ | ||
1001 | 934 | key_value = NIH_MUST (nih_str_split (NULL, safe_pair, "=", TRUE)); | ||
1002 | 935 | |||
1003 | 936 | /* Construct systemd event@key=*.target group name */ | ||
1004 | 937 | group_name = NIH_MUST (nih_sprintf (NULL, "%s@%s=*.target", | ||
1005 | 938 | event_name, key_value[0])); | ||
1006 | 939 | |||
1007 | 940 | /* Construct systemd event@key=value.target unit name */ | ||
1008 | 941 | unit_name = NIH_MUST (nih_sprintf (NULL, "%s@%s\\x3d%s.target", | ||
1009 | 942 | event_name, key_value[0], | ||
1010 | 943 | key_value[1])); | ||
1011 | 944 | |||
1012 | 945 | /* Stop group */ | ||
1013 | 946 | int pid = -1; | ||
1014 | 947 | siginfo_t info; | ||
1015 | 948 | do { | ||
1016 | 949 | pid = fork (); | ||
1017 | 950 | } while (pid < 0); | ||
1018 | 951 | |||
1019 | 952 | if (pid) { | ||
1020 | 953 | info.si_code = 0; | ||
1021 | 954 | info.si_status = 0; | ||
1022 | 955 | if (waitid (P_PID, pid, &info, WEXITED)) { | ||
1023 | 956 | nih_fatal ("%s %s", _("Failed to wait for systemctl"), | ||
1024 | 957 | strerror (errno)); | ||
1025 | 958 | } | ||
1026 | 959 | if (info.si_code != CLD_EXITED || info.si_status) { | ||
1027 | 960 | nih_fatal ("Bad systemctl exit code %i and status %i\n", info.si_code, info.si_status); | ||
1028 | 961 | } | ||
1029 | 962 | } else { | ||
1030 | 963 | /* Create and submit stop state transition, do not wait to complete */ | ||
1031 | 964 | execlp ("systemctl", "systemctl", "--no-block", "stop", group_name, (char *)NULL); | ||
1032 | 965 | } | ||
1033 | 966 | |||
1034 | 967 | /* Create and submit start state transition, do not wait to complete */ | ||
1035 | 968 | if (systemd_start_unit_sync (NULL, systemd, unit_name, "replace", &job_name)) { | ||
1036 | 839 | NihError *err; | 969 | NihError *err; |
1037 | 840 | err = nih_error_get (); | 970 | err = nih_error_get (); |
1038 | 841 | nih_warn ("%s", err->message); | 971 | nih_warn ("%s", err->message); |
1039 | 842 | nih_free (err); | 972 | nih_free (err); |
1040 | 843 | } | 973 | } |
1043 | 844 | 974 | } | |
1044 | 845 | dbus_pending_call_unref (pending_call); | 975 | |
1045 | 976 | |||
1046 | 977 | static void | ||
1047 | 978 | process_event (ClientConnection *client, | ||
1048 | 979 | const char *pair, | ||
1049 | 980 | size_t len) | ||
1050 | 981 | { | ||
1051 | 982 | emit_event (client, pair, len); | ||
1052 | 983 | |||
1053 | 984 | if (systemd) { | ||
1054 | 985 | systemd_launch_instance (client, pair, len); | ||
1055 | 986 | } | ||
1056 | 846 | } | 987 | } |
1057 | 847 | 988 | ||
1058 | === modified file 'extra/upstart-udev-bridge.c' | |||
1059 | --- extra/upstart-udev-bridge.c 2013-10-18 15:02:34 +0000 | |||
1060 | +++ extra/upstart-udev-bridge.c 2015-01-17 15:39:44 +0000 | |||
1061 | @@ -69,6 +69,15 @@ | |||
1062 | 69 | static NihDBusProxy *upstart = NULL; | 69 | static NihDBusProxy *upstart = NULL; |
1063 | 70 | 70 | ||
1064 | 71 | /** | 71 | /** |
1065 | 72 | * user: | ||
1066 | 73 | * | ||
1067 | 74 | * If TRUE, run in User Session mode connecting to the Session Init | ||
1068 | 75 | * rather than PID 1. In this mode, certain relative paths are also | ||
1069 | 76 | * expanded. | ||
1070 | 77 | **/ | ||
1071 | 78 | static int user = FALSE; | ||
1072 | 79 | |||
1073 | 80 | /** | ||
1074 | 72 | * no_strip_udev_data: | 81 | * no_strip_udev_data: |
1075 | 73 | * | 82 | * |
1076 | 74 | * If TRUE, do not modify any udev message data (old behaviour). | 83 | * If TRUE, do not modify any udev message data (old behaviour). |
1077 | @@ -86,6 +95,8 @@ | |||
1078 | 86 | NULL, NULL, &daemonise, NULL }, | 95 | NULL, NULL, &daemonise, NULL }, |
1079 | 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"), |
1080 | 88 | NULL, NULL, &no_strip_udev_data, NULL }, | 97 | NULL, NULL, &no_strip_udev_data, NULL }, |
1081 | 98 | { 0, "user", N_("Connect to user session"), | ||
1082 | 99 | NULL, NULL, &user, NULL }, | ||
1083 | 89 | 100 | ||
1084 | 90 | NIH_OPTION_LAST | 101 | NIH_OPTION_LAST |
1085 | 91 | }; | 102 | }; |
1086 | @@ -97,6 +108,11 @@ | |||
1087 | 97 | { | 108 | { |
1088 | 98 | char ** args; | 109 | char ** args; |
1089 | 99 | DBusConnection * connection; | 110 | DBusConnection * connection; |
1090 | 111 | char * pidfile_path = NULL; | ||
1091 | 112 | char * pidfile = NULL; | ||
1092 | 113 | char *user_session_addr = NULL; | ||
1093 | 114 | nih_local char ** user_session_path = NULL; | ||
1094 | 115 | char * path_element = NULL; | ||
1095 | 100 | struct udev * udev; | 116 | struct udev * udev; |
1096 | 101 | struct udev_monitor *udev_monitor; | 117 | struct udev_monitor *udev_monitor; |
1097 | 102 | int ret; | 118 | int ret; |
1098 | @@ -113,8 +129,19 @@ | |||
1099 | 113 | if (! args) | 129 | if (! args) |
1100 | 114 | exit (1); | 130 | exit (1); |
1101 | 115 | 131 | ||
1102 | 132 | if (user) { | ||
1103 | 133 | user_session_addr = getenv ("UPSTART_SESSION"); | ||
1104 | 134 | if (! user_session_addr) { | ||
1105 | 135 | nih_fatal (_("UPSTART_SESSION isn't set in environment")); | ||
1106 | 136 | exit (EXIT_FAILURE); | ||
1107 | 137 | } | ||
1108 | 138 | } | ||
1109 | 139 | |||
1110 | 116 | /* Initialise the connection to Upstart */ | 140 | /* Initialise the connection to Upstart */ |
1112 | 117 | connection = NIH_SHOULD (nih_dbus_connect (DBUS_ADDRESS_UPSTART, upstart_disconnected)); | 141 | connection = NIH_SHOULD (nih_dbus_connect (user |
1113 | 142 | ? user_session_addr | ||
1114 | 143 | : DBUS_ADDRESS_UPSTART, | ||
1115 | 144 | upstart_disconnected)); | ||
1116 | 118 | if (! connection) { | 145 | if (! connection) { |
1117 | 119 | NihError *err; | 146 | NihError *err; |
1118 | 120 | 147 | ||
1119 | @@ -153,6 +180,35 @@ | |||
1120 | 153 | 180 | ||
1121 | 154 | /* Become daemon */ | 181 | /* Become daemon */ |
1122 | 155 | if (daemonise) { | 182 | if (daemonise) { |
1123 | 183 | /* Deal with the pidfile location when becoming a daemon. | ||
1124 | 184 | * We need to be able to run one bridge per upstart daemon. | ||
1125 | 185 | * Store the PID file in XDG_RUNTIME_DIR or HOME and include the pid of | ||
1126 | 186 | * the Upstart instance (last part of the DBus path) in the filename. | ||
1127 | 187 | */ | ||
1128 | 188 | |||
1129 | 189 | if (user) { | ||
1130 | 190 | /* Extract PID from UPSTART_SESSION */ | ||
1131 | 191 | user_session_path = nih_str_split (NULL, user_session_addr, "/", TRUE); | ||
1132 | 192 | |||
1133 | 193 | for (int i = 0; user_session_path && user_session_path[i]; i++) | ||
1134 | 194 | path_element = user_session_path[i]; | ||
1135 | 195 | |||
1136 | 196 | if (! path_element) { | ||
1137 | 197 | nih_fatal (_("Invalid value for UPSTART_SESSION")); | ||
1138 | 198 | exit (1); | ||
1139 | 199 | } | ||
1140 | 200 | |||
1141 | 201 | pidfile_path = getenv ("XDG_RUNTIME_DIR"); | ||
1142 | 202 | if (!pidfile_path) | ||
1143 | 203 | pidfile_path = getenv ("HOME"); | ||
1144 | 204 | |||
1145 | 205 | if (pidfile_path) { | ||
1146 | 206 | NIH_MUST (nih_strcat_sprintf (&pidfile, NULL, "%s/%s.%s.pid", | ||
1147 | 207 | pidfile_path, program_invocation_short_name, path_element)); | ||
1148 | 208 | nih_main_set_pidfile (pidfile); | ||
1149 | 209 | } | ||
1150 | 210 | } | ||
1151 | 211 | |||
1152 | 156 | if (nih_main_daemonise () < 0) { | 212 | if (nih_main_daemonise () < 0) { |
1153 | 157 | NihError *err; | 213 | NihError *err; |
1154 | 158 | 214 | ||
1155 | @@ -163,10 +219,12 @@ | |||
1156 | 163 | 219 | ||
1157 | 164 | exit (1); | 220 | exit (1); |
1158 | 165 | } | 221 | } |
1163 | 166 | 222 | ||
1164 | 167 | /* Send all logging output to syslog */ | 223 | if (!user) { |
1165 | 168 | openlog (program_name, LOG_PID, LOG_DAEMON); | 224 | /* Send all logging output to syslog for system bridge */ |
1166 | 169 | nih_log_set_logger (nih_logger_syslog); | 225 | openlog (program_name, LOG_PID, LOG_DAEMON); |
1167 | 226 | nih_log_set_logger (nih_logger_syslog); | ||
1168 | 227 | } | ||
1169 | 170 | } | 228 | } |
1170 | 171 | 229 | ||
1171 | 172 | /* Handle TERM and INT signals gracefully */ | 230 | /* Handle TERM and INT signals gracefully */ |
1172 | 173 | 231 | ||
1173 | === modified file 'util/telinit.c' | |||
1174 | --- util/telinit.c 2014-03-10 13:43:50 +0000 | |||
1175 | +++ util/telinit.c 2015-01-17 15:39:44 +0000 | |||
1176 | @@ -160,27 +160,73 @@ | |||
1177 | 160 | int | 160 | int |
1178 | 161 | restart_upstart (void) | 161 | restart_upstart (void) |
1179 | 162 | { | 162 | { |
1182 | 163 | nih_local NihDBusProxy *upstart = NULL; | 163 | nih_local NihDBusProxy *upstart = NULL; |
1183 | 164 | DBusPendingCall *ret; | 164 | NihError *err; |
1184 | 165 | int ret; | ||
1185 | 165 | 166 | ||
1186 | 166 | upstart = upstart_open (NULL); | 167 | upstart = upstart_open (NULL); |
1187 | 167 | if (! upstart) | 168 | if (! upstart) |
1188 | 168 | return -1; | 169 | return -1; |
1189 | 169 | 170 | ||
1204 | 170 | /* Fire and forget: | 171 | /* Ask Upstart to restart itself. |
1205 | 171 | * | 172 | * |
1206 | 172 | * Ask Upstart to restart itself using the async interface to | 173 | * Since it is not possible to serialise a D-Bus connection, |
1207 | 173 | * avoid the client-side complaining if and when it detects that | 174 | * Upstart is forced to sever all D-Bus client connections, |
1208 | 174 | * Upstart has severed all connections to perform the re-exec. | 175 | * including this one. |
1209 | 175 | */ | 176 | * |
1210 | 176 | ret = upstart_restart (upstart, NULL, NULL, NULL, 0); | 177 | * Further, since the user expects telinit to block _until the |
1211 | 177 | dbus_connection_flush(upstart->connection); | 178 | * re-exec has finished and Upstart is accepting connections |
1212 | 178 | 179 | * once again_, the only solution is to wait for the forced | |
1213 | 179 | /* We don't care about the return code, but we have to keep | 180 | * disconnect, then poll until it is possible to create a new |
1214 | 180 | * the compiler happy. | 181 | * connection. |
1215 | 181 | */ | 182 | * |
1216 | 182 | if (ret != (DBusPendingCall *)TRUE) | 183 | * Note that we don't (can't) care about the return code since |
1217 | 183 | return 0; | 184 | * it's not reliable: |
1218 | 185 | * | ||
1219 | 186 | * - either the re-exec request completed and D-Bus returned zero | ||
1220 | 187 | * before Upstart started the re-exec. | ||
1221 | 188 | * | ||
1222 | 189 | * - or the re-exec request completed but upstart started the | ||
1223 | 190 | * re-exec (severing all D-Bus connections) before D-Bus got a | ||
1224 | 191 | * chance to finish cleanly meaning we receive a return of -1. | ||
1225 | 192 | * | ||
1226 | 193 | * We cannot know exactly what happened so have to allow for | ||
1227 | 194 | * both scenarios. Note the implicit assumption that the re-exec | ||
1228 | 195 | * request itself was accepted. If this assumption is incorrect | ||
1229 | 196 | * (should not be possible), the worst case scenario is that | ||
1230 | 197 | * upstart does not re-exec and then we quickly drop out of the | ||
1231 | 198 | * reconnect block since it never went offline. | ||
1232 | 199 | */ | ||
1233 | 200 | ret = upstart_restart_sync (NULL, upstart); | ||
1234 | 201 | |||
1235 | 202 | if (ret < 0) { | ||
1236 | 203 | err = nih_error_get (); | ||
1237 | 204 | nih_free (err); | ||
1238 | 205 | } | ||
1239 | 206 | |||
1240 | 207 | nih_free (upstart); | ||
1241 | 208 | |||
1242 | 209 | nih_debug ("Waiting for upstart to finish re-exec"); | ||
1243 | 210 | |||
1244 | 211 | /* We believe Upstart is now in the process of | ||
1245 | 212 | * re-exec'ing so attempt forever to reconnect. | ||
1246 | 213 | * | ||
1247 | 214 | * This sounds dangerous but there is no other option, | ||
1248 | 215 | * and a connection must be possible unless the system | ||
1249 | 216 | * is completely broken. | ||
1250 | 217 | */ | ||
1251 | 218 | while (TRUE) { | ||
1252 | 219 | |||
1253 | 220 | upstart = upstart_open (NULL); | ||
1254 | 221 | if (upstart) | ||
1255 | 222 | break; | ||
1256 | 223 | |||
1257 | 224 | err = nih_error_get (); | ||
1258 | 225 | nih_free (err); | ||
1259 | 226 | |||
1260 | 227 | /* Avoid DoS'ing the system whilst we wait */ | ||
1261 | 228 | usleep (100000); | ||
1262 | 229 | } | ||
1263 | 184 | 230 | ||
1264 | 185 | return 0; | 231 | return 0; |
1265 | 186 | } | 232 | } |
This merge proposal is in SILO 01