
Can you use a example to explain what you mean.Alverstone wrote:A terrible lack (or my ignorance of otherwise) of openrc is that while you are able to simply invoke /bin/openrc to start runlevels, you can not actually use it to stop them, at least when openrc-init is not PID 1.

Now, the runit package in particular does not provide a service manager, so you might want to try using OpenRC on top of runit to provide that capability, kind of like it is used on top of sysvinit on Gentoo. In that case, the strategy would be to call the openrc program in /etc/runit/1, and then call it again as openrc shutdown in /etc/runit/3. That stops services started by other (OpenRC!) runlevels. However I don't know how well that would work in practice.Alverstone wrote:– A runit user
Ionen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though

Consider the default /etc/runit/{1,3} implementation:pingtoo wrote:Can you use a example to explain what you mean.
Code: Select all
#!/bin/bash
# system one time tasks
PATH=/sbin:/usr/sbin:/bin:/usr/bin
RUNLEVEL=S /sbin/openrc sysinit
RUNLEVEL=S /sbin/openrc boot
touch /etc/runit/stopit
chmod 0 /etc/runit/stopit
Code: Select all
#!/bin/bash
sv -w 300 force-shutdown /etc/service/*
. /etc/runit/rc.sh
run_rc_stage 3
Code: Select all
#!/bin/sh
test -x /etc/runit/reboot && LAST=6 || LAST=0
test -x /etc/runit/reboot && RC=reboot || RC=shutdown
RUNLEVEL=$LAST /sbin/openrc $RC
Why is that so? Re-implementing the boot sequence is a mess, it is a blessing when some parts of it can be simply reused to avoid over saturating universe with wheelsGDH-gentoo wrote:If distributions implement other init systems in a way that depends on the openrc binary and OpenRC service scripts, they are doing it wrong
— A user of an s6-based init system
I do use openrc to manage stages 1 and 3, though not exclusively. Rather, I build my own gimmicks on top of what openrc provides out of the box. For example, my /etc/runit/1 is simplyusing OpenRC on top of runit to provide that capability, kind of like it is used on top of sysvinit on Gentoo
Code: Select all
#!/bin/bash
# system one time tasks
PATH=/sbin:/usr/sbin:/bin:/usr/bin
RUNLEVEL=S /sbin/openrc sysinit
/etc/runit/bootrc early
RUNLEVEL=S /sbin/openrc boot
/etc/runit/bootrc late
touch /etc/runit/stopit
touch /etc/runit/reboot
chmod 000 /etc/runit/stopit
chmod 000 /etc/runit/reboot
Void has incomplete boot sequence that only supports the default scenario and allows very little flexibility. Gentoo's openrc boot sequence is quite superior to Void's. Also, Void isn't relevant since the question is about gentoo.Runit on Void does not use OpenRC.
The boot and sysinit runlevels are not meant to be stopped (including any services included therein). They exist for basic tools to bring a system to a nominal usable state with all of the services can be terminated by a hardware reboot/shutdown without recourse.Alverstone wrote:When the "/sbin/openrc shudown" or "/sbin/openrc reboot" executes, the boot and sysinit runlevels are not stopped. That needs to be manually implemented in context of rc-service, which is messy.

Because the mechanism used by OpenRC for implementing the boot sequence (and shutdown sequence) is... surprise! OpenRC-specificAlverstone wrote:Why is that so?GDH-gentoo wrote:If distributions implement other init systems in a way that depends on the openrc binary and OpenRC service scripts, they are doing it wrong
— A user of an s6-based init system
Uh... no? Did you see the #!/sbin/openrc-run in the service scripts? It's like saying we could simply reuse systemd unit files.Alverstone wrote:[...] some parts of it can be simply reused [...]
Ionen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though

What about /etc/init.d/hwclock?grknight wrote:The boot and sysinit runlevels are not meant to be stopped (including any services included therein). They exist for basic tools to bring a system to a nominal usable state with all of the services can be terminated by a hardware reboot/shutdown without recourse.Alverstone wrote:When the "/sbin/openrc shudown" or "/sbin/openrc reboot" executes, the boot and sysinit runlevels are not stopped. That needs to be manually implemented in context of rc-service, which is messy.
Any service that is able to be stopped must be in a runlevel besides those. (Fun fact, you can create custom runlevels but hardly anyone does.)
Edit: Reread last sentence and found issues with it. Fixed

Ionen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though
The docs say this is true. But, they don't need to be in most cases.GDH-gentoo wrote:I'm pretty sure openrc shutdown does execute the stop() function of service scripts that correspond to services in the sysinit and boot runlevels. I'll add lvm to the examples given by Alverstone.
I'm not in front of a Gentoo computer right now, but when I am, that should be easy to test with scripts that just print messages.

Alverstone wrote:When the "/sbin/openrc shudown" or "/sbin/openrc reboot" executes, the boot and sysinit runlevels are not stopped.
Simple test then:GDH-gentoo wrote:I'm pretty sure openrc shutdown does execute the stop() function of service scripts that correspond to services in the sysinit and boot runlevels.
Code: Select all
#!/sbin/openrc-run
depend() {
before killprocs savecache
}
start() { :; }
stop() {
ebegin "Stopping a service in the sysinit runlevel"
sleep 5
eend 0
}Code: Select all
#!/sbin/openrc-run
depend() {
before killprocs savecache
}
start() { :; }
stop() {
ebegin "Stopping a service in the boot runlevel"
sleep 5
eend 0
}Code: Select all
# rc-update add test-sysinit sysinit
# rc-update add test-boot bootIonen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though

I do not understand what is the internal difference when OpenRC runs on top of sysinit compared to runit-init, but it would be very nice if /bin/openrc stopped services in the previous runlevel when switching to a new one, as described in the manual. As I said, since the code to build dependency graph is already there, it shouldn't be a big problem.GDH-gentoo wrote:If this doesn't happen with OpenRC on top of runit, then that's a separate problem.
Try rc-status -aI'm pretty sure openrc shutdown does execute the stop() function of service scripts that correspond to services in the sysinit and boot runlevels.
but it would be very nice if /bin/openrc stopped services in the previous runlevel when switching to a new one, as described in the manual.
Code: Select all
# grep ^l /etc/inittab
l0u:0:wait:/sbin/telinit u
l0:0:wait:/sbin/openrc shutdown
l0s:0:wait:/sbin/halt.sh
l1:1:wait:/sbin/openrc single
l2:2:wait:/sbin/openrc nonetwork
l3:3:wait:/sbin/openrc default
l4:4:wait:/sbin/openrc default
l5:5:wait:/sbin/openrc default
l6u:6:wait:/sbin/telinit u
l6:6:wait:/sbin/openrc reboot
l6r:6:wait:/sbin/reboot -dkn

There is one: OpenRC never leaves the boot runlevel until the computer shuts down (the way /etc/runit/1 is probably written). I didn't check openrc's source code, but, since boot is special, it might be significant.Alverstone wrote:I do not understand what is the internal difference when OpenRC runs on top of sysinit compared to runit-init, [...]
As I said, it does stop services in the sysinit and boot runlevels when shutting down and running on top of sysvinit. It probably does what the manual says when switching runlevels as well, but people usually don't switch away from the default runlevel, other than by shutting down, or define new OpenRC runlevels to switch to.Alverstone wrote:[...] but it would be very nice if /bin/openrc stopped services in the previous runlevel when switching to a new one, as described in the manual.
They are mapped to two pseudo-runlevels:szatox wrote:No runlevel is mapped to boot or sysinit.
Code: Select all
# System initialization, mount local filesystems, etc.
si::sysinit:/sbin/openrc sysinit
# Further system initialization, brings up the boot runlevel.
rc::bootwait:/sbin/openrc bootIonen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though


Could you please elaborate on this? The s6 'socket activation' page says:Alverstone wrote:Why do I need socket activation as a part of the init system
There's also this 2015 post by Laurent Bercot, the creator/maintainer of s6.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 ...
Most of the time, you don't need to use execline. Bercot is very frustrated by people believing or claiming that s6 requires the use of execline. As i've written elsewhere:Alverstone wrote:Why do I need """execline"""???
You might find the page "Why not just use /bin/sh?" answers some of your questions about execline.As with s6 services, s6-rc services generally do not need to be written in the execline scripting language; service scripts can be written in any shell or scripting language, using the appropriate shebang line (e.g. #!/bin/sh) instead of #!/usr/bin/execlineb -P. The only exception to this is that up and down scripts for oneshot services must be written in execline, but even there, those scripts can simply chain load a script written in any language.


Okay, but as far as i'm aware, that's what s6 does? Via the various s6-fdholder* commands? Could you explain why you feel 'socket activation' (in its s6 form) must be set up and used when using s6 as init / supervision?Alverstone wrote:Socket activation does not belong with the init system. Have a separate set of utilities for it, that are distributed and documented separately.
See above.Alverstone wrote:Nothing stops you from writing a program, that waits for a socket, and then exec()s into your daemon. And if you need to hold your fds in case your daemon "has to crash", that can be done by another daemon, that is hopefully more reliable, and which you hopefully will not restart accidentally.
i'm not sure whether by "s6-init" you mean "using s6 for init" or "using the s6-linux-init" package; could you clarify? (My guess is that you mean the former, but i wanted to check.)Alverstone wrote:As for execline, I'd don't mind the interpreter itself, what I do mind is that I have to be even aware of its existence if I want to use s6-init.
Hm, so is the simple presence of execline on your system part of the issue? (i understand people wanting to minimise what's on their system, e.g. to reduce potential attack surface.)Alverstone wrote:I really, really could not care less for another interpreter on my desktop system.
Yeah, Bercot is aware of this issue. (And i understand your comparison with runit - i contributed to the Void documentation in this regard. As a side comment, i also eventually ended up running 66 on my Void system.) He's currently working on something he hopes will make things easier.Alverstone wrote:s6-init, and I am not joking here, from user's (my) perspective, is harder to use than systemd, which is almost comic. Part of it is packaging, of course, but still. I won't tire of repeating it, but with runit, I only have to manage /etc/runit/{1,2,3,ctrlaltdel} and a bunch of almost trivial run files in /etc/service. This is literally just how easy runit is to use. I fail to imagine anything simpler that would still be functional (hello suckless init). With s6, I read the docs on skarnet again and again and I still don't begin to imagine how to merely get started with s6 and it's service management which is the only reason I consider it at all, as opposed to runit.

All of that comes from a single codebase, as far as I understand. I install s6 and see all of those creepy utilities I sure as hell do not need.Okay, but as far as i'm aware, that's what s6 does?
I never said or implied that.Could you explain why you feel 'socket activation' (in its s6 form) must be set up and used when using s6 as init / supervision?
Regardless of the under the hood nuances, the s6 as a whole is presented along with execline, and even requires it for one shot services. All of that is too much necessary complexity, integration and so on. My opinion is that the init system itself should only include process supervision and service management, the latter being necessary only since relatively recent times. And those should be simple enough that they wouldn't know about any specific interpreters.i'm not sure whether by "s6-init" you mean "using s6 for init" or "using the s6-linux-init" package; could you clarify?


OK, if you don't like it, you don't like it. Yes, s6 (the package, not the whole suite) provides in one single package a few groups of related tools that the author believes are useful: broadly, the daemontools-like supervision suite and auxiliary programs (an equivalent of about 95% of runit), the super-server and related utilities for implementing local services, s6-sudod and related utilities, and the tools for file descriptor passing and holding. Well, there's the tools for logging, notification and dynamic instances management, but you could group those with the supervision suite.Alverstone wrote:I have spent some time with s6-init in a VM, and I am unhappy with it. It has a large sprawl, beginning with simple supervision and ending with a sudo replacement.
You don't. The author just thinks that it is useful and happens to package it with his supervision suite. You as the user are not required to use it directly, but the service manager does use it internally for implementing oneshots. I don't think one can say that oneshots aren't needed.Alverstone wrote:Why do I need a sudo replacement as a part of my init system?
You don't. The author does have external programs for parts of the underlying mechanism of "socket activation" that he finds useful (UNIX domain super-server and file descriptor passing and holding), he just happens to package them with his supervision suite. The service manager does use those internally for implementing longrun pipelining (search for it here), which is how you do logging with s6-rc.Alverstone wrote:Why do I need socket activation as a part of the init system, when it can be done by an external program?
You don't, flexibeast addressed that. Do look at the link to know why execline exists. And execline is a separate package. The service manager and s6-linux-init use it internally though, in part because the author finds it easy to generate 'glue' excecline scripts from C programs, I seem to remember.Alverstone wrote:Why do I need """execline"""???
It's not "a dozen", the essential ones are s6-rc-compile for making one and s6-rc-update for swapping the one used by an s6-rc live state directory associated with an active supervision tree. And then there is s6-rc-db for the benefit of the human userAlverstone wrote:Why do I have a dozen utilities managing a "service database", God knows how (reload db? remove obsolete instances? changing service state? recompiling the db every time? what hell is all that stuff)?
There are manpages thanks to flexibeast, and if you are genuinely interested, you can ask if you don't understand the HTML documentation. The man pages are made with the contents of the HTML documentation though, if I understand correctly, so I'm not sure how they would help in this case.Alverstone wrote:Due to the lack of manpages, I still find most of s6 to be incomprehensible despite reading the html documentation multiple times.
I'd like to note that first and second points are implemented by the already written s6-rc in a somewhat different way, and the last one can be handled with s6 readiness notification and the already written s6-notifyoncheck program from s6.Alverstone wrote:I have therefore thought (but haven't done anything to make it happen) of a rather simple set of improvements to runit, that I thought I'd share just to get a public opinion.
Assuming that $PWD is a service directory, add:
- ./deps: a list of dependencies, one per line, that correspond to the current runsvdir. Empty means no dependencies.
- ./type: a file that contains a single line, either "c" or "o", where "o" stands for a one-shot service. This may not be needed, but for OCD's sake it would be nice to not run unnecessary `runsv` instances.
- ./notify: an executable file, that is only used for daemons (type "c" services). When the file exits 0, the daemon is considered started, if not 0, then the daemon is considered to have failed, and if ./run is still alive it is killed. While this process is ongoing, the daemon is simply considered to be down (./supervise/status).
That sort of is the UNIX domain super-server, s6-ipcserverd. It is separate, and is documented separately, just not distributed separately.Alverstone wrote:Socket activation does not belong with the init system. Have a separate set of utilities for it, that are distributed and documented separately. Nothing stops you from writing a program, that waits for a socket, and then exec()s into your daemon.
That sort of is the file descriptor holder, s6-fdholderd. Ditto.Alverstone wrote:And if you need to hold your fds in case your daemon "has to crash", that can be done by another daemon, that is hopefully more reliable, and which you hopefully will not restart accidentally.
You can be 99,9% unaware if you want to.Alverstone wrote:As for execline, I'd don't mind the interpreter itself, what I do mind is that I have to be even aware of its existence if I want to use s6-init.
And, as the existence of this thread seems to imply, while you find it nice, you also seem to consider runit insufficient. You don't like this other alternative, so you wish someone would write something specifically for runit, complementing what it lacks. That's fine. Only nobody has done it yet.Alverstone wrote:I won't tire of repeating it, but with runit, I only have to manage /etc/runit/{1,2,3,ctrlaltdel} and a bunch of almost trivial run files in /etc/service.
You can write oneshots as:Alverstone wrote:Regardless of the under the hood nuances, the s6 as a whole is presented along with execline, and even requires it for one shot services.
Code: Select all
/absolute/pathname/of/some-script upCode: Select all
/absolute/pathname/of/some-script downIonen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though


Yes.Alverstone wrote: Sat Apr 04, 2026 8:04 pmTo use Gentoo's code I'd have to adapt it, i.e. run it outside of openrc-run.
Exactly.Alverstone wrote: Sat Apr 04, 2026 8:04 pmThere's also Artix linux of course, but their boot sequence is specific to their distro.
Exactly.Alverstone wrote: Sat Apr 04, 2026 8:04 pmOf course, it's possible to just do it runit-style, but that defeats the purpose of s6-rc.
It is realistic though, Gentoo's OpenRC scripts exist, and can be studied and adapted. I've done it (at least for one single system, mineAlverstone wrote: Sat Apr 04, 2026 8:04 pmIt makes life quite difficult for alternative inits, because it is just not realistic to redo the whole boot sequence yourself and then also maintain it on your own.
Ionen wrote:As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though
