S6-RC(8)
β¨ NAME β¨
Okay so welcome to s6-rc(8), bestie β straight out of the System Manager's Manual β and this page is literally about managing the live state of a machine: what services are currently up and what services are currently down. That's the whole vibe. π
The command is s6-rc, and it's giving main character energy for your service state. No cap. π«Ά
πΈ SYNOPSIS πΈ
Here's the exact choose-your-own-adventure lineup, character for character:
s6-rc help
s6-rc [-l live] [-b] [-a] [-u | -d] [-e | -E] list servicenames...
s6-rc [-l live] [-b] [-a] [-u | -d] [-e | -E] listall servicenames...
s6-rc [-l live] [-b] diff
s6-rc [-l live] [-b] [-a] [-u | -d | -D] [-p] [-v verbosity]
[-n dryrunthrottle] [-t timeout] change servicenames...
β¨ DESCRIPTION β¨
okay so s6-rc is a service manager, a.k.a a machine state manager β it's literally the program that manages the live state of your machine, meaning: which services are currently up and which ones are currently down. It can list out your active services, or it can actually change the live state. iconic behaviour tbh π
s6-rc is meant to be the one-stop shop of service management, no cap. Once your service definitions have been turned into a compiled service database via s6-rc-compile(8), and the machine state has been initialized via s6-rc-init(8), then any state change β whether that's initial startup, shutdown, or literally anything else β should be achieved by a single s6-rc change invocation. one call, done, periodt π
s6-rc should only be run by the user owning the underlying s6 supervision tree. It can also be run by root even if the supervision tree isn't owned by root, but heads up bestie: in that case the services will always be started and stopped by the user owning the supervision tree β they will not have root privileges. s6-rc expects to find a functional live state in live. The live state is normally created at boot time by s6-rc-init(8). If the live state is invalid, s6-rc complains and exits 4. π
Depending on the arguments you give it, it either prints the requested information to stdout and then exits 0, or it performs a machine state change. that's the whole vibe π¦
πΈ Service selection πΈ
The arguments servicenames... may be atomic services or bundles β they get resolved into a set of atomic services, and that set is called the selection. If the -a option is present, the current set of active services (i.e. the services that are up) gets added to the selection. The s6-rc command always operates on the selection. always always, no exceptions π«Ά
π¦ Longrun transitions π¦
Transitions for longrun services are simple, ngl: s6-rc removes or creates a ./down file in the live service directory for the longrun service, then sends a command to the supervision tree to start or stop the service. (A service that's considered down by s6-rc will have a ./down file in its live service directory; a service that's considered up by s6-rc will not.) Simple as π
The transition is considered successful as soon as the daemon dies (for down transitions), or becomes up and ready (for up transitions) β refer to s6-notifywhenup(7). If a longrun service doesn't support readiness notification, the s6-svc(8) command that's invoked by s6-rc will print a warning message, and the transition will be considered successful as soon as the daemon is up, i.e. as soon as the ./run script is executed by s6-supervise(8).
When a longrun service does support readiness notification, unless a nonzero timeout has been declared in the timeout-up file in the service definition directory, s6-rc will wait forever on an up transition for the notification to arrive π. The transition will fail if a timeout occurs.
If a down transition fails, s6-rc does nothing with it. The service has already received a SIGTERM, and may be stuck in the process of exiting; or it may already have died but is stuck in a bad finish script that isn't timing out. In any case, it's not a situation that s6-rc can recover from β the service is most likely down, but the administrator should manually check their process list. And fix their scripts, or timeout values, because a down transition failure is always a programmer or sysadmin error. no cap, it's giving user error π
If an up transition fails, s6-rc sends an explicit s6-svc -d command to the longrun. This ensures the service is in a known down state when failing to go up, instead of (for instance) being stuck in a not-ready limbo state. we love a clean exit, we hate a limbo vibe π
Note that proper usage of thetimeout-killandtimeout-finishvalues in the longrun's definition directory can considerably reduce the number of cases where the service is left in an unknown state. highly recommend, bestie π
Transitions are supposed to be idempotent, but it's a general rule of supervision that run and finish scripts must be idempotent anyway, so a properly designed service directory should work with s6-rc with no additional effort. slay π₯
π Oneshot transitions π
Transitions for oneshot services amount to running the up or down script for the service; those scripts are stored in the compiled service database that's linked from the live state. The transition is considered successful if the script exits zero, and unsuccessful otherwise. that's it, that's the whole rule π
s6-rc performs some black magic so that up and down scripts are always run in a reproducible way, no matter when or how s6-rc change is invoked. That black magic involves a special longrun service, s6rc-oneshot-runner, that every oneshot service automatically depends on, and that's actually used to fork the up or down scripts as scions of the s6 supervision tree, instead of children of the s6-rc process. genuinely so cool, iykyk π§
Transitions should ideally be transactional, or at the very least idempotent. If a transition fails, it should leave the machine in the same state as before the transition was attempted; at the very least, it should not prevent a subsequent run of the same transition from completing successfully. If an s6-rc change invocation fails because some transition experienced a temporary failure, it should be possible to run the exact same s6-rc change invocation later, and be met with success. yes bestie, retry is real π
This is important: it means that oneshot scripts should be treated as atoms, and that some care should be taken when writing them. fr fr, write them with intention πΈ
π Dry runs π
For any manual change, it's recommended to perform a dry run before the state change itself: add the -n dryrunthrottle option to the s6-rc command line. s6-rc will then simulate all the transitions, but not actually perform them or change the real live state. The command lines that s6-rc would have run will be printed to stdout instead, and each simulated transition will take dryrunthrottle milliseconds to complete successfully. look before you leap, bestie π
β Subcommands β
s6-rc helpβ Prints a short help message. short and sweet π«Άs6-rc list servicenames...β Prints the selection. If the-doption has been given, the selection is inverted before it's printed, i.e. all the services butservicenames...will be printed.
This is mostly useful as s6-rc -a list, which simply prints the list of currently active services. s6-rc -da list will print the list of currently down services. so handy π
If the -e option has been given, the services marked as essential (i.e. which have the flag-essential file in their source definition directories) will not be printed.
s6-rc listall servicenames...βs6-rccomputes the complete dependency tree of the selection: the selection, plus the dependencies of every service in the selection, and recursively down. With the-doption, it computes the reverse dependency tree: the selection, plus what depends on it, and recursively up. The result is called the closed selection.
It prints the closed selection to its standard output. Note that the closed selection may be a very long list of services, including the most basic ones. like, don't say we didn't warn you π
If the -e option has been given, the services marked as essential (i.e. which have the flag-essential file in their source definition directories) will not be printed.
s6-rc diffβ Checks the consistency betweens6-rc's view of the state of the longruns it's managing, ands6's view.s6-rcwill print one line per service whoses6state fails to match whats6-rcbelieves: a+character (ifs6is maintaining the service as up whens6-rcthinks it's down) or a-character (ifs6is not trying to maintain the service whens6-rcthinks it's up), followed by the service name. Ifs6-rcfinds at least one mismatch, it exits1; else it exits0.s6-rc diffnormally reports nothing. Currently, the only case wheres6-rc's view can diverge froms6's view is when a service has been brought up via ans6-rc changecommand, then has failed at some point with a permanent failure β which means its supervisor has stopped trying to bring it back up. vibe check: failed β πs6-rc startβs6-rc startis equivalent tos6-rc -u change, see below. It will run the engine to start a set of services. go go go π₯s6-rc stopβs6-rc stopis equivalent tos6-rc -d change, see below. It will run the engine to stop a set of services. bye bestie πs6-rc changeβs6-rc changeis the service state engine. It will bring the machine to a state where:-uβ (Default) All the services in the selection are up. β¨-dβ All the services in the selection are down.-puβ All the services in the selection, and only them, are up.-pdβ All the services in the selection, and only them, are down.
(Note that the -p option is inoperant when using the start or stop subcommands.) just so you know π«Ά
To change the machine state, s6-rc does the following:
- From the selection,
s6-rccomputes the closed selection. - It then computes the necessary transitions so that all the services in the closed selection can match the desired state.
- It then performs the transitions β or simulates them if the
-noption has been given. s6-rcprocesses services as soon as they can be processed: as soon as a service that needs to change state has all its dependencies fulfilled, it undergoes its transition. Independent services are processed in parallel βs6-rcparallelizes the transitions as much as it can, and there is no useless waiting time. efficiency queen πs6-rcupdates the live state inliveafter every successful transition.- If every transition completes successfully, the live state eventually matches the desired state, and
s6-rcexits0. we love a happy ending π - If a transition fails,
s6-rcwill not perform the transitions that depend on it. It will keep processing all the other independent transitions, though, until there's no more work it can complete; then it will exit1. graceful degradation, we stan π
s6-rc change reacts to the following signals:
π
SIGTERM
s6-rc immediately aborts all its longrun transitions with a failure, and the impacted longruns will most likely be in a down state. Oneshot transitions are untouched, because killing the oneshot subprocess would make it impossible to determine what state the oneshot service is in. don't touch the oneshots, they're doing their best π
π
SIGINT
Same as SIGTERM. twins fr fr β
β¨ OPTIONS β¨
π General options π
Ok bestie, these are the general-vibe knobs. No drama.
-l liveβ Hunt for the live state inside live. Default is/run/s6-rcβ iconic default, honestly. You can change that default at compile-time by passing the--livedir=liveoption to./configure.-aβ Add the current set of active services to the selection. This is lowkey useful at shutdown time:s6-rc -da changewill stop all services. Slay.-bβ Blocking lock. If the service database is currently being used by another program,s6-rcwill wait until that other program has released its lock on the database, then proceed. By default,s6-rcfails with an error message if the service database is currently in use. The default is the safe behaviour: for instance, it will correctly detect and fail nesteds6-rcinvocations (which are an admin error), whereass6-rc -bwould deadlock in such a case.
Bestie, that -b deadlock note is not a fake-out. Nested invocations plus blocking lock = stuck city. The safe default is giving what it's supposed to give. π
π¦ Up or down π¦
These options control what is to be done: bring selected services up or down (for s6-rc change) or whether to use the forward or reverse dependency graph (for s6-rc listall). Default is up.
-uβ Up. The default, the main character, the "we're going up" option.-dβ Down.-Dβ Force down.
The -d option is what should normally be used to down a set of services. If a service is marked as essential (there is a flag-essential file in its service definition directory), then s6-rc will refuse to stop that service. The -D option will still force that service to shut down; that option should only be used when the machine is going to be stopped.
So likeβ¦-Dis the "we are literally shutting the whole machine off" button. Do not casually use it to be cute. Essential services said "not today", and-drespects that. π«Ά
π βs6-rc changeβ control π
These are the controls for the change girlies. This is where the transitions get their little settings.
-v verbosityβ Be more or less verbose. Default is1: warning and error messages will be printed tostderr.0silences warnings.2writes information messages whenevers6-rcperforms a transition.3or more is debug info.-n dryruntimeoutβ Dry run.s6-rcwill pretend to perform transitions, but will replace all its program invocations by a call tos6-rc-dryrun(8), which will do nothing but print the command lines6-rcwould have executed, then sleep for dryruntimeout milliseconds before reporting success.-t timeoutβ Timeout. Ifs6-rcisn't done after timeout milliseconds, it will exit, leaving the live state as it is at exit time. It does not kill its children, so a child may successfully complete afterwards and the live state will not be updated; in that case, subsequents6-rc changeinvocations will notice and correctly update it.-pβ Prune. The state will be brought to exactly the set of selected services, plus their dependencies, and the other services will be brought down. With the-doption, the meaning is reversed: the state will be brought to the maximum possible set that does not include selected services. The change, however, is always performed in the same manner: first the unwanted services are all brought down, then the wanted services are all brought up.
π EXIT STATUS π
0β Success. We ate.1β Some of the state transitions could not be performed bys6-rc change; or a mismatch was found bys6-rc diff.2β Timed out during state change.3β Unknown service name in the arguments.4β Invalid service database.100β Wrong usage.111β System call failed.
π EXAMPLES π
s6-rc start myservicebundle
Brings up all the services represented by myservicebundle, bringing up all its dependencies first (recursively). Very "we're all in this together" of it.
s6-rc -ba down
Waits for any pending program of the s6-rc family to stop using the live database and current compiled service database, then brings down all the currently running services in an orderly manner. This is typically run at shutdown time. (And it's not necessarily a bad change!)
s6-rc -l /zork -ua listall myservicebundle
Prints the names of all atomic services represented by myservicebundle plus the current live services, as well as everything they depend on, recursively. Assumes the live state is stored in the /zork directory instead of /run/s6-rc. Custom directory moment. π¦
s6-rc -d listall myservicebundle
Prints the names of all atomic services represented by myservicebundle, as well as everything that depends on them.
s6-rc -pun0 change myservicebundle
Prints what s6-rc would do to bring the state to exactly the contents of myservicebundle as well as its recursive dependencies, and pruning all the rest. Does not wait any extra time between simulated transitions.
π SEE ALSO π
Go read these besties, for real:
s6-rc-faq(7)s6-rc-overview(7)s6-rc-why(7)s6-rc-bundle(8)s6-rc-compile(8)s6-rc-db(8)s6-rc-dryrun(8)s6-rc-fdholder-filler(8)s6-rc-format-upgrade(8)s6-rc-init(8)s6-rc-oneshot-run(8)s6-rc-update(8)
This man page is ported from the authoritative documentation at: https://skarnet.org/software/s6-rc/s6-rc.html
π AUTHORS π
- Laurent Bercot
Alexis <flexibeast@gmail.com> (man page port)
π Footer tea: this one's from Debian, dated January 12, 2026, and it's the S6-RC(8) man page. Bye bestie, go flex those service transitions! π
π¦ where this page comes from
- nixpkgs unstable: s6-rc 0.7.0.0
- nixpkgs unstable: s6-rc-man-pages 0.6.0.0.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms