2424
2525static  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+ 
139186static  bool 
140187systemd_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
163213static  inline  char  * 
0 commit comments