The s6 ecosystem

A modular, lightweight alternative for low-level userspace

The skarnet.org projects that revolve around process supervision, init, service management, and maybe a few other related things, are colloquially known as something nebulous called s6. This document aims to show exactly what piece does what, how the different parts interact together, and how they can be used to compose a modular system that has the exact features you need it to have, and nothing more.

Table of contents

The software packages

The core

When we talk about the s6 init system, we are really talking about a specific set of components:

  • At the heart of it all is the s6 process supervision system. This is the foundation that every other package depends on. It provides essential features, among which:

    • Process supervision: to manage long-running processes, a.k.a. daemons
    • Infrastructure for reliable logging
    • Instant notification support and tooling for process synchronization
    • Tooling for socket-listening services
    • Support for fd-holding (a.k.a. the useful part of "socket activation")

    Although the package name is s6, and using the s6 terminology in the strict sense refers to this process supervision package only, to avoid any confusion we will refer to it as s6-supervision, and we will use the s6 terminology to refer to the broader concepts implemented by either s6-supervision or one of the other skarnet.org packages. If the larger s6 ecosystem takes off, it would probably be a good idea to rename the s6 package itself to s6-supervision, for clarity; s6 could then become a meta-package resolving to the whole core.

    s6-supervision can be used as is, without necessarily being tied to an init system. However, by their nature, init systems need to integrate at least a minimal form of process supervision in their pid 1 functionality — so running s6-supervision in addition to an existing init system is somewhat wasteful. To prevent functionality duplication, s6-supervision was designed to be able to run as pid 1; but even then, pid 1 and process supervision do not an init system make, so the next package addresses this.

  • The s6-linux-init package provides /sbin/init functionality for the s6-supervision package, as well as additional tooling providing compatibility with the traditional sysvinit interfaces. Together, s6-supervision and s6-linux-init provide a functional init, although devoid of a service manager: the result is similar to runit, but with better foundations to build a service infrastructure upon because it guarantees the supervision framework to exist before the init scripts are run.
  • The s6-rc package implements service management on top of s6-supervision. Service management is the last, and most complex, part of an init system: it involves starting and stopping services, at boot/shutdown time or any time the administrator requires it, in an orderly fashion, following a graph of service dependencies. It is the part administrators interact with the most.

    s6-rc is the service management engine. It provides all the necessary mechanism and tooling to perform service management in a reliable way, and makes automation easy. However, it does not provide a human-friendly interface; to be on par with existing init systems, an additional component is required.

  • s6-frontend is the user interface to the s6-rc engine, and it also interfaces with lower level components, for optimal use of the flexibility the infrastructure offers. It is the capping stone of the s6 init system, integrating all the lower-level packages and hardcoding some good practices policy. It provides:

    • An interface based on text files, named service files, to describe service configuration in a declarative fashion (as opposed to s6-supervision or s6-rc where services are scripts). Service files are conceptually the same thing as systemd's unit files, although they do not follow exactly the same syntax, nor the same organization. (This is because s6 and systemd view services through a slightly different lens, so there are things in unit files that do not make sense for s6, and there are concepts that s6 needs and unit files do not express.)
    • A pre-written set of service files, that should be able to boot a majority of Linux machines without modification — in the same way that OpenRC and systemd provide their own sets of scripts and unit files, to help distributions get started with booting machines. This is policy, not mechanism; traditionally, s6 has shied away from implementing policy because 1. it impedes flexibility and 2. policy is a distribution's job, not upstream's job; but since s6-frontend aims to make s6 as user-friendly as possible, for distributors and end users, and general criticism of s6 is that it is overall too flexible, it makes sense to provide policy here and make distributors' lives easier.
    • A one-stop-shop s6 command, to provide a high-level command-line interface to all aspects of the system. The goal is to provide a syntax that administrators are familiar with, such as s6 restart foo, instead of having to know the inner details of lower-level layers in order to type the equivalent command s6-svc -r /run/service/foo.

Together, these packages form the s6 init system, which eventually aims to become a serious competitor to systemd.

