busybox - init system

Forum rules
General talk about software - if the program is not in the repos, please links to the developer's page or github.
pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

busybox - init system

Unread post by pidsley » Mon Jun 09, 2014 8:08 pm

Most of you know that I have been using busybox as init for my low-memory scrots, and you may have wanted to try it. It is relatively easy.

I learned how to do this by reading this topic on the Arch board: https://bbs.archlinux.org/viewtopic.php?id=162606&p=1

I shamelessly stole ideas and code from hut's "minirc" repo here: https://github.com/hut/minirc

Hut's code is designed for Arch, and it is a bit more complicated than I needed, so I made some changes to make it work on my Debian systems. My modified code is available on my github. You should really read the Arch thread and hut's rc script to see how he does the more complicated stuff.

Please only try this on a test install that can be allowed to break beyond repair. Please. I also highly recommend that you create a separate GRUB entry for systemd (add init=/lib/systemd/systemd to the kernel boot line) so you can still boot with systemd if busybox breaks badly.

Still ready to try it? As Ivan says, "let's begin."

This is all based on the Spring BBQ spin. It should work on any spin based on Spring, and most anything on sid, but no promises.

Hut has an installer script, and I thought about writing one or modifying his, but I want to make you do things manually so you know what has been done -- this will make it easier to revert the changes later when things break.

First, get my minirc code:

Code: Select all

git clone https://github.com/pidsley/minirc
(You really only need the inittab-busybox and rc files, so if you just want to grab those from the github, do that instead.)

Open the "rc" script in your favorite editor. You will see that it is just a simple script that starts and stops services. Right now, it is only configured to save and restore alsa and start a static wired network interface. If you want to use dhcp, wireless or add other services you will have to modify the code. Modifying the script should not be difficult, but you are on your own. See hut's script for ideas for other services. If you add any service scripts, please post the code!

Now, let's save the existing init and inittab, before we replace them:

Code: Select all

# cp /etc/inittab /etc/inittab-sysv
# mv /sbin/init /sbin/init-sysv
Finally, we make busybox our init, and copy the new inittab and rc script to their directories:

Code: Select all

# ln -s /bin/busybox /sbin/init
# cp minirc/inittab-busybox /etc/inittab
# cp minirc/rc /sbin
Now theoretically we are ready to reboot, but we must use the "-f" flag on reboot to force the reboot, because we changed the init system in the middle of the session:

Code: Select all

$ sudo reboot -f
Cross your fingers and hope for the best. The network may still be broken because of some resolv.conf confusion, but I will let you explore that for yourself. If things are hopelessly broken you may need to boot a live USB and mount the root partition so you can edit /sbin/rc (or boot your systemd GRUB entry if you followed my advice). You can always move the saved inittab and init back where they were and revert to sysv-init.

Once busybox is running as init, when you want to reboot or shutdown you must call busybox to do this; for example:

Code: Select all

$ sudo busybox poweroff
Of course you can create aliases or symlinks to make this easier.

Don't worry about the mdev.conf and xorg stuff in the minirc github; that's for later, when we switch from udev to mdev.

Image

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: busybox - init system

Unread post by GekkoP » Mon Jun 09, 2014 8:18 pm

Thank you very much for this one. I'm going to try it asap.

pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

Re: busybox - init system

Unread post by pidsley » Mon Jun 09, 2014 8:24 pm

I know you have been waiting for it -- I've put it off so far because there are many ways to make this fail, and I didn't want to be held responsible. ;) Let us know how it goes.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: busybox - init system

Unread post by GekkoP » Mon Jun 09, 2014 8:30 pm

I'll follow your guidelines exactly. I'm going to do it on the Pentium 4. It's just for testing and random experiments so nothing important on it I might break. ;)

User avatar
rhowaldt
Dog
Posts: 4565
Joined: Wed Oct 17, 2012 9:01 am
Contact:

Re: busybox - init system

Unread post by rhowaldt » Mon Jun 09, 2014 8:49 pm

pidsley, while this is definitely nothing i will ever try, i applaud your elaborate postings on the subject.
All statements are true in some sense, false in some sense, meaningless in some sense, true and false in some sense, true and meaningless in some sense, false and meaningless in some sense, and true and false and meaningless in some sense.

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: busybox - init system

Unread post by machinebacon » Mon Jun 09, 2014 9:08 pm

How could I miss this post? Pid, great write-up, thanks a lot!
..gnutella..

pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

Re: busybox - init system

Unread post by pidsley » Mon Jun 09, 2014 9:30 pm

You're all welcome.

And for those still wondering WTF is this busybox thing?
http://www.busybox.net/about.html
https://en.wikipedia.org/wiki/BusyBox
http://www.busybox.net/downloads/BusyBox.html

Cool thing is that Debian already uses it in early boot, so it's in all the spins. No bloat required.

It is possible to replace coreutils with their busybox equivalents, and even to build a system consisting of nothing but busybox and a kernel: http://linuxbbq.org/bbs/viewtopic.php?p=14888#p14888

User avatar
rust collector
Motörhead
Posts: 536
Joined: Mon Jan 13, 2014 3:56 pm
Location: no_nb

Re: busybox - init system

Unread post by rust collector » Mon Jun 09, 2014 11:15 pm

Thanks very much, I have been looking at this for a long time, but never really got anywhere.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: busybox - init system

