Discussion:
How to add filter for ActiveState property and get to know for which object this property is?
(too old to reply)
Tomasz Michalski
2018-01-16 14:41:11 UTC
Permalink
Raw Message
Hi
I am in the middle of implementation monitor for getting states from
services. I have some question to my current implementation.
My current implementation is:

void main()
{
.....
r = sd_bus_add_match(&bus,
NULL,
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.DBus.Properties',"
"member='PropertiesChanged',"
"arg0='org.freedesktop.systemd1.Unit'",
propertiesChangedHandler,
NULL); //user data*/
if (r < 0)
{
fprintf(stderr, "Failed to add match for PropertiesChanged",
strerror(-r));
goto finish;
}

r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"Subscribe",
&error,
NULL,
NULL);
if (r < 0)
{
fprintf(stderr, "Failed to enable subscription: %s\n", strerror(-r));
//TO DO use also error code
return r;
}

...
}

Handler:
int propertiesChangedHandler(sd_bus_message *message, void *userdata,
sd_bus_error *error)
{
const char *data;
const char *path;
int r = 0;

if(!message)
printf("Empty message provided\n");

path = sd_bus_message_get_path(message);
if (!path)
{
printf("Empty message provided\n");
return 0;
}

r = sd_bus_message_read(message, "s", &data); //here problem with
parsing ActiveState,SubState
if (r < 0)
{
fprintf(stderr, "Failed to parse response message: %s\n",
strerror(-r));
return 0;
}
}


Question:
How to narrow down filter? In the above examples the handler will be
triggered by any property change. I am only interested in ActiveState,
eventually SubState trigger. Should I add in sd_bus_add_match:
"arg1='ActiveState'",
"arg2='SubState'"
?
Tomasz Michalski
2018-01-16 15:13:38 UTC
Permalink
Raw Message
And I have other question. Generally we wonder what will be better design
for monitoring systemd services
1.)
- add-match to ActiveState
- subscribe to systemd1.Manager
- then we have to start in separate thread some infinitive-loop with
sd_bus_wait()
and sd_bus_process() (*)
2.)
- asking for example each 5s all services with the aid of method
sd_bus_get_property about ActiveState. None additional thread is required
in our case as timer when expires send notification to existed infinity
while loop from current handler.

I wonder which solution occupy more processor. From the first glance it
seems like second one, because there might be too much unnecessary
communication through the bus in order to get to know about systemd service
states.
However take care that here (*) we have to have some infinity while loop
probably in separate thread which will block thread waiting for signals
from systemd. As far as timers are concerned in 2nd solution none
additional thread is required. Is it possible somehow in 1.) not to have
additional thread in order to receive signal from systemd?
Moreover 2nd solution seems to be better in case when systemd1.Manager fail
at all (will be killed). In 2nd solution we will get to know it immediately
as there will be none response on sd_bus_get_property. In 1.) solution we
won't know that, thinking services are in active state.
Thanks in advance for your opinions.


2018-01-16 15:41 GMT+01:00 Tomasz Michalski <***@gmail.com>:

> Hi
> I am in the middle of implementation monitor for getting states from
> services. I have some question to my current implementation.
> My current implementation is:
>
> void main()
> {
> .....
> r = sd_bus_add_match(&bus,
> NULL,
> "type='signal',"
> "sender='org.freedesktop.systemd1',"
> "interface='org.freedesktop.DBus.Properties',"
> "member='PropertiesChanged',"
> "arg0='org.freedesktop.systemd1.Unit'",
> propertiesChangedHandler,
> NULL); //user data*/
> if (r < 0)
> {
> fprintf(stderr, "Failed to add match for PropertiesChanged",
> strerror(-r));
> goto finish;
> }
>
> r = sd_bus_call_method(
> bus,
> "org.freedesktop.systemd1",
> "/org/freedesktop/systemd1",
> "org.freedesktop.systemd1.Manager",
> "Subscribe",
> &error,
> NULL,
> NULL);
> if (r < 0)
> {
> fprintf(stderr, "Failed to enable subscription: %s\n", strerror(-r));
> //TO DO use also error code
> return r;
> }
>
> ...
> }
>
> Handler:
> int propertiesChangedHandler(sd_bus_message *message, void *userdata,
> sd_bus_error *error)
> {
> const char *data;
> const char *path;
> int r = 0;
>
> if(!message)
> printf("Empty message provided\n");
>
> path = sd_bus_message_get_path(message);
> if (!path)
> {
> printf("Empty message provided\n");
> return 0;
> }
>
> r = sd_bus_message_read(message, "s", &data); //here problem with
> parsing ActiveState,SubState
> if (r < 0)
> {
> fprintf(stderr, "Failed to parse response message: %s\n",
> strerror(-r));
> return 0;
> }
> }
>
>
> Question:
> How to narrow down filter? In the above examples the handler will be
> triggered by any property change. I am only interested in ActiveState,
> eventually SubState trigger. Should I add in sd_bus_add_match:
> "arg1='ActiveState'",
> "arg2='SubState'"
> ?
>
>
Lennart Poettering
2018-01-24 11:25:01 UTC
Permalink
Raw Message
On Di, 16.01.18 16:13, Tomasz Michalski (***@gmail.com) wrote:

> And I have other question. Generally we wonder what will be better design
> for monitoring systemd services
> 1.)
> - add-match to ActiveState
> - subscribe to systemd1.Manager
> - then we have to start in separate thread some infinitive-loop with
> sd_bus_wait()
> and sd_bus_process() (*)
> 2.)
> - asking for example each 5s all services with the aid of method
> sd_bus_get_property about ActiveState. None additional thread is required
> in our case as timer when expires send notification to existed infinity
> while loop from current handler.
>
> I wonder which solution occupy more processor. From the first glance it
> seems like second one, because there might be too much unnecessary
> communication through the bus in order to get to know about systemd service
> states.
> However take care that here (*) we have to have some infinity while loop
> probably in separate thread which will block thread waiting for signals
> from systemd. As far as timers are concerned in 2nd solution none
> additional thread is required. Is it possible somehow in 1.) not to have
> additional thread in order to receive signal from systemd?
> Moreover 2nd solution seems to be better in case when systemd1.Manager fail
> at all (will be killed). In 2nd solution we will get to know it immediately
> as there will be none response on sd_bus_get_property. In 1.) solution we
> won't know that, thinking services are in active state.
> Thanks in advance for your opinions.

This of course all matters on how much stuff actually happens on your
system. I generally would suggest watching the PropertiesChanged stuff
with a precise "path" match. But if you have services that change
state all the time, then polling might be better. But I'd not go for
that option unless oyu have hard performance data.

Lennart

--
Lennart Poettering, Red Hat
Lennart Poettering
2018-01-24 11:22:17 UTC
Permalink
Raw Message
On Di, 16.01.18 15:41, Tomasz Michalski (***@gmail.com) wrote:

> Handler:
> int propertiesChangedHandler(sd_bus_message *message, void *userdata,
> sd_bus_error *error)
> {
> const char *data;
> const char *path;
> int r = 0;
>
> if(!message)
> printf("Empty message provided\n");
>
> path = sd_bus_message_get_path(message);
> if (!path)
> {
> printf("Empty message provided\n");
> return 0;
> }
>
> r = sd_bus_message_read(message, "s", &data); //here problem with
> parsing ActiveState,SubState

The PropertiesChanged signal sends a more complex data struct
back. For details see the D-Bus spec:

https://dbus.freedesktop.org/doc/dbus-specification.html

It's a bit nasty to parse that out, but doable.

> Question:
> How to narrow down filter? In the above examples the handler will be
> triggered by any property change. I am only interested in ActiveState,
> eventually SubState trigger. Should I add in sd_bus_add_match:
> "arg1='ActiveState'",
> "arg2='SubState'"
> ?

Unfortunately D-bus does not allow such finegrained matches. You
cannot look inside of arrays or dicts with them.

Lennart

--
Lennart Poettering, Red Hat
Loading...