The s6-supervision and s6-linux-init packages are already more or less feature-complete. The objectives of the current work are:

  1. To redesign s6-rc from its prototype status that only supports static sets of services to a full-featured service manager engine that supports a richer dependency model as well as dynamic external events.
  2. To implement all three parts of the s6-frontend user interface: the service files syntax, the policy set of service files, and the s6 high-level command. This part of the work can only be started once s6-rc is complete — or at the very least once its interfaces have been fully designed and are thought to be reasonably stable.

The satellites

In addition to the s6 init system there are a few components that are not stricto sensu part of s6, but that are also developed on skarnet.org, and interact with the s6 package in a natural way.

  • The execline scripting language. It is used internally by s6-supervision (optional but recommended) and s6-rc (mandatory) to provide functionality. One of the main advantages of execline is that it makes it very easy to automate reliable script generation, compared to shell for which the generation has to keep track of things like quoting level. s6-rc takes advantage of this to generate the scripts it executes.

    Despite being a dependency of s6, execline is not a part of it in the strict sense; and, contrary to an unfortunately popular myth, it is not necessary to learn it in order to use s6 by any means: user-provided scripts can be written in any language, including shell. Examples and documentation sometimes feature scripts written in execline, but only because it makes them lighter and easier to write and understand.

  • The s6-dns package, which is a set of DNS tools and has nothing to do with local system administration. It is totally independent from s6, completely optional, and is only listed because it is a dependency of the following package.
  • The s6-networking package, which is also completely optional, but provides the same kind of tools for network sockets (INET domain) that s6-supervision provides for local sockets. Administrators who like the feel of the s6 tools to create their own services will benefit from s6-networking, which follows the same design principles.

Despite not being part of the s6 core, these packages can be seen as satellites or extensions to s6, and so they are a part of the s6 ecosystem at large.

Other s6-prefixed programs

On skarnet.org, there are other packages whose name start with an s6- prefix. This is arguably a historical naming mistake, because they have no relation to s6 at all, either thematically or in the software dependency graph; the only trait they share with s6 is the design philosophy that pervades all of the skarnet.org software, which is more or less the original Unix philosophy of having one tool for one job.

  • s6-portable-utils is a collection of various small low-level utilities that do not use any non-portable constructs and are thus usable on any UNIX-like system.
  • s6-linux-utils is a collection of various small low-level utilities that use Linux-specific interfaces and are thus only usable on Linux systems.

Even though the utilities in these packages are prefixed with s6-, and even though they interact well with an s6-based system (because any Unixish tool will interact well!), the packages are not considered a part of the s6 ecosystem, and are out of scope for this whole series of documents.

A layered approach

The fact that the s6 init system is separated into so many packages might seem like maintenance overhead and needless complexity for the distributors or administrators, but there is a good reason for it: it emphasizes how modular s6 is.

systemd advocates like to say that "systemd is modular", because it is composed of several binaries and you don't have to run all of them; but it is a façade, and the reality is that all the systemd components are interconnected, and all the functionality comes into one package. You may not run such or such systemd component, but the support for the component is still there, and the binaries still occupy disk space, if not precious RAM.

With s6, modularity is made very visible by the packages that admins may choose not to install, and at every step, the system is perfectly functional.

  • Do you only want service supervision, without changing your init system? You can install s6-supervision and that's it.
  • Do you need full service and dependency management? Install s6-rc on top of s6-supervision.
  • Do you just want to boot a machine fast, without the cruft of your old init system? Install s6-linux-init along with s6-supervision, and you will have the fastest boot in the game. A setup made of only s6-linux-init and s6-supervision is perfect for minimalistic environments such as embedded systems, or containers — although some containers will be complex enough to also benefit from the dependency management offered by s6-rc, which you can of course install and use on top of s6-supervision with or without s6-linux-init.
  • Do you want the full systemd-like experience of an integrated init system with declarative service files? Install s6-frontend on top of all the other components, and that's exactly what you will get, without sacrificing the reliability, swiftness, or thriftiness of the lower-level components.

In other words, this layered approach to an init system is a feature.

The work

As previously mentioned, the current work involves two projects:

The links go further into design details of these projects, as they are being worked on.