Unread post by GekkoP » Tue Jun 10, 2014 8:36 am

Image

Works good here. Just follow the instructions and be happy. Thanks again for sharing this, I'll read about starting other services later.

pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

Re: busybox - init system

Unread post by pidsley » Tue Jun 10, 2014 9:40 am

Very cool GekkoP. If you get any other services running, please post the code.

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: busybox - init system

Unread post by machinebacon » Tue Jun 10, 2014 9:54 am

Made it happen, and go dhclient to work (and fixed the resolvconf problem)

Thanks for the instructions. Seems to work well on this old box :)
Attachments
busy.png
..gnutella..

pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

Re: busybox - init system

Unread post by pidsley » Tue Jun 10, 2014 1:14 pm

Nice bacon. Thanks for testing. If you write or modify any services, please post the code!

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: busybox - init system

Unread post by GekkoP » Tue Jun 10, 2014 2:16 pm

dhclient in action.
Image
I'm enjoying this experiment very much, as you all can already tell. :)

pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

Re: busybox - init system

Unread post by pidsley » Tue Jun 10, 2014 2:30 pm

^ Great! Keep it around for a while if you can -- it should work with spark and sinit with only minor modifications. I'll try to do some testing this week.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: busybox - init system

Unread post by GekkoP » Tue Jun 10, 2014 2:34 pm

^ oh yes, it'll be there for a while. At least until your next guide ;)

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: busybox - init system

Unread post by machinebacon » Tue Jun 10, 2014 4:11 pm

I added the gpm as service:

Code: Select all

service_start() {
    echo_color 2 starting "$1"...
    case "$1" in
    gpm)
        gpm;;
    alsa)
        alsactl restore;;
    network)
        if ip link | grep -Fq $NETWORK_INTERFACE; then :; else
            echo_color $COLOR "waiting for $NETWORK_INTERFACE to settle..."
            for i in $(seq 100); do
                ip link | grep -Fq $NETWORK_INTERFACE && break
                sleep 0.1
            done
        fi
        /bin/ip addr add $NETWORK_ADDRESS dev $NETWORK_INTERFACE
        /bin/ip link set $NETWORK_INTERFACE up
        /bin/ip route add default via $NETWORK_GATEWAY;;
    dhclient)
        if ip link | grep -Fq $NETWORK_INTERFACE; then :; else
            echo_color $COLOR "waiting for $NETWORK_INTERFACE to settle..."
            for i in $(seq 100); do
                ip link | grep -Fq $NETWORK_INTERFACE && break
                sleep 0.1
            done
        fi
        dhclient $NETWORK_INTERFACE;;
    *)
        # fallback: start the command
        echo_color 1 'no start service handler found for ' "$1"
        "$1";;
    esac
}

service_stop() {
    echo_color 1 stopping "$1"...
    case "$1" in
    gpm)
        gpm -k;;
    alsa)
        alsactl store;;
    network)
        /sbin/ip route del default
        /sbin/ip link set $NETWORK_INTERFACE down
        /sbin/ip addr del $NETWORK_ADDRESS dev $NETWORK_INTERFACE
        /sbin/ip link set lo down
        /sbin/ip addr del 127.0.0.1/8 dev lo;;
    *)
        # fallback: kill all processes with the name of the command
        echo_color 1 'no stop service handler found for ' "$1"
        echo_color 1 'attempting killall '$1
        killall "$1";;
    esac
}
not quite sure if it should be in this file or rather be a separated script somewhere. The github says:
To add another service, simply add it to the respective variable. If you don't
specify anything else -- and this is indeed enough for most services -- minirc
has certain standard behaviors for starting, stopping and polling a service
with the name $service: ...
..gnutella..

pidsley
Hermit
Posts: 2539
Joined: Wed Oct 17, 2012 12:31 pm

Re: busybox - init system

Unread post by pidsley » Tue Jun 10, 2014 4:21 pm

I think it's fine right where it is. Thanks for adding it.

I think what the github means is that if you don't add a handler for something, and just add it to the SERVICES variable, start and stop fall through the case statement to the fallback, which would probably work for most simple services like gpm. Others that need more complicated code can be added to the case statement like you did. Either way is fine, but your way means we see explicitly what gets done when gpm starts and stops, and don't have to see the warning when the script can't find a handler for gpm. This is better, IMO.

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: busybox - init system

Unread post by machinebacon » Tue Jun 10, 2014 4:33 pm

OK I see, thanks pid!

Now I just have to find out how to make something be started as normal user (for example bbq instead of root). Example: emacs --daemon should be started, but not as root, else emacsclient cannot connect. Even sysvinit failed to do this.

Probably I write an external script for the start. Stopping is quite easy ;)
..gnutella..

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: busybox - init system

Unread post by machinebacon » Tue Jun 10, 2014 4:37 pm

Oh that was too easy:

Code: Select all

bbq@grill:~$ cat /sbin/rc|grep emacs
    emacs)
        su bbq -c "emacs --daemon";;
    emacs)
        killall emacs;;
connect to emacs with emacsclient -nw
..gnutella..

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: busybox - init system

Unread post by machinebacon » Tue Jun 10, 2014 4:54 pm

and one for urxvt:

Code: Select all

    urxvt)
        su bbq -c "urxvtd -q -f -o";;
    urxvt)
        killall urxvtd;;
connect to it with urxvtc
..gnutella..

Post Reply