Re: [systemd-devel] sd-bus: serving method call message in a separate thread

2019-03-04 Thread Giacinto Cifelli
Hi Stanislav,

On Mon, Mar 4, 2019 at 9:56 PM Stanislav Angelovič
 wrote:
>
> Hi sd-bus-ers!
>
> Quick question: How can I process a method call on service side in a 
> different thread, without creating race condition?
>
> Longer version:
>
> In sdbus-c++, we are working on server-side asynchronous method call support.
>
> In sd-bus, a service handles D-Bus method calls via sd_bus_message_handler_t 
> callback that is registered during object vtable registration. The callback 
> receives sd_bus_message* as the first parameter (among others), which is the 
> method call message. In a typical implementation, this method call is served 
> synchronously (D-Bus method parameters are deserialized from the message, an 
> operation is executed, and either method reply or method error, depending on 
> the condition, is sent back) and the callback returns execution to sd-bus. 
> Standard stuff so far.
>
> Now, I would like to handle the method call asynchronously, in a thread pool. 
> So a typical approach would be to increment ref count of sd_bus_message and 
> push the sd_bus_message* in a queue. It would then be popped by one of worker 
> threads and processed -- method parameters are deserialized, method logic is 
> executed, and either method reply or method error is created and sent back, 
> and sd_bus_message* ref count is decremented. Now, sending back the reply or 
> an error is thread-safe in my implementation, I don't have an issue with 
> that. The problem that I want to discuss is the method call sd_bus_message 
> instance. I cannot simply forward a pointer to it to a separate thread, 
> because of it's non-atomic ref count handling, which is the source of race 
> condition (hopefully this is the only data race condition here). It's 
> manipulated by both the D-Bus loop thread (which decrements ref count after 
> sd_bus_message_handler_t returns) and the worker thread concurrently (which 
> also decrements ref count after it has handled the method call).
>
> I see three potential solutions now:
>
> 1. In sd_bus_message_handler, create a deep copy of the method call 
> sd_bus_message via sd_bus_message_copy(). And pass a pointer to this copy to 
> a worker thread. This is very straight-forward and simple, it solves the race 
> condition, but introduces a performance cost of copying (I don't know how big 
> this cost is, perhaps it's rather negligible).
>
> 2.  Don't pass the sd_bus_message* to the worker thread. In 
> sd_bus_message_handler, rather deserialize all arguments, create (empty) 
> method reply message, and move these to the worker thread. The worker thread 
> executes the logic and serializes results to that reply message, and sends it 
> back. The problem here is that we have to create a method reply or method 
> error before the fact (before executing method logic), which in case of 
> method error is impossible because we don't know possible error name and 
> message beforehand.
>
> 3. Solution on sd-bus side :-) which is to make sd_bus_message ref count 
> handling thread-safe (atomic), just like one for sd_bus. This avoids the need 
> for deep copy. What do you think? Anyway, we'd still have to come up with a 
> solution now, based on already releases sd-bus versions.
>
> So the only feasible solution for now seems to be #1 (while #3 could also be 
> a sd-bus improvement for the future). Do you agree that this is the good way 
> along the lines of sd-bus design principles, or are there more options I'm 
> unaware of?
>

In my use of sdbus I am going for option 3. Also because I am not sure
what happens when sdbus writes on the bus in parallel two long
messages. I know that sdbus is thread aware, but not thread safe.
So 2 long messages could in theory be sent in collision. Maybe you can
verify this opening two (or more) instances of a client that query
automatically all introspectable methods of a specific server
implemented with your thread pool, and see what happens in repeated
trials.

> Thank you for your constructive comments, and sorry for long elaboration :) I 
> wanted to be clear...
>
> Cheers,
> Stanislav.
>

Cheers,
Giaciinto


> ___
> systemd-devel mailing list
> systemd-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

[systemd-devel] sd-bus: serving method call message in a separate thread

2019-03-04 Thread Stanislav Angelovič
Hi sd-bus-ers!

Quick question: How can I process a method call on service side in a
different thread, without creating race condition?

Longer version:

In sdbus-c++, we are working on server-side asynchronous method call
support.

In sd-bus, a service handles D-Bus method calls via
sd_bus_message_handler_t callback that is registered during object vtable
registration. The callback receives sd_bus_message* as the first parameter
(among others), which is the method call message. In a typical
implementation, this method call is served synchronously (D-Bus method
parameters are deserialized from the message, an operation is executed, and
either method reply or method error, depending on the condition, is sent
back) and the callback returns execution to sd-bus. Standard stuff so far.

