:: Re: [DNG] Custom OS initiator. In n…
Top Page
Delete this message
Reply to this message
Author: Steve Litt
Date:  
To: dng
Subject: Re: [DNG] Custom OS initiator. In need of some hints...
On Mon, 13 Jun 2016 08:16:44 +0200
Edward Bartolo <edbarx@???> wrote:

> Hi,
>
> This is a question about implementing a minimal OS initiator. If
> DNG's admins/mods deem this email is misplaced please delete it or
> ignore it.
>
> Till now, I implemented a little OS initiator that calls "/bin/bash"
> and then enters an infinite while loop that does nothing. The loop's
> purpose is to prevent PID 1 from exiting.
>
> I would like to have my OS initiator:
> a) initiate a terminal before launching it. /sbin/init launches six
> such terminals tty1..tty6
> b) prevent this terminal from closing
> c) do some basic child process management
>


Edward, it sounds to me like you're building your own PID1 as a
shellscript. If this is true, I salute you!

Learning the ins and outs of PID1 and its relation to the rest of the
init system is a process, and that process starts with the 16 lines
(not counting blank lines) of C code at the bottom of the following
post:

http://ewontfix.com/14/

Your first task is to implement that in either sh or csh, and
personally, I think it's very possible.

You can look up the details of the C calls: They mostly relate to
dealing with signals. Here are a few high level guides to this code:

* See if (fork()) for (;;) wait(&status); ? That code is the infinite
loop that keeps PID1 running forever, in a loop checking for new
signals.

* if (fork()) for (;;) wait(&status); splits the process into two
processes: PID1 and a child. PID1 spins forever checking signals,
while the child process drops through and eventually execs /etc/rc,
or whatever you want to call the shellscript that handles bringing up
processes. Your six tty1 thru tty6 get brought up by /etc/rc, NOT by
PID1.

* In my opinion, the best way to handle /etc/rc is to have it first do
a few preliminary one-time early bringups, such as udev/vdev/eudev
and maybe the network. Then /etc/rc can hand over control to either
runit or s6, to supervise forever type processes such as tty1 thru
tty6.

* In my opinion, runit and s6 are so good that there's no use you or
anyone else trying to write a replacement for them. Stick to
rewriting PID1, in bash, and when you get it finished, please
publicize it widely so others can follow in your footsteps.

* You're not done when you've written /etc/rc and had it invoke runit
or s6. You still need to write a shutdown shellscript. This script
would do any special ordered shutdown such as downing apps before
databases, databases before the network, etc. The final several lines
of most home-brew shutdown scripts look something like the
following, to guaranty you won't need an fsck or a journal recover
after each reboot:

    killall5 -15; sleep 2 # Ask nicely
    killall5 -9; sleep 2  # They didn't comply, so murder them
    sync                  # Get everything written to disk
    swapoff -a            # Cleanly shut down swap
    umount -a             # Unmount everything
    mount -o remount,ro /dev/sda1  # System now readonly
                                   # Safe to halt
    /sbin/halt            # Or /sbin/reboot


* The shutdown script must be run manually to shut down, and doesn't
respond to Ctrl+Alt+Del. Later, when you make your PID1 shellscript
more like Suckless Init, it can respond to Ctrl+Alt+Del and to
reboot signals.

* Rich Felker's 16 line PID1 doesn't react to signals, it just dumps
them on the floor. Later, when you've mastered Felker's algorithm,
you can look at Suckless Init, an 83 line C program that does pretty
much what Felker's program does, except it also handles appropriate
signals and reaps zombies. But get Felker's working in /bin/sh first.

If I were in your shoes (and actually I have been), for
experimentation's sake I'd compile Rich Felker's init, possibly
changing the location of the rc file, and call the compiled result /f

By using the short name /f, it becomes very easy upon Grub to change
the init to /f, and init to Felker.

Next, I would have /etc/rc do nothing but run /bin/bash, or for
Poetterized directory systems /usr/bin/sh. All this does is brings up a
shell, in tty1, for you to look around. It's a proof of concept. With
this bash shell on tty1 as a periscope, start trying mount -a and other
stuff, find out what goes wrong, and make a shellscript to properly
mount and instantiate things. Obviously, with this being experimental,
you should have no encryption nor LVM nor RAID, and to the best of your
ability, have a one partition filesystem plus a swap partition.

Next I'd make my shutdown script, and make sure when shut down by the
shutdown script, the next reboot invokes neither fsck nor journal
recovery.

Then I'd integrate either runit or s6, calling it from /etc/rc or the
shellscript invoked by /etc/rc to get everything mounted.

Then I'd fool around with the system for awhile, making sure it's
useable to a degree.

Then I'd code a shellscript plug replacement for the Felker PID1, plug
it in, and see if it works.

Once that happens, I'd exchange the Suckless Init PID1 for your
shellscript PID1, and verify that works the same as yours did. BE SURE
that it spawns the same rc file as yours did.

Then I'd write a shellscript workalike for Suckless Init. In my
opinion, once you've done that, you should publicize it like the Autumn
leaves, because you've done a service to all of Linuxdom, and you've
especially done a service to Devuan, whose root story is that init
should be simple. I'm not saying Devuan should use your init: I'm
saying that your init gives tremendous credibility to Devuan, and
increases skepticism of Systemd.

SteveT

Steve Litt
June 2016 featured book: Troubleshooting: Why Bother?
http://www.troubleshooters.com/twb