Replacing rc(8) (Was: FreeBSD Boot Times)

Richard Yao ryao at gentoo.org
Wed Jun 20 16:51:34 UTC 2012


On 06/20/2012 11:28 AM, Wojciech Puchar wrote:
>> Hi all, I wanted to jump in here. My name is Daniel Robbins and I'm
>> the creator of Gentoo Linux and the original designer of the Gentoo
>> initscripts, which now exist in rewritten form as OpenRC. FreeBSD
>> inspired many of the concepts in Gentoo Linux.
>>
>> I see a great potential for collaboration here between Gentoo, Funtoo
>> (my current project, a derivative/fork of Gentoo), FreeBSD and OpenRC
>> (which is now an independently-managed project, distinct from the
>> upstream distros)
> stripped list of CC recipient - got too large.

Lets include the OpenRC developers in the conversation. Hopefully one of
them will add their two cents.

Note that I am not actually a part of the OpenRC development team. I do
stuff in Gentoo with ZFS (Linux), Clang and Gentoo FreeBSD.

>> There has been some suggestion of a boot-time shoot-out, and it makes
>> perfect sense to me that the OpenRC team would need to demonstrate the
>> benefits of OpenRC first, before FreeBSD devs devote time to looking
>> at OpenRC.
> 
> Whatever benefits are, and for sure they are think of this:
> 
> 1) can it be compatible with 20000 ports already made for FreeBSD, where
> many of them install rc.d scripts in CURRENT format.

I believe that any combination of 3 possibilities can be done:

1. We could try to modify OpenRC could be modified to work with FreeBSD
init scripts.
2. We could convert the FreeBSD init scripts to the OpenRC format. On
Gentoo FreeBSD, we use the same init scripts we use on Gentoo Linux, so
this has not gotten much attention, but there have been a few
exceptions. In particular, I have converted encswap with only minor changes.
3. We could adapt Gentoo's init scripts. In theory, they should not
require modifications. In practice, exceptions are possible.

> 2) is the problem 1 worth of slight improvement over already good, but
> certainly not perfect rc.d subsystem.

Code sharing among open source projects provides a deduplication of
work, which benefits everyone. Clang and ZFS are excellent examples of
this. Adoption of OpenRC in FreeBSD init system would enable us to pool
our resources, which should have similar benefits.

I will try to make time to write patches that import OpenRC into the
base system and then do some benchmarks. To be honest, I think that the
biggest advantage of OpenRC is the ease with which changes to the init
system's configuration are made.

Currently, you have 3 files that control things and what actually is
started is a juxaposition of them. With OpenRC, you can get a very
simple summary of what is started by doing `rc-update`. You can also
make changes such as adding sshd by doing `rc-update add sshd default`
or removing sshd by doing `rc-update remove sshd default`. It takes much
less time than typing out an editor command, finding the appropriate
entry (or making a new one), and making the change.

There is an open bug at Gentoo for a few init scripts that we are
missing. One is encswap and the conversion from FreeBSD's format to
OpenRC's format was quite simple:

https://bugs.gentoo.org/show_bug.cgi?id=420165

OpenRC init scripts lack much of the boiler plate code that FreeBSD's
init scripts contain. FreeBSD's syslogd init script is 72 lines in
length. OpenRC's syslogd init script is 19 lines in length and I
reproduce it below:

#!/sbin/runscript
# Copyright (c) 2007-2009 Roy Marples <roy at marples.name>
# Released under the 2-clause BSD license.

command=/usr/sbin/syslogd
command_args=$syslogd_args
case "$RC_UNAME" in
        FreeBSD|DragonFly)      pidfile=/var/run/syslog.pid;;
        *)                      pidfile=/var/run/syslogd.pid;;
esac
name="System Logger Daemon"

depend()
{
        provide logger
        use net newsyslog
        need localmount
        after bootmisc
}

There is clearly much more boilerplate code in the FreeBSD counterpart.
The syslogd script is unusually short for an OpenRC init script, so I
present pf for something a bit more representative:

#!/sbin/runscript
# Copyright (c) 2007-2009 Roy Marples <roy at marples.name>
# Released under the 2-clause BSD license.

name="Packet Filter"
: ${pf_conf:=${pf_rules:-/etc/pf.conf}}
required_files=$pf_conf

extra_commands="checkconfig showstatus"
extra_started_commands="reload"

depend() {
        need localmount
        keyword -jail
}

start()
{
        ebegin "Starting $name"
        if type kldload >/dev/null 2>&1; then
                kldload pf 2>/dev/null
        fi
        pfctl -q -F all
        pfctl -q -f "$pf_conf" $pf_args
        pfctl -q -e
        eend $?
}

stop()
{
        ebegin "Stopping $name"
        pfctl -q -d
        eend $?
}

checkconfig()
{
        ebegin "Checking $name configuration"
        pfctl -n -f "$pf_conf"
        eend $?
}

reload()
{
        ebegin "Reloading $name rules."
        pfctl -q -n -f "$pf_conf" && \
        {
                # Flush everything but existing state entries that way when
                # rules are read in, it doesn't break established
connections.
                pfctl -q -Fnat -Fqueue -Frules -FSources -Finfo -FTables
-Fosfp
                pfctl -q -f "$pf_conf" $pf_args
        }
        eend $?
}

showstatus()
{
        pfctl -s info
}

OpenRC's init script is 59 lines while FreeBSD's pf script is 72 lines
in length (just like syslogd). If you do a comparison, you should find
differences in length to be consistent. OpenRC has less boilerplate code.

Also, OpenRC abstracts common daemon starting/stopping functionality
into a start-stop-daemon command, which is implicitly executed in the
syslogd script. When `rc-status` is invoked, OpenRC is able to report
daemons that have crashed. Unfortunately, OpenRC currently does not
respond to such events in real time, but it should happen as soon as
someone writes that functionality.

> If someone would like to make new ports subsystem from scratch then it
> would be great. Would you like to ? ;)
> Certainly it will be great, as  ports are certainly a mess, but it's
> "quite" a hell amount of work!
> lets assume someone working of port subsystem would prepare 3 well done
> ports per day average, then you need 20 people working for it for a year
> at least...

I would very much like to see Gentoo's package manager rewritten in C
under a BSD license along with the ability to invoke the package manager
on ebuild files as is done in ports. Currently, it is in python, under
the GPL and invoking the package manager on ebuild files bypasses
dependency calculations.

When/If those things happen, I will be sure to let people on the hackers
mailing list know. For now, available development resources make that
impractical.


More information about the freebsd-hackers mailing list