Now, I would like to handle the method call asynchronously, in a thread
pool. So a typical approach would be to increment ref count of
sd_bus_message and push the sd_bus_message* in a queue. It would then be
popped by one of worker threads and processed -- method parameters are
deserialized, method logic is executed, and either method reply or method
error is created and sent back, and sd_bus_message* ref count is
decremented. Now, sending back the reply or an error is thread-safe in my
implementation, I don't have an issue with that. The problem that I want to
discuss is the method call sd_bus_message instance. I cannot simply forward
a pointer to it to a separate thread, because of it's non-atomic ref count
handling, which is the source of race condition (hopefully this is the only
data race condition here). It's manipulated by both the D-Bus loop thread
(which decrements ref count after sd_bus_message_handler_t returns) and the
worker thread concurrently (which also decrements ref count after it has
handled the method call).

I see three potential solutions now:

1. In sd_bus_message_handler, create a deep copy of the method call
sd_bus_message via sd_bus_message_copy(). And pass a pointer to this copy
to a worker thread. This is very straight-forward and simple, it solves the
race condition, but introduces a performance cost of copying (I don't know
how big this cost is, perhaps it's rather negligible).

2.  Don't pass the sd_bus_message* to the worker thread. In
sd_bus_message_handler, rather deserialize all arguments, create (empty)
method reply message, and move these to the worker thread. The worker
thread executes the logic and serializes results to that reply message, and
sends it back. The problem here is that we have to create a method reply or
method error before the fact (before executing method logic), which in case
of method error is impossible because we don't know possible error name and
message beforehand.

3. Solution on sd-bus side :-) which is to make sd_bus_message ref count
handling thread-safe (atomic), just like one for sd_bus. This avoids the
need for deep copy. What do you think? Anyway, we'd still have to come up
with a solution now, based on already releases sd-bus versions.

So the only feasible solution for now seems to be #1 (while #3 could also
be a sd-bus improvement for the future). Do you agree that this is the good
way along the lines of sd-bus design principles, or are there more options
I'm unaware of?

Thank you for your constructive comments, and sorry for long elaboration :)
I wanted to be clear...

Cheers,
Stanislav.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Re: [systemd-devel] OnCalendar timer starts before the scheduled date has passed

2019-03-04 Thread Alden Page
You're right, I misunderstood the purpose the the Requires directive.
Thanks for pointing this out, I am seeing the expected behavior in my
script after removing it.

Alden

On Mon, Mar 4, 2019 at 1:43 PM Andrei Borzenkov  wrote:

> 04.03.2019 21:19, Alden Page пишет:
> > Hi systemd team,
> >
> > I'm having some trouble understanding the behavior of a systemd timer
> I've
> > set up in systemd version 219. I have a task that I want to run once per
> > week on Sundays at 3:00am UTC. However, as soon as I do `systemctl start
> > my_timer.timer`, the task starts no matter what time it is. This is a
>
> That is what you told it to do.
>
> > problem for me, because that means that my timer starts every single
> time I
> > recreate my server's virtual machine. After the initial erroneously
> > scheduled job has completed successfully, the timer starts behaving
> > correctly and runs on Sundays at 3:00am UTC.
> >
> > Here is how I've set up my timers. This is an excerpt from the script I
> use
> > to bootstrap my VMs:
> >
> > # Schedule weekly ingest of new data
> > cat << EOF > /etc/systemd/system/ingest_upstream.service
> > [Unit]
> > Description=Load and index image data from upstream.
> > [Service]
> > ExecStart=/usr/bin/curl -XPOST localhost:8001/task -H "Content-Type:
> > application/json" -d '{"model": "image", "action": "INGEST_UPSTREAM"}'
> > EOF
> >
> > cat << EOF > /etc/systemd/system/ingest_upstream.timer
> > [Unit]
> > Description=Ingest data from upstream every Sunday at 8:00am EST (3:00am
> > UTC).
> > Requires=ingest_upstream.service
> >
>
> Requires means - when ingest_upstream.timer is started (activated) also
> start (activate) units listed here. Which is exactly what happens.
>
> > [Timer]
> > OnCalendar=Sun *-*-* 3:00:00
> > Unit=ingest_upstream.service
> >
> > [Install]
> > WantedBy=timers.target
> > EOF
> > systemctl start ingest_upstream.timer
> >
> > After `systemctl start`, shouldn't it wait until the next OnCalendar
> > interval has passed, particularly since `Persistent=...` is not set?
> >
>
> It (presumably ingest_upstream.timer) does wait; your service is not
> activated by timer but by basic systemd unit dependency.
> ___
> systemd-devel mailing list
> systemd-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Re: [systemd-devel] OnCalendar timer starts before the scheduled date has passed

