S6 mega thread

I’m still new to s6, not sure. I think it’d be the readiness codes that you put in the file. The s6-logger has this notification-fd file and its contents is always 3. I’ve been using it without knowing its meaning yet, but it works, sooo… oh right, both s6 and 66 recommend getting into it without reading everything first, since most of the advanced stuff you might not even see (unless you write services yourself, in which case, since there’s nothing good out there, I have to).

Yes, inside the service definition.

The way I proposed handling this is allowing the user full control over the system. You never change a user’s source files and never mess with the user’s system state (the s6-rc database). You give services from the repo in an “examples” folder (I currently have that be delivered in /etc/s6-rc/s6sv) and if you don’t want to have to think about the service, you symlink from the examples to the source folder (/etc/s6-rc/source - basically the fountain-of-truth for your system state).

Because (in the way I envision it) everything goes in the examples folders (when managing a repo, you’d have a service file bundled with the program’s repo package that would only be added when it’s installed), if a user wants to have their own definition or custom folder, then one would either copy the example service with a custom name in the same location and symlink with the normal name to the custom name (e.g. /etc/s6-rc/source/chronyd → /etc/s6-rc/s6sv/chronyd-custom-service) and s6 will see it as just the normal name (despite it pointing to literal gibberish as long as the folder is a valid service definition), or one would just copy the service directly from the examples to the source folders and modify it there.

The above is kinda hard to digest. Let me rephrase it. Everything goes to examples, users should never touch examples directly (because they’ll be always overwritten from the repo). They can symlink the example if they don’t want a custom service. If the example updates, they just have to update their s6-rc db and nothing else (to get the new service definition, but that’s not mandatory).

If users want custom services for their own needs, they either make a new “example” and symlink to it, or make the folder directly in the sources folder for s6-rc-compile. The repo maintainers will never touch the s6-rc source folder and will only deliver examples. The only exception would be on first system setup, when some low-level services (init-modules, mount-fs, tty etc.) are set up as symlinks to the examples in the source folder. That’s the only thing users should generally avoid modifying, but they can remove all of them and use their own custom options (busybox tty instead of agetty, added modules etc.).

Yes, I know systemd has the “systemctl edit something.service” option, I’ve used it myself. I find this too be too much on the chaotic side (why have a built-in functionality that could introduce bugs, instead of using something like examples?).

I prefer the fedora approach, you don’t enable services for your users automatically when someone installs something. The way ubuntu and debian does it might make it easier (automatically setting things up), but that’s insane when it comes to user preferences. Just like you have to manually either “systemctl enable service,” so would you have to enable a service in s6 (which is currently a bit complicated, but I’ll be working on a helper script to make it easy - that’s why s6 is easy, to allow frontends to integrate with it).

If you view the larger pictures, they’re just services. Actually, something not said in many places, the both the service files run and finish can even be binaries and don’t have to be scripts. If you have a custom, idk, java program that you just execute and it does its magic, then you can literally just copy the binary in the source folder, name it to “run” and go with it. It won’t be ideal, because it bloats the s6-rc db, but it’s workable. Ideally you have a very simple execline script that only calls that binary from somewhere else on the system (like, idk, /opt/program or /usr/bin), so you keep your s6-rc db lean.

This is especially important if you want to update your binary (get a new version) without having to rebuild your system state (that’s why you’d invoke it from somewhere else). In some places, actually having it in the db might make sense (like in embedded), so everything just runs from the db (s6 even has a data and env folder for services, that also never get touched).

You can run nested s6-svscan as a user, which can have its own s6-rc database. You can even run s6-svscan + s6-rc under runit or systemd. You can even use s6 as your “glue” between your services if you have a large unix suite composed of multiple programs that need to executed in a certain order.

s6 is flexible when it comes to that (the fact that systemd can’t run if it’s not PID 1 is total insanity to me - if I chroot into my rootfs from another system and I want to disable a broken systemd service, or want to start a systemd service that I know should work just fine, then I shouldn’t get an error that systemd isn’t running as pid 1 and should just start the dang service, dangit!).

