From 5ec7a9947edd3dadc3546f02273e9b5a4e67c125 Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Tue, 28 Apr 2020 19:09:53 +0530 Subject: [PATCH] man: sd_notify() race is gone with sd_notify_barrier() Add note for change of behaviour in systemd-notify, where parent pid trick is only used when --no-block is passed, and with enough privileges ofcourse. Also, fix a small error in systemd(1). --- man/systemd-notify.xml | 33 ++++++++++++++++++++++++--------- man/systemd.service.xml | 9 ++++++++- man/systemd.xml | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml index 4560074505020..6d583003baca6 100644 --- a/man/systemd-notify.xml +++ b/man/systemd-notify.xml @@ -54,15 +54,19 @@ off the process, i.e. on all processes that match NotifyAccess= or NotifyAccess=. Conversely, if an auxiliary process of the unit sends an sd_notify() message and immediately exits, the service manager might not be able to properly - attribute the message to the unit, and thus will ignore it, even if - NotifyAccess= is set for it. - - systemd-notify will first attempt to invoke sd_notify() pretending to - have the PID of the invoking process. This will only succeed when invoked with sufficient privileges. On failure, - it will then fall back to invoking it under its own PID. This behaviour is useful in order that when the tool is - invoked from a shell script the shell process — and not the systemd-notify process — appears as - sender of the message, which in turn is helpful if the shell process is the main process of a service, due to the - limitations of NotifyAccess= described above. + attribute the message to the unit, and thus will ignore it, even if NotifyAccess= is set for it. When is used, all synchronization for reception of notifications + is disabled, and hence the aforementioned race may occur if the invoking process is not the service manager or spawned + by the service manager. + + Hence, systemd-notify will first attempt to invoke sd_notify() + pretending to have the PID of the invoking process. This will only succeed when invoked with sufficient privileges. + On failure, it will then fall back to invoking it under its own PID. This behaviour is useful in order that when + the tool is invoked from a shell script the shell process — and not the systemd-notify process + — appears as sender of the message, which in turn is helpful if the shell process is the main process of a service, + due to the limitations of NotifyAccess=. Use the + switch to tweak this behaviour. + @@ -129,6 +133,17 @@ with systemd. + + + + Do not synchronously wait for the requested operation to finish. + Use of this option is only recommended when systemd-notify + is spawned by the service manager, or when the invoking process is directly spawned + by the service manager and has enough privileges to allow systemd-notify + to send the notification on its behalf. Sending notifications with + this option set is prone to race conditions in all other cases. + + diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 398fd69b46979..bba867f79914c 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -959,7 +959,14 @@ . Conversely, if an auxiliary process of the unit sends an sd_notify() message and immediately exits, the service manager might not be able to properly attribute the message to the unit, and thus will ignore it, even if - NotifyAccess= is set for it. + NotifyAccess= is set for it. + + Hence, to eliminate all race conditions involving lookup of the client's unit and attribution of notifications + to units correctly, sd_notify_barrier() may be used. This call acts as a synchronization point + and ensures all notifications sent before this call have been picked up by the service manager when it returns + successfully. Use of sd_notify_barrier() is needed for clients which are not invoked by the + service manager, otherwise this synchronization mechanism is unnecessary for attribution of notifications to the + unit. diff --git a/man/systemd.xml b/man/systemd.xml index 1534027d927b1..4e08ff6254466 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -257,7 +257,7 @@ execution compared to the target unit's state and is marked successful and complete when both satisfy. However, this job also pulls in other dependencies due to the defined relationships and thus leads to, in our - our example, start jobs for any of those inactive units getting queued as + example, start jobs for any of those inactive units getting queued as well. systemd contains native implementations of various tasks