2019-03-04 Thread Andrei Borzenkov
04.03.2019 21:19, Alden Page пишет:
> Hi systemd team,
> 
> I'm having some trouble understanding the behavior of a systemd timer I've
> set up in systemd version 219. I have a task that I want to run once per
> week on Sundays at 3:00am UTC. However, as soon as I do `systemctl start
> my_timer.timer`, the task starts no matter what time it is. This is a

That is what you told it to do.

> problem for me, because that means that my timer starts every single time I
> recreate my server's virtual machine. After the initial erroneously
> scheduled job has completed successfully, the timer starts behaving
> correctly and runs on Sundays at 3:00am UTC.
> 
> Here is how I've set up my timers. This is an excerpt from the script I use
> to bootstrap my VMs:
> 
> # Schedule weekly ingest of new data
> cat << EOF > /etc/systemd/system/ingest_upstream.service
> [Unit]
> Description=Load and index image data from upstream.
> [Service]
> ExecStart=/usr/bin/curl -XPOST localhost:8001/task -H "Content-Type:
> application/json" -d '{"model": "image", "action": "INGEST_UPSTREAM"}'
> EOF
> 
> cat << EOF > /etc/systemd/system/ingest_upstream.timer
> [Unit]
> Description=Ingest data from upstream every Sunday at 8:00am EST (3:00am
> UTC).
> Requires=ingest_upstream.service
> 

Requires means - when ingest_upstream.timer is started (activated) also
start (activate) units listed here. Which is exactly what happens.

> [Timer]
> OnCalendar=Sun *-*-* 3:00:00
> Unit=ingest_upstream.service
> 
> [Install]
> WantedBy=timers.target
> EOF
> systemctl start ingest_upstream.timer
> 
> After `systemctl start`, shouldn't it wait until the next OnCalendar
> interval has passed, particularly since `Persistent=...` is not set?
> 

It (presumably ingest_upstream.timer) does wait; your service is not
activated by timer but by basic systemd unit dependency.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

[systemd-devel] OnCalendar timer starts before the scheduled date has passed

2019-03-04 Thread Alden Page
Hi systemd team,

I'm having some trouble understanding the behavior of a systemd timer I've
set up in systemd version 219. I have a task that I want to run once per
week on Sundays at 3:00am UTC. However, as soon as I do `systemctl start
my_timer.timer`, the task starts no matter what time it is. This is a
problem for me, because that means that my timer starts every single time I
recreate my server's virtual machine. After the initial erroneously
scheduled job has completed successfully, the timer starts behaving
correctly and runs on Sundays at 3:00am UTC.

Here is how I've set up my timers. This is an excerpt from the script I use
to bootstrap my VMs:

# Schedule weekly ingest of new data
cat << EOF > /etc/systemd/system/ingest_upstream.service
[Unit]
Description=Load and index image data from upstream.
[Service]
ExecStart=/usr/bin/curl -XPOST localhost:8001/task -H "Content-Type:
application/json" -d '{"model": "image", "action": "INGEST_UPSTREAM"}'
EOF

cat << EOF > /etc/systemd/system/ingest_upstream.timer
[Unit]
Description=Ingest data from upstream every Sunday at 8:00am EST (3:00am
UTC).
Requires=ingest_upstream.service

[Timer]
OnCalendar=Sun *-*-* 3:00:00
Unit=ingest_upstream.service

[Install]
WantedBy=timers.target
EOF
systemctl start ingest_upstream.timer

After `systemctl start`, shouldn't it wait until the next OnCalendar
interval has passed, particularly since `Persistent=...` is not set?

Thanks,
Alden
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Re: [systemd-devel] what does it mean to have exit-code of 251

2019-03-04 Thread prashantkumar dhotre
Thanks.
It seems like that call to zookeeper lib API is causing this exit with 251
and hence it is most likely in zookeeper lib code.
Regards


