On Sat, 09 May 2015 09:26:23 +0200
Didier Kryn <kryn@???> wrote:
> Le 08/05/2015 20:28, Steve Litt a écrit :
> > This email isn't a recommendation for the Devuan distribution, it's
> > just some interesting info for the more DIY members of the Devuan
> > community.
>
> Dear Steve,
>
> I think Devuan, being about freedom of choice and autonomy of
> admin, has something to do with DIY. And for this reason you can find
> some fans of it here :-)
Yes! This is one of the reasons I find Dng and Devuan so enjoyable. And
Devuan's removal of ridiculous dependencies makes DIY a lot easier.
> > The init program does initialization with no process management. It
> > passes control to rc.whatever. In that respect, it doesn't conform
> > to Laurent's minimum of supervising at least one process, but
> > rc.whatever can exec to something that manages all processes, so
> > you have only that one tiny process at risk.
>
> Do you know what that program is doing? And what of it cannot be
> done by a script?
>
> For me, the ideal DIY init is a script. I think the shell
> languages are just missing a high quality signal handling for scripts
> to be eligible as init. Adding the primitives to use the Linux
> signalfd in a shell language is maybe the only missing bit to reach
> that graal.
>
> Didier
Hi Didier,
I know what Suckless Init does to some degree, but until the systemd
debacle, I wasn't much of a systems programmer, so I don't understand
it all. Just for fun, I've put all 89 lines of Suckless Init at the
bottom of this email.
It looks to me like it spawns rc.whatever, then spins, listening for
signals, and if it finds a SIGUSR1, SIGINT, or SIGCHLD it "does the
right thing", which for poweroff and reboot is to call rc.shutdown with
the proper argument. It's up to rc.shutdown to achieve the reboot or
poweroff with the proper reboot or halt command, "proper" meaning
invoking it so that it's not simply an intermediary to /sbin/shutdown.
And before calling reboot or halt, it's up to rc.shutdown to kill all
processes.
So process management, which is the majority of what sysvinit or
systemd would call "init", is done by rc.whatever, which can be, and
probably is, a shellscript.
SteveT
Steve Litt
May 2015 featured book: Quit Joblessness: Start Your Own Business
http://www.troubleshooters.com/startbiz
/* See LICENSE file for copyright and license details. */
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define LEN(x) (sizeof (x) / sizeof *(x))
static void sigpoweroff(void);
static void sigreap(void);
static void sigreboot(void);
static void spawn(char *const []);
static struct {
int sig;
void (*handler)(void);
} sigmap[] = {
{ SIGUSR1, sigpoweroff },
{ SIGCHLD, sigreap },
{ SIGINT, sigreboot },
};
#include "config.h"
static sigset_t set;
int
main(void)
{
int sig;
size_t i;
if (getpid() != 1)
return EXIT_FAILURE;
chdir("/");
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, NULL);
spawn(rcinitcmd);
while (1) {
sigwait(&set, &sig);
for (i = 0; i < LEN(sigmap); i++) {
if (sigmap[i].sig == sig) {
sigmap[i].handler();
break;
}
}
}
/* not reachable */
return EXIT_SUCCESS;
}
static void
sigpoweroff(void)
{
spawn(rcpoweroffcmd);
}
static void
sigreap(void)
{
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}
static void
sigreboot(void)
{
spawn(rcrebootcmd);
}
static void
spawn(char *const argv[])
{
pid_t pid;
pid = fork();
if (pid < 0) {
perror("fork");
} else if (pid == 0) {
sigprocmask(SIG_UNBLOCK, &set, NULL);
setsid();
execvp(argv[0], argv);
perror("execvp");
_exit(EXIT_FAILURE);
}
}