I’m not into those kinds of embedded systems, sorry. :sweat_smile:

Oops.

You didn’t need to explain to me, but I still read the explanation regardless. :slight_smile:

I noticed, that’s what I wanted to write before you wrote this, but I got busy with other stuff and you got ahead of me :stuck_out_tongue:


With more and more discussions, I find that this is becoming a trend. This is not criticism of systemd users. It seems most of them like having the service manager do things for them, especially when they’re the ones writing the service (unit) files.

I can see why one would prefer built-in directives, as opposed to the stability of a minimal program, where you’d have to program (probably repetitive) functions. In regards to s6 stack, the default is s6-rc, but there’s another contender, 66, which makes things a bit more like systemd definitions (they look similar to unit files in some aspects, but you still have some scripting involved, like the start command and I think there’s no soft dependencies either).

This is a big philosophical difference between s6 stack and systemd. Systemd does a lot of things (and arguably not well, but “good enough” for most people). The advantage of s6 is its extensibility. I can see why s6-rc maybe isn’t for you. And maybe 66 won’t be for you either, as it still maintains some basics that s6-rc also does (66 used to be a bunch of wrapper scripts around s6-rc, but it became its own thing later on).

But there’s a possibility that someone might write a new service manager around s6-supervise that acts more like systemd and offers all (or most) of the built-in functionality (you probably won’t see stuff like netword, gummiboot or nspawn though, which should’ve been separate projects anyway).

The author of s6 actually wrote an article on how to reimplement systemd in s6. It’s insanity.


I prefer execline rather than shell, but again, you can have a service be anything, even a c or java binary. The reason I prefer to write even the basic service file in execline is to keep my s6-rc db minimal.

Here’s my simplest service definition.

# cat cronie/run 
#!/bin/execlineb -P
envfile -I /etc/s6-rc/config/cronie.conf 
importas -uD "" OPTS OPTS

exec cronie-crond -n ${OPTS}

In sh, it’d translate to something like this.

. /etc/s6-rc/config/cronie.conf
export OPTS

exec cronie-crond -n ${OPTS}

If cronie-crond had the default to run in foreground and not daemonize (background) itself, you could literally invoke cronie-crond without any arguments (the OPTS arguments is currently empty, but it’s used if an admin wants to add additional flags, like enabling debug and restarting the service, without having to recompile the s6-rc db, because the system state hasn’t changed, but trying to run a service with more verbosity).

One of the more crazy services I’ve written is the nfs-server (because nfs has a lot of moving parts). You won’t need to write this yourself once I’m done (which is why I have a git for s6_services), but you could edit it (once I finish the commit, nfs is not done yet).

I’m a sysadmin, s6-rc comes natural to me, because I have to modify services from time to time. In systemd I’ve used the edit option, as mentioned before. Sometimes I even have to create them from scratch (mostly did this on nixos, but not with the native nix stuff, just the systemd unit file itself). I never saw practical places where a soft dependency makes sense. Maybe I’ll get confronted with that at some point, but until then, I need something that works for me and I don’t mind having to use just hard dependencies.

I’m really enjoying our discussion. I’d prefer if we can keep it here. I want to see all point of views from systemd side and I’m glad jaskij is here as well.

Do you even deal with notifications in systemd? I doubt most people need to think about these things. It’s up to software developers and at best maintainers to add these things in. Once defined, a user will just know to set up the service (or it’ll come from the maintainers anyway and a user won’t have to even think about it, just like with systemd).

But as far as file descriptors go, many people (probably even a majority, or at least a large minority in unix) still deal with them (stdin, stdout, stderr). Just that rarely anyone deals with custom fd and most people just pipe stuff (well, pipes and network sockets are also fd - don’t ask me to give you an in-depth overview, lol, I only know the surface / basics).

Slightly off-topic, but Upstart’s design is sane. Its implementation is the definition of insanity (ptracing a PID to monitor it).

I’m pretty sure the why answers most of the s6 questions on the design choices. Stuff like “how to do X in s6” is what I can (hopefully) answer.

No. As long as it’s still s6-adjacenet and questions on how s6 could handle stuff, it’s all good.