On Mon, Mar 4, 2019 at 5:26 PM Lennart Poettering 
wrote:

> On Mo, 04.03.19 16:58, prashantkumar dhotre (prashantkumardho...@gmail.com)
> wrote:
>
> > Hi,
> >
> > In my journal log, I see ;
> >
> > 1199473 Mar 01 15:46:03 evo-qfx-01 systemd[1]: ifmand.service: Main
> process
> > exited, code=exited, status=251/n/a
> >
> >
> > I want to know what does 251 means.
> >
> > Can you  please  let me know where can I see the exit-code to meaning
> mapping
>
> This depends on the program you are invoking as a service. i.e. ask
> the folks who wrote "ifmand" about this, or consult the documentation
> for that program.
>
> When systemd cannot invoke a program you configured it will generate a
> couple of error codes on its own. These are documented here:
>
>
> https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Process%20exit%20codes
>
> But as you can see there 251 is none of the exit codes systemd itself
> defines, hence it must come from your own app.
>
> Lennart
>
> --
> Lennart Poettering, Red Hat
>
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Re: [systemd-devel] what does it mean to have exit-code of 251

2019-03-04 Thread Lennart Poettering
On Mo, 04.03.19 16:58, prashantkumar dhotre (prashantkumardho...@gmail.com) 
wrote:

> Hi,
>
> In my journal log, I see ;
>
> 1199473 Mar 01 15:46:03 evo-qfx-01 systemd[1]: ifmand.service: Main process
> exited, code=exited, status=251/n/a
>
>
> I want to know what does 251 means.
>
> Can you  please  let me know where can I see the exit-code to meaning mapping

This depends on the program you are invoking as a service. i.e. ask
the folks who wrote "ifmand" about this, or consult the documentation
for that program.

When systemd cannot invoke a program you configured it will generate a
couple of error codes on its own. These are documented here:

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Process%20exit%20codes

But as you can see there 251 is none of the exit codes systemd itself
defines, hence it must come from your own app.

Lennart

--
Lennart Poettering, Red Hat
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Re: [systemd-devel] what does it mean to have exit-code of 251

2019-03-04 Thread prashantkumar dhotre
In my app, I don't explicitly call exit(251).
I use zookeeper lib.
Fro my logs,I see that after a call to zookeeper lib API, I see that my
service exited with 251.
Is 251 a std exit code or app/lib specific custom exit code ?
Thanks



On Mon, Mar 4, 2019 at 5:02 PM Umut Tezduyar Lindskog 
wrote:

> You need to do some bit analysis - https://shapeshed.com/unix-exit-codes/
>
> On Mon, Mar 4, 2019 at 12:29 PM prashantkumar dhotre
>  wrote:
> >
> > Hi,
> >
> > In my journal log, I see ;
> >
> > 1199473 Mar 01 15:46:03 evo-qfx-01 systemd[1]: ifmand.service: Main
> process exited, code=exited, status=251/n/a
> >
> >
> > I want to know what does 251 means.
> >
> > Can you  please  let me know where can I see the exit-code to meaning
> mapping ?
> >
> > Thanks
> >
> > Prashant
> >
> >
> > ___
> > systemd-devel mailing list
> > systemd-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Re: [systemd-devel] what does it mean to have exit-code of 251

2019-03-04 Thread Umut Tezduyar Lindskog
You need to do some bit analysis - https://shapeshed.com/unix-exit-codes/

On Mon, Mar 4, 2019 at 12:29 PM prashantkumar dhotre
 wrote:
>
> Hi,
>
> In my journal log, I see ;
>
> 1199473 Mar 01 15:46:03 evo-qfx-01 systemd[1]: ifmand.service: Main process 
> exited, code=exited, status=251/n/a
>
>
> I want to know what does 251 means.
>
> Can you  please  let me know where can I see the exit-code to meaning mapping 
> ?
>
> Thanks
>
> Prashant
>
>
> ___
> systemd-devel mailing list
> systemd-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

[systemd-devel] what does it mean to have exit-code of 251

2019-03-04 Thread prashantkumar dhotre
Hi,

In my journal log, I see ;

1199473 Mar 01 15:46:03 evo-qfx-01 systemd[1]: ifmand.service: Main process
exited, code=exited, status=251/n/a


I want to know what does 251 means.

Can you  please  let me know where can I see the exit-code to meaning mapping
?

Thanks

Prashant
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel