Skip to content

Commit 36e790e

Browse files
clumensnrwahl2
authored andcommitted
Refactor: libcrmservice: Subscribe to systemd D-Bus signals
We'll add a filter later. This does not meaningfully change behavior. Ref T25 Signed-off-by: Reid Wahl <[email protected]>
1 parent 9e51527 commit 36e790e

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

lib/services/systemd.c

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
static void invoke_unit_by_path(svc_action_t *op, const char *unit);
2626

27+
/* Systemd D-Bus interface
28+
* https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html
29+
*/
2730
#define BUS_NAME "org.freedesktop.systemd1"
2831
#define BUS_NAME_MANAGER BUS_NAME ".Manager"
2932
#define BUS_NAME_UNIT BUS_NAME ".Unit"
@@ -136,6 +139,50 @@ systemd_call_simple_method(const char *method)
136139
return reply;
137140
}
138141

142+
/*!
143+
* \internal
144+
* \brief Subscribe to D-Bus signals from systemd
145+
*
146+
* Systemd does not broadcast signal messages unless at least one client has
147+
* called the \c Subscribe() method. Also, a D-Bus client ignores broadcast
148+
* messages unless an appropriate match rule is set, so we set one here.
149+
*
150+
* \return Standard Pacemaker return code
151+
*/
152+
static int
153+
subscribe_to_signals(void)
154+
{
155+
const char *match_rule = "type='signal',"
156+
"sender='" BUS_NAME "',"
157+
"interface='" BUS_NAME_MANAGER "',"
158+
"path='" BUS_PATH "'";
159+
DBusMessage *reply = NULL;
160+
DBusError error;
161+
162+
/* Tell D-Bus to accept signal messages from systemd.
163+
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
164+
*/
165+
dbus_error_init(&error);
166+
dbus_bus_add_match(systemd_proxy, match_rule, &error);
167+
168+
if (dbus_error_is_set(&error)) {
169+
crm_err("Could not listen for systemd DBus signals: %s " QB_XS " (%s)",
170+
error.message, error.name);
171+
dbus_error_free(&error);
172+
return ECOMM;
173+
}
174+
175+
// Tell systemd to broadcast signals
176+
reply = systemd_call_simple_method("Subscribe");
177+
if (reply == NULL) {
178+
dbus_bus_remove_match(systemd_proxy, match_rule, &error);
179+
return ECOMM;
180+
}
181+
182+
dbus_message_unref(reply);
183+
return pcmk_rc_ok;
184+
}
185+
139186
static bool
140187
systemd_init(void)
141188
{
@@ -153,11 +200,14 @@ systemd_init(void)
153200
if (need_init) {
154201
need_init = 0;
155202
systemd_proxy = pcmk_dbus_connect();
203+
204+
if (subscribe_to_signals() != pcmk_rc_ok) {
205+
pcmk_dbus_disconnect(systemd_proxy);
206+
systemd_proxy = NULL;
207+
}
156208
}
157-
if (systemd_proxy == NULL) {
158-
return false;
159-
}
160-
return true;
209+
210+
return (systemd_proxy != NULL);
161211
}
162212

163213
static inline char *

0 commit comments

Comments
 (0)