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

Support fork-free locking notification mechanism #42

Closed
wants to merge 1 commit into from

Conversation

CameronNemo
Copy link
Contributor

This allows for service/task managers to be notified when the lock screen has been displayed. It is particularly useful when locking the screen before closing the lid. The daemonization option can also be used, but then you either lose supervision of the swaylock process or resort to hacks like ptrace or cgroups.

Documentation for READY_FD can be found here.

It is loosely based on s6's service readiness notification mechanism, and compatible with s6.

@ddevault
Copy link
Contributor

ddevault commented Feb 5, 2019

Can you gate this behind a meson option?

@CameronNemo
Copy link
Contributor Author

Yeah sure. Not sure why that would be necessary considering there are no new dependencies but it can't hurt :)

@ddevault
Copy link
Contributor

ddevault commented Feb 5, 2019

I'd just like to see this get more popular among init systems and/or downstream distributions before we start shipping it for everyone.

@CameronNemo
Copy link
Contributor Author

Added the meson option, defaulting to false.

@CameronNemo
Copy link
Contributor Author

How would you feel about a similar option in sway itself, by the way?

@emersion
Copy link
Member

emersion commented Feb 5, 2019

How would you feel about a similar option in sway itself, by the way?

Sway users could just put exec ready in their config file.

main.c Outdated Show resolved Hide resolved

env = getenv("READY_FD");

if (!env || env[0] == '\0') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really needed to have an argument for READY_FD? Can't we just enable it if the env variable is defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could do that. I don't in this case for two reasons:

  1. While I hope this does not happen, the variable could be leaked from a parent process. In such a case the contents are likely invalid or at least not intended to be used by swaylock.

  2. If a user configures their service with an older version of swaylock, the supervisor will be twiddling its thumbs while it waits for a notification that will never come. This would lead to some unexpected (although not particularly nasty) behavior. A flag would make such a misconfiguration glaringly obvious (swaylock: unrecognized option '--readyfd').

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a blocker?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No.

main.c Outdated Show resolved Hide resolved
main.c Outdated Show resolved Hide resolved
@CameronNemo
Copy link
Contributor Author

CameronNemo commented Feb 5, 2019

