How do I perform socket activation with s6 ?
First, it's important to realize that you don't need socket activation. It's a marketing word used by systemd advocates that mixes a couple useful architecture concepts and several horrible ideas, for a very minor speed benefit. Read this mail and this post for details.
- s6 will not help you implement super-servers in process 1, because doing so is bad engineering. However, it will help you set up super-servers. The s6-ipcserver program, for Unix domain sockets, as well as the s6-tcpserver program, for TCP INET domain sockets (available in the s6-networking package) are super-servers you can use to your heart's content. They are even wrappers around simpler programs, and you can use their components in the way you choose: bind sockets, drop privileges, accept connections from clients, it's all about what you write in your command line. Super-servers are a good thing; using process 1 to act as a super-server is not. s6 provides you with the tools to get the good without the bad.
- s6 will not help you run all your services before their
dependencies are met, because doing so is very bad engineering.
However, it will provide you with:
- a reliable logging infrastructure, that makes sure your services never lose logs: s6-log, in conjunction with s6-supervise and s6-svscan.
- ways to open your sockets and bind them as early as you want in your boot process, and make them accept client connections later: s6-ipcserver-socketbinder and s6-tcpserver-socketbinder.
- A supervision infrastructure that can start as many services in parallel as you want: s6-supervise and s6-svscan.
- s6 will not help you centralize all your socket information in process 1, because doing so is contrary to modularity and independence of services. However, s6 will provide you with a way to store your open sockets and retrieve them when you want, which it calls "fd holding": s6-fdholder-daemon.
So, how do I open all my sockets first, store them, and dispatch them to daemons later ?
Again, it's not necessary to do that: you'll be fine, and quite speedy, just starting your daemons in their good time. You will not reap any noticeable benefit from performing "socket activation". But if you really want to:
- Make sure you have an early supervision infrastructure running. Ideally, you would make s6-svscan your process 1.
- Start an early fd-holding service. Let's say the fd-holding daemon is listening on socket /service/fdholder/s.
- For every Unix domain socket /my/socket you need to open, run s6-ipcserver-socketbinder /my/socket s6-fdholder-store /service/fdholder/s unix:/my/socket. You can do the same with INET domain sockets.
- Proceed to your initialization.
- When you want to run a daemon myserverd that accepts clients connecting to /my/socket, run s6-fdholder-retrieve /service/fdholder/s unix:/my/socket myserverd. myserverd will be executed with /my/socket as its standard input.
- The descriptors remain safely stored in the fd-holding daemon and you can retrieve them again whenever you want, for instance when your service crashes and is restarted.
That is all there is to it. You don't have to use specific libraries or write complex unit files, you just need to understand how a command line works. This is Unix.
