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

RFE: use socket activation on systemd systems #230

Open
YHNdnzj opened this issue Mar 2, 2024 · 10 comments
Open

RFE: use socket activation on systemd systems #230

YHNdnzj opened this issue Mar 2, 2024 · 10 comments

Comments

@YHNdnzj
Copy link

YHNdnzj commented Mar 2, 2024

In the context of #221, busy retrying should be the last resort. Instead, it's cleaner and probably more efficient to support systemd's socket activation mechanism and only start the daemon when there's a connection.

@Paiusco
Copy link
Contributor

Paiusco commented May 3, 2024

Do you know how easy it is to create a ydotoold.socket? It's still on my list to read about that and see how to create it

@Paiusco
Copy link
Contributor

Paiusco commented May 7, 2024

@YHNdnzj I've been reading a bit on socket creation in the docs

I was wondering if the ListenSpecial=/dev/uinput would be the way to go, but then there's nothing coming from the device block to trigger the start.
We basically just have to wait until the /dev/uinput is up to start the daemon, it's not like we're waiting some data come out of it.

I wonder if a dependency After= Requires= on dev-uinput.device would suffice. Although I don't know if the udev rule would cover us for most of the distro/installations, and it'd not add more dependencies (for instance: having to ship and extra udev rule to make sure uinput would always be flagged as systemd, hence having a .device)

Can you provide some guidance here?

@YHNdnzj
Copy link
Author

YHNdnzj commented May 9, 2024

I was wondering if the ListenSpecial=/dev/uinput would be the way to go, but then there's nothing coming from the device block to trigger the start.
We basically just have to wait until the /dev/uinput is up to start the daemon, it's not like we're waiting some data come out of it.

Hmm, I don't understand what you're trying to do here? What I'm proposing is to make ydotool <-> ydotoold socket activatable, and that has nothing to do with uinput?

@YHNdnzj
Copy link
Author

YHNdnzj commented May 9, 2024

To implement systemd's socket activation, ydotoold must be taught to receive connection file descriptors from systemd, rather than binding to sockets on its own.

@Paiusco
Copy link
Contributor

Paiusco commented May 9, 2024

No, wait, but that's not the issue mentioned on #221.
The issue there is that ydotoold somehow is starting so fast that /dev/uinput is still unavailable, hence the failed to open uinput device: Permission denied message on the log.

I'm trying to make it in a way that the daemon waits/checks if the block device is already available. Can we do that using and extra .socket unit on systemd? Or should we change the daemon code itself to check if a couple of times and only then fail to start?

the CLI (ydotool) is not even part of the equation there, and that is the one that communicates via the socket file.

@YHNdnzj
Copy link
Author

YHNdnzj commented May 9, 2024

The issue there is that ydotoold somehow is starting so fast that /dev/uinput is still unavailable, hence the failed to open uinput device: Permission denied message on the log.

I think the cause of the original issue is that the user service starts before the session is started. And because the access to /dev/uinput is granted through uaccess, i.e. after the session becomes active, the daemon fails to start.

By switching the ydotoold to socket activation we circumvent the problem: the daemon is started only when ydotool is invoked for the first time, which happens after the session activates.

@Paiusco
Copy link
Contributor

Paiusco commented May 9, 2024

oh, so you mean that the first call from the CLI will start the daemon... and then the .socket creates the socket file that the daemon will be attached to.

but wouldn't that mean a big delay the first call from ydotool happens? Meaning that the first time someone would use it, the delay would be considerable... only because we can't check if the uinput is there already or not?

@YHNdnzj
Copy link
Author

YHNdnzj commented May 9, 2024

but wouldn't that mean a big delay the first call from ydotool happens? Meaning that the first time someone would use it, the delay would be considerable...

Well, you'd be surprised how many services on your system are actually socket/dbus-activated ;-)

Try run userdbctl or hostnamectl and see if you could notice the delay? systemd-hostnamed and systemd-userdbd are both activated when needed, and the former even automatically exits if it's idle for a while.

@Paiusco
Copy link
Contributor

Paiusco commented May 13, 2024

I liked it! I'll soon try it out, what do you recommend for the case where one is either starting ydotoold manually or not using systemd? I don't want it to be dependend on it.

That in this case ydotoold falls back to creating the socket itself? (e.g. expects a socket on /path/example, and if not there, creates one)

Never done something like this, want to read your mind clarify some ideas beforehand :)

@YHNdnzj
Copy link
Author

YHNdnzj commented May 23, 2024

That in this case ydotoold falls back to creating the socket itself?

Yes. If ydotoold didn't acquire the connection fd from a call to sd_listen_fds, it should fall back to creating and listening to the socket in the file system manually.

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

No branches or pull requests

2 participants