Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation: Issue with systemd notification using RHEL Ruby SCL #3086

Open
FabriceSalvaire opened this issue Feb 22, 2023 · 0 comments
Open

Comments

@FabriceSalvaire
Copy link

RHEL Ruby SCL uses a tool scl to fork puma with the right environments.

Unfortunately, it messes the PID for systemd to get the notification.

scl[21764]: Puma starting in single mode...
scl[21764]: * Puma version: 6.1.0 (ruby 3.0.2-p107) ("The Way Up")
scl[21764]: *  Min threads: 0
scl[21764]: *  Max threads: 5
scl[21764]: *  Environment: production
scl[21764]: *          PID: 21768
scl[21764]: * Listening on http://0.0.0.0:3000
scl[21764]: Use Ctrl-C to stop
systemd[1]: Got notification message from PID 21768, but reception only permitted for main PID 21764
... repeated

Thus, the unit hangs and fails.

A workaround seems to use NotifyAccess=all with Type=notify (instead of Type=simple).

Then it starts:

22231 ?        Ss     0:00 /usr/bin/scl enable rh-ruby30 puma -e production -b tcp://0.0.0.0:3000
22235 ?        Sl     0:04 puma 6.1.0 (tcp://0.0.0.0:3000) [redmine-5.0.4]

Notice other RHEL SCL daemons like MariaDB works. Why ???

See also systemd.service man page:

NotifyAccess=

Controls access to the service status notification socket, as accessible via the sd_notify(3) call. Takes one of none (the default), main, exec or all. If none, no daemon status updates are accepted from the service processes, all status update messages are ignored. If main, only service updates sent from the main process of the service are accepted. If exec, only service updates sent from any of the main or control processes originating from one of the Exec*= commands are accepted. If all, all services updates from all members of the service's control group are accepted. This option should be set to open access to the notification socket when using Type=notify/Type=notify-reload or WatchdogSec= (see above). If those options are used but NotifyAccess= is not configured, it will be implicitly set to main.

Note that sd_notify() notifications may be attributed to units correctly only if either the sending process is still around at the time PID 1 processes the message, or if the sending process is explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally forked off the process, i.e. on all processes that match main or exec. 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=all 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants