> Some of the older init systems may be clearer about the things that happen in it.
Or some of the newer ones:
http://smarden.org/runit/runit.8.html
This document fully documents Runit, it doesn't just document it but this document counts as a specification; it says exactly what it does to the point of it being sufficient to develop a perfect drop in replacement for it from this document alone; it's a document that fits onto my screen without scrolling—it's way, way smaller than what sysvinit s documentation would amount to.
> ... a design which relies on double-forking, PID files and dodgy shell scripts.
Do you know anything about runit? I don't think so. Here, let me help you out ( http://smarden.org/runit/benefits.html )
> Each service is associated with a service directory, and each service daemon runs as a child process of a supervising runsv process running in this directory. The runsv program provides a reliable interface for signalling the service daemon and controlling the service and supervisor. Normally the sv program is used to send commands through this interface, and to query status informations about the service.
> The runsv program supervises the corresponding service daemon. By default a service is defined to be up, that means, if the service daemon dies, it will be restarted. Of course you can tell runsv otherwise.
> This reliable interface to control daemons and supervisors obsoletes pid-guessing programs, such as pidof, killall, start-stop-daemon, which, due to guessing, are prone to failures by design. It also obsoletes so called pid-files, no need for each and every service daemon to include code to daemonize, to write the new process id into a file, and to take care that the file is removed properly on shutdown, which might be very difficult in case of a crash.
Runit is much better than being dependent on something as crappy and non-standard as cgroups and having the init completely hijack the cgroups hierarchy. Talk about a kudgy hack.
You might want to take a look at runsvdir, which is part of runit. It's sort of a clone of daemontools. I use Void, which uses it by default, but you should be able to use it on other distributions as well.
Basically it runs all the services in the service directory in parallel, and each service has a ./run
shell script, so you would be able to see what each service is doing by putting echo statements in there.
Runit runs certain scripts. At boot it runs /etc/runit/1
for one-time initialization tasks like mounting the root filesystem and whatnot, and then it runs /etc/runit/2
, which usually starts runsvdir, but it could start OpenRC or something. And /etc/runit/3
is run when the system stops and /etc/runit/2
finishes.
-runit is the fastest init i've ever used (http://smarden.org/runit/ - beware, void uses different default locations for stuff)
-xbps is a really fast package manager. i thought yum was slow compared to apt-get but apt-get is a glacier compared to xbps
-void-packages: basically ports. lots of ports, package build templates also include options, so you can for example compile dmenu with xft support as I did here, without leaving the packaging system
That would be an incompatibility with runit then, which has been more-or-less adopted by Void but is definitely a separate project.
So in reality, GNOME doesn't support runit (or Void, at least not by default). Not the other way around.
Tying a DE to any init system seems pretty silly to me. I guess you could run Void on top of systemd but systemd doesn't appear to be in Void's repository.
> Void linux move from systemd to openrc
Actually no, they moved to runit. But there are some distros using OpenRC, notably Gentoo.
Just in case you find it interesting and haven't seen it, you might want to take a look at sinit at suckless.org. Now, that is a minimal init. It gets one thinking about what one wants to include in the init and what should be external to the init.
And, if you are interested, another init system to look at is runit ( http://smarden.org/runit/ ) which is used by Void Linux. I haven't looked at it myself, but it seems interesting.
After a brief look, it has 2 components, the service and the php. The service does the computation and the php serves up the web ui and interacts with the service.
In order to install it on a server you need to run the service with runit and copy the whole directory onto a server.
I can look into this more after work.
... The whole world doesn't revolve around systemd. I was talking about tools like Runit, S6 and OpenRC. Runit, for example, can be used as a service manager on top of an existing init system.
The non-systemd init is the hardest requirement to meet because systemd is everywhere. However, my recommendation is Void Linux, it uses the runit init system and it has a ports-like system that allows you to build packages from source in addition to its standard package manager. I've been using it on my laptop for a couple weeks now and experimenting with it on VMs for a while before that, it's honestly a pretty nice setup.
systemd people often portray complaints about systemd as occupying a binarity between legacy/greybeard and new/innovative, but systemd is but one of a number of new/non-legacy init systems. runit (used by Void), for instance, is new init system, and works very well. s6 is another.
There are of course good ideas in systemd, but it seems to become more and more byzantine over time (which sets the stage for potential fragility). systemd is also mainstream at this point, which of course has its advantages, but it also stands out in your list for that reason. (And, as /u/cruxmostsimple points out, systemd expects glibc rather than musl.)
I'm not sure what the anti-GNU angle is though. Plenty of good GNU software out there.
Creating a finish
file with ExecStop
's contents should do the trick.
Simple question: does running the run
script on the terminal (by itself, ./run
) give you back control immediately? Then that's what's called a forking daemon, and it requires differently handling on runit (if you have to type Ctrl+C to get your terminal back, though, the service runs on the foreground and your script will work, most likely).
The official Void repositories aren't quite as minimal as the Arch repos IIRC. I used Arch for a while, and experienced a lot of breakage stemming from outdated AUR packages. I don't have to be so vigilant with Void since the packages I want are in the official repos and are managed with the same scrutiny.
This might have changed for Arch though, it was probably a decade ago since I last used it.
Then there's the init and service supervision system which is simple and great. I've used systemd professionally for years now and there are still things I don't understand about it. Void uses runit which I'd only used on some embedded systems before but knew from that experience was dead simple and relaiable with no nonsense. It's the reason I decided to try Void in the first place.
I use Debian (workstation and servers) and Void (home desktop) now. I probably wouldn't use Void on a server because there's a lot of value in Debian's widespread deployment and repository management strategy. But for a desktop PC it's a great choice.
I have not used Devuan, but I do love runit a lot. To make a service available to be started create a link from /etc/sv
to /var/service
. To start a service use sv
(i.e. sv start my-service
, and so on for enabling, stoping, etc). Writing services is EXTREMELY easy under runit as well! Here is a quick guide.
I have combined the guides from the arch wiki, void docs and runit docs as independently none of the above provided a completely operational setup.
Create a directory under /etc/sv
, mine is titled runsvdir-<username>
. Make a run
file with the following content:
```
exec 2>&1
user_groups="$(id -Gn <username> | tr ' ' ':')"
exec chpst -u "<username>:$user_groups" runsvdir -P home/<username>/.local/var/service
Also make a `finish` script here in order to make runit succesfully terminate your services during shutdown:
sv -w600 force-stop /home/<username>/.local/var/service/*sv
exit /home/<username>/.local/var/service/*
``
Make both of these executable,
755permissions should be alright. Symlink this folder into
/var/service/` and it should be operational at this point.
You can the create the directory ~/.local/var/service
and create user scripts here or symlink them into this directory from somewhere else. (Make sure to provide full path to the linket service folder!)
Let me know if you have any further questions!
About my initial topic, I have settled for launching mpd
and pulseaudio
from my window manager's config.
I like runit. Very similar to daemontools. It's used as PID1 in Void Linux, so it's well tested. Service scripts are usually one liners (not including the shebang). AFAIK it works as an init replacement on most *NIX systems.
It's not quite an answer to what you asked, but I've had a fair amount of luck with logging to stdout/stderr and using runit's svlogd to collect those.
For context, I generally like to allow operational concerns to be handled by the deployment environment; but then again, that's evidently not how everyone sees these things.
After hopping from NixOS (like, yesterday), I don't think I'll go back or switch again. Void Linux uses runit which in my experience is faster than both systemd and OpenRC in terms of boot time, and xbps is a quite good package manager.
Generally all you have to do when you install a new service with Void you just make a symlink between /etc/sv/your_service
and /var/service
and then do sv start your_service
or sv u your_service
(u is up). There's also this FAQ if anyone is curious.
Yep. A lot of people agree PID 1 should have as little code as possible. This article talks about the size of systemd as PID1, which is 1.8 MiB. On my system, runit is 740 KB, just under sysvinit's size, and according to this, runit is only 330 LoC.
>PID 1 is special in that, if it crashes, the system crashes. Thus, some feel that it's preferable to have as little code as possible in it.
>In my experience SysV init scripts were easier to write, and easier to maintain.
Have you taken a look at OpenRC or runit?
One of the differences between the two is that OpenRC has true dependencies. runit can only make sure that service A runs before service B, which is usually good enough, but it won't stop service A if you stop service B, unless you do that in the finish
script. That being said, I like runit's use of named pipes for supervision, although the downside is it requires memory for each process supervisor.
I agree unit-file-to-sysvinit-rcfile has a limited realistic potential. To be honest, even if it could be done I don't even think it'd make that many people happy - while there are certainly some who seem to like sysv largely because it is battle-tested and/or don't like change, from what I gather many more just don't like the specific systemd change, but didn't like sysv either. It's got to be frustrating to be in that group, some kind of out-of-the-frying-pan-into-the-fire kinda thing.
Another closely related option would be to get all the notable init people to try to work together here (which is arguably even less realistic) to make another standard that is sufficiently flexible that it could be used to generate the specific other init system configuration. This too would have issues - I expect the equivalent of #ifdef
's would be required, and the benefits of any given init config format in terms of ease-of-writing would be lost in this new inevitably ungainly standard.
If there's a good way to make it so that distro maintainers will only have to write one, clean init config that magically works on multiple inits exists, I'm totally missing it.
If that's the only issue for non-systemd people, though, I think it's a realistically managable one. Alternative inits could provide distro-agnostic scripts, such as how runit does it. The non-systemd crowd could manage their own here. If it works well enough, it runit-scripts
or the equivalent could be its own package the way manpages is.
uptime
and /proc/uptime
start counting from the when the kernel is initialized (i.e., just after the bootloader). If you make a service which depends on whichever service you consider sufficient for your system to have booted (e.g., a getty or a display manager or whatever) and tell it to cat /proc/uptime
and log it somewhere, then you'll know. I'm guessing logging uptime
would just tell you the system's been running for 0 minutes, but /proc/uptime
should be accurate to 10 ms or something. The procedure for creating something like this seems fairly straightforward:
runit is a cross-platform Unix init scheme with service supervision, a replacement for sysvinit, and other init schemes. It runs on GNU/Linux, **BSD, **MacOSX, **Solaris*, and can easily be adapted to other Unix operating systems.
sv - control and manage services monitored by runsv(8)
Void uses runit as PID 1 and the service manager. runit is 300 lines of code if I remember correctly. It's not very hard to audit 300 lines of code if I remember correctly. runit calls runsvdir which scans directories in /var/service
(you can also specify a directory if you're running it for your own user for example) which runs runsv for each directory.
http://smarden.org/runit/
What I just stated about how runit chains into runsvdir which chains into runsv is reminiscent of the UNIX philosophy and functional programming. You don't write this one big program to do everything. You write very small functions that do one thing well and you compose them or combine them to get larger functionality. As the user, you might think this is a trivial difference because you're not a software developer. But I'd argue it leads for more robust software and easier debugging.
Find whatever command is being run by the vyrvpn.service
file from systemd and turn it into a runit service.
http://smarden.org/runit/faq.html#create
You basically just need a file called run
to reside in /etc/sv/$SVC_NAME
and be executable. Usually this takes the form of a shell script that just launches whatever daemon.
ex:
#!/bin/sh -e sv check dbus #if, for example, your daemon depends on another daemon, in this case dbus. not often required [ -r conf ] && . ./conf #to load environment variables from a file called "conf", if it exists. not often required, can be used to load command-line options by defining them as a variable exec daemon-program-here $OPTS #finally, actually start the program. if $OPTS was defined in ./conf, it will be passed to the daemon as command line flags
simpler example, if your daemon has no dependencies and doesn't need any environment variables passed to it:
#!/bin/sh -e exec daemon-program
Yes, its not build by default and not mentioned in any documentation. The only references are in http://smarden.org/runit1/, notice the 1 in the url and:
> This package is obsolete, see here for the current stable release of runit.
and http://smarden.org/runit/upgrade.html:
> 1.3.x to 1.4.0 or 1.4.1
> With this version the runsvctrl, runsvstat, svwaitdown, and svwaitup programs no longer are being installed, the functionality of these programs has been incorporated into the sv program. The documentation now suggest to put service directories by default into the /etc/sv/ directory, and a list of frequently asked questions with answers has been added. The chpst program understands a new option -d to limit memory of the data segment per process.
Systemd allows for fully declarative unit files; OpenRC cannot guarantee that (I understand that some initscripts can be reduced to a shebang and a single command= stanza and suchlike, but systemd units are still more stringent). You have resources like https://github.com/OpenRC/openrc/blob/master/service-script-guide.md say stuff like
> PID files should be writable only by root
and that's what I shouldn't have to care about when i want to spawn a process which may or may not spawn other stuffs and still keep everything tidy, controllable and limitable in a (c)group hierarchy. Similar for runit (http://smarden.org/runit/runscripts.html#apache); I should not have to think about what exec
implies in a service definition.
That still puts systemd and openrc, runit, etc in different classes.
Thank you for the detailed answer!
How do I make the process use syslog / socklog?
The runit FAQ suggests something along the lines of
exec chpst -ulog svlogd -tt ./main
in log/run
. How can I adjust this to make it work with socklog?
That's an excellent news. Is it possible to push your changes upstream, so we could have a pic32 support right in the official u-boot release?
Systemd with all it's components takes almost 10Mb of resident memory. May be replacing it with runit would help, like in Void Linux.
Most of tools fit fine into 32Mb, except apt. May be we just need some replacement with a low footprint. Does Microchip have plans to extend the mz-da family by adding more memory on the chip? They already have a few Cortex-A5 based chips with 64 and 128 Mbytes of internal DDR2.
I installed void on a Toshiba Satellite of 2002 (wm: openbox, editor: vim, browser: netsurf/w3m). It uses ~60/256mb of RAM, it's an excellent operating system.
There are many distros valid for low performance devices (Debian, Arch Labs, Puppy Linux are just a few) but void offers good stability, by its nature (like Arch or Gentoo etc.) requires some practice for management and documentation is lacking (but you can help with research on other manuals (like runit documentation) and "adapting" guides of the Arch/Gentoo wikis.
I can't claim to be an expert in how all of this works under the hood, but AFAIK runit (which termux-services uses) can be used instead of systemd. Runit is way older than systemd though so perhaps mostly used in niche environments today.
Regarding
>In regards to the way the services run on "foreground" for logging to be available, what about coprocessing the service through a subshell, and writing any stout to a file descriptor? I believe that, by calling a service such as sshd as a coprocess, will still allow the server to run and accept incoming connections.
What do you want to achieve here?
For template guidelines have a look at all the scripts at the upstream site: http://smarden.org/runit/runscripts.html and at other places. Most of them are very similar, start the program in foreground and perhaps redirect 2>&1
yeah.. uh.. I honestly don’t know. it might.
this might be able to do that
http://smarden.org/runit/svlogd.8.html
it is much faster though, like seriously noticable. like half the services need to start than on systemd.
In addition to runit, there's also GNU Shepherd and s6 . I haven't had a chance to do much with s6, but I've used both runit and Shepherd fairly extensively and they're both excellent. They work very well (and don't hang my system when I need to reboot/shutdown; an issue I've had with other inits). A bit I always appreciate from the Shepherd manual:
> .... If something goes wrong, it is usually better to tell the user about the problem and let her fix it, taking care to make finding solutions or workarounds for problems (like a misconfigured service) easy. This way, the user is in control of what happens and we can keep the implementation simple. To make a long story short, we don’t try to be too clever, which is usually a good idea in developing software.
There is runit [http://smarden.org/runit/] , which is the default init system that comes with Void Linux, it's quite simple and that's what i was looking for in my work/home laptop, for servers i use the default which is systemd these days
You obviously don't know what you're talking about. I'm not talking about a shell script that's mostly boilerplate like with SysV.
The entire contents of /etc/sv/pcscd/run
is
#!/bin/sh exec pcscd -f
Here are a lot more examples.
amongst others. I get very tired of hearing comments like /u/PBLKGodofGrunts , which are the equivalent of:
> Horse-and-buggies died out as a reasonable means of transport years ago. Ford is the clear victor.
Because, obviously there aren't any other car companies and anyone questioning Ford's safety record must want a return to horse-and-buggy transport.
btw runit has excellent per-process logging capabilities that offer stdout capture with some interesting configuration features such as:
This is amazing, thank you! I learned quite some things just checking your scripts. I'm actually a lot less knowledgeable on this topic than you might have thought, and although those scripts will be tremendously useful, my problem is a little different from getting a getty script to work. At the time Smarden's tutorial was done, Debian used to have SysV, so his tutorial is based on that; Artix gives you the possibility of using both openRC or runit, but it comes with openRC as default; and Void already comes with runit. Problem is, according to this section of Smarden's tutorial:
>Step 3: The getties
>
>At least one getty must run in stage 2 so that you are able to login. Choose a free tty, say tty5, where sysvinit is not running any getty (edit /etc/inittab and kill -HUP 1 if needed), and tell runsvdir about the getty-5 service: [...]
I believe it means at least some getties are already assigned to the init used (SysV, SystemD and I'm guessing openRC as well)...? I think I'd need to disconnect the getty from its init before using it with runit, but I don't know how to search for this, so I can't really make use of Debian or Artix here, and Void wouldn't have it assigned to begin with. Artix somehow works just by installing runit and removing openRC and some more things, but I think this happens because the devs already handled this getty issue?
Simpler and less error prone to have a watchdog or system init program handle the startup and restart cases for you. That plus a health check endpoint can work pretty well.
See runit for example. monit is also heavily used (though I've run into enough problems with it that I probably wouldn't deploy it specifically).
I agree with /u/YMK1234 and /u/mishagale re: multiple instances plus load balancers. Depending on the architecture, instead of load balancers you might have servers register themselves with a coordination service using ethereal nodes so that when they go down they're deregistered.
I'd say yes, considering the sense of humor that developers normally have (and the weird names they give to things).
However, if I had to make something up based on this, maybe it means replacement unix init? I mean, it's not stated there but it would fit quite nicely considering the description of runit they have on that site.
Well, remember that there are different paradigms there. You could easily use daemontools or runit simply "plugged in" to traditional sysv (or other inits) just by launching them: http://smarden.org/runit/useinit.html
I regularly run daemontools launched via a standard sysv-style init script on RHEL/CentOS.
I guess that's kind of the point" "systemd" is an all-encompassing paradigm. Prior to that, you could mix and match whatever you wanted in many cases. Hell, if someone really wanted to, they could probably find a way to run the rest of the RH "setup" initscripts as an xinetd config..
If you're asking for "something that tries to do everything that systemd is doing, and is doing it as a single package, but isn't systemd," then I'm not sure there's an answer for you on the Linux side. launchd is probably the closest, but the Mac OS X startup is an entirely different beast anyway.
Your edit reads, to me, like "Docker Supervisor" is a component of docker itself - they're just describing running supervisord in the container.
You could also use runit or any other "init replacement" script/tool you'd like, although it's debatable wether or not you should, vs sticking to the design principles of docker/micro-services, which prefer to "do one thing and do it well"... rabble rabble rabble
Otherwise, nice narrative style.
Quatch argument, there are many service managers that do not do dbus but keep it as simple as writing single characters to a fifo.
But please, tell me how this is wrong or is dbus.
PID 1 is a special process for the Linux kernel. If this process returns, or crash, then whole system panics and goes down, which means it can't be restarted (I'm probably not teaching you anything here).
To make this special process more reliable and unlikely to break, I think it should only handle the bare minimum: Adopting orphans, and bringing the system up/down.
All other tasks should be managed by sub processes. You could totally have a systemd-daemon
process that would be the parent of all your services, so it could open sockets for them, changed the UID/GID they run in, watch/restart them when necessary and so on. In case this systemd-daemon
crash, sure, that would bring all your services down, but that's also true if PID 1 crashes (it would be worse).
I like runit's take on this. runit
is the init process, runsvdir
is the parent of all services, and runsv
is a wrapper around each process. This hierarchy allow simple management of each service, PID tracking and it makes each service ownderfully simple to write, as the "service script" is a shell script that is only supposed to start the process. To take my example of thttpd again:
#!/bin/sh exec 2>&1 exec thttpd -C /etc/thttpd.conf
And that's all. You can hardly make simpler. And as runsvdir
and runvz
taking care of the PID, restart/reload are handled PID wise without problem.
yup, kind of dumbed down service manager that restarts them every time they stop and most setup is done via single bash script.
http://smarden.org/runit/sv.8.html
obviously, systemd can do all that, but production here is still at debian 6.
Use runit or daemontools.
Quickstart:
mkdir /etc/sv/tool echo 'exec program' > /etc/sv/tool/run chmod +x /etc/sv/tool/run ln -s /etc/sv/tool /service/tool # use /etc/service for runit
What should PID 1 do if PID 2 dies ?
runit follows the design of PID 1 doing nothing but reaping zombies and spawning children to handle the different stages; during stage 2, runsvdir is the program supervising services. But even runit's pid 1 restarts runsvdir if it crashes or exits 111; runit only enters stage 3 when runsvdir exits normally. It's simple, it's basic, but it's still supervision - and so the tree is rooted in process 1. That's all there is to it.
What about djb's daemontools and descendants such as runit and s6? Wikipedia claims daemontools is over 12 years old, and has an excellent and very Unix-y design in my opinion.
The s6 pages include nice overviews of a few different supervisors. I know systemd brings more features to the table; is there a nice summary of what those are? (I don't care about systemd vs. sysV init; more about systemd vs. s6. I also don't care about FHS vs. /package.)