Regarding sway, that is a good stop gap and I may personally use it in the near term (particularly since I don't expect such changes to be included in the 1.0 cycle). However, it is not ideal because care would have to be taken to ensure that sway does not leak the variable and file descriptor to a significant number of child processes.

Edit: I have found a better solution: don't use a ready fd at all with sway, and just notify the supervisor via other means. Like exec ready as you said, just not ready fd... that way no fd to lose track of.

@CameronNemo
Copy link
Contributor Author

Disappointed that this was not considered for the recent release. Back to patching I guess.

@emersion
Copy link
Member

emersion commented May 4, 2019

I'd really prefer this to be backed by service managers.

@CameronNemo
Copy link
Contributor Author

There are two existing.

@emersion
Copy link
Member

emersion commented May 4, 2019

What are they? I don't consider that s6 supports it (it supports a similar mechanism, but not READY_FD).

Isn't it possible to discuss with service manager maintainers and ask what they think about the spec?

@CameronNemo
Copy link
Contributor Author

CameronNemo commented May 4, 2019

Unfortunately no HTML documentation, but the manpage describes the support for it in startup. Indeed s6 does not support the protocol (it supports a more flexible mechanism... which is why it can wrap READY_FD easily), but it will function with this patch.

Do you know of anyone else who works on service managers? Lennart shared his thoughts about the spec on twitter already. Not particularly interested in interacting with him further on this subject.

@emersion
Copy link
Member

emersion commented May 4, 2019

Lennart shared his thoughts about the spec on twitter already. Not particularly interested in interacting with him further on this subject.

For reference, discussion on Twitter: https://twitter.com/pid_eins/status/1094611367938674688

(Why shouldn't we add support for NOTIFY_SOCKET instead, which is almost the same and is widely used?)

Do you know of anyone else who works on service managers?

https://alternativeto.net/software/systemd/

@CameronNemo
Copy link
Contributor Author

(Why shouldn't we add support for NOTIFY_SOCKET instead, which is almost the same and is widely used?)

You certainly could. It would require linking to libsystemd, which you already optionally do. I have some criticisms of it for other use cases, but it makes some sense here.

@emersion
Copy link
Member

emersion commented May 4, 2019

Makes sense.

Moving forward, I'd be interested in what OpenRC, s6 and runit maintainers think about this. Would it be possible to get in touch and ask their thoughts?

@CameronNemo
Copy link
Contributor Author

CameronNemo commented May 4, 2019

runit maintainer is gone, has been for years. I asked some of the Void members for reviews of the reference implementation. @skarnet stopped by on the cups patch apple/cups#5507. They did not seem to be opposed to the protocol, but then again they did not explicitly comment on the protocol but instead focused on s6 itself.

edit: I think container runtime maintainers are important stakeholders, but I would rather come to them with a patch than some docs and example code.

@CameronNemo
Copy link
Contributor Author

Thanks for the feedback!

@emersion
Copy link
Member

emersion commented May 4, 2019

I think it would be useful to send a message on the s6 mailing list and open an issue on the OpenRC repo to ask if they would be interested in merging a patch adding READY_FD support.

@skarnet
Copy link

skarnet commented May 4, 2019

There is no need to patch s6 for READY_FD support, it will work out of the box. Just have the run script start with env READY_FD=n ... if n is the value contained in the notification-fd file.

I don't know about OpenRC.

@emersion: I very much recommend against supporting NOTIFY_SOCKET. NOTIFY_SOCKET is much more complex (the extra features add nothing of value, those people don't understand YAGNI) and, as the name implies, it forces the notification IPC to be a socket, which favours a centralized architecture such as systemd and is actively hostile to decentralized architectures such as s6. Not making any assumptions on the nature of the file descriptor used for notification is much more flexible and much better.

Note that I provide a wrapper for people who want to use the s6 notification mechanism under systemd; whereas to my knowledge, systemd doesn't provide anything for people who want to use the NOTIFY_SOCKET mechanism under s6. So, supporting the s6 mechanism (or READY_FD, which is almost equivalent) is more generic and can still work with systemd.

@emersion
Copy link
Member

emersion commented May 4, 2019

There is no need to patch s6 for READY_FD support, it will work out of the box. Just have the run script start with env READY_FD=n ... if n is the value contained in the notification-fd file.

Is there a reason why it doesn't work out-of-the-box?

@CameronNemo
Copy link
Contributor Author

CameronNemo commented May 4, 2019

Probably because I came later, and allowing the service to dictate the fd number requires less work for the service. (No parsing env variables needed, just write to 3 or whatever). Basically it is a trade off between flexibility on the service manager side and simplicity on the service side.

@skarnet
Copy link

skarnet commented May 4, 2019

It does work out-of-the-box. s6 lets the service choose any notification fd it wants; you, the user, have more choice, so you just need to pick a number, and tell both the service (via the READY_FD variable) and the supervisor (via the notification-fd file) what number you have chosen.

@CameronNemo CameronNemo force-pushed the readyfd branch 2 times, most recently from 3840fdd to b13d1c3 Compare May 5, 2019 07:06
@gdamjan
Copy link

gdamjan commented Mar 3, 2020

You certainly could. It would require linking to libsystemd,

this is actually not true. the api is trivially implementable in anything.
look for ex. this pure-python implementation https://github.com/bb4242/sdnotify/blob/master/sdnotify/__init__.py

muni-corn pushed a commit to muni-corn/swaylock that referenced this pull request Apr 16, 2022
@CameronNemo
Copy link
Contributor Author

CameronNemo commented Dec 16, 2022

If I rebased, would this (possibly) be accepted? Or should I just close it?

@WhyNotHugo
Copy link
Contributor

To summarize on the s6 side:

  • s6 allows the administrator to specify which file descriptor the daemon will use to notify its readiness. This is done via an unsigned integer in a config file. This value is called notification-fd.
  • An administrator can specify environment variables for services. This includes a variable READY_FD=.
  • An administrator can configure a service in a way that notification-fd matches the value of READY_FD=.

Essentially, the implementation on this PR has no incompatibilities. It merely requires being set up correctly.

It doesn't work out of the box because notification-fd must be defined explicitly. That is, support for readiness notification must be explicitly opted into by the administrator. There is no approach that will work "out of the box" because the feature is disabled by default.

Source: https://skarnet.org/software/s6/notifywhenup.html
Source: https://skarnet.org/software/s6/servicedir.html

@WhyNotHugo
Copy link
Contributor

WhyNotHugo commented Jan 13, 2023

Here's a rebased version of this branch:

0b7bc2a

Conflicts were trivial.

emersion added a commit that referenced this pull request Jan 27, 2023
This implements a readiness notification mechanism which works on
both systemd and s6.

References: #42
References: #275
@emersion emersion mentioned this pull request Jan 27, 2023
@emersion
Copy link
Member

Related: #281

emersion added a commit that referenced this pull request Jan 28, 2023
This implements a readiness notification mechanism which works on
both systemd and s6.

References: #42
References: #275
kennylevinsen pushed a commit that referenced this pull request Jan 28, 2023
This implements a readiness notification mechanism which works on
both systemd and s6.

References: #42
References: #275
mstoeckl pushed a commit to mstoeckl/swaylock-plugin that referenced this pull request Jan 29, 2023
This implements a readiness notification mechanism which works on
both systemd and s6.

References: swaywm#42
References: swaywm#275
@emersion
Copy link
Member

emersion commented Feb 2, 2023

Superseded by #281

@emersion emersion closed this Feb 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants