RC in C

26 Jan 2007 • 3 min read

Every Gentooer knows RC - or rather /sbin/rc.It's the tool that handles the initial boot and then starts and stops services depending on the runlevel desired. It's also primarily written in bash. This is no bad thing, as it's a powerful shell, compared with say the standard sh shell from FreeBSD. But this is not without a price, and that price my friends is speed.baselayout-1.13 currently boots around 10 seconds faster than 1.12. This is purely because we moved the bash code that worked out service dependencies and ordering into a C program, rc-depend. Magnus Deininger (the author of eINIT) filed a bug requesting that our init scripts could call eINIT if that was running in place of sysvinit (our default). We discussed some things, and the end product is that we now have a small library in C that provides information about services, runlevels and their state. Infact, rc-depend is now just a front end to this library.Well, after having most of the basic foundations in a C library, and Vapier had already moved the system specific code out of RC for 1.12 it struck me that it wouldn't take that more more to have the entirety of RC in C. This has now been done, and my Gentoo/FreeBSD laptop is currently using it just fine. It doesn't yet support all the the bash functionality (parallel starts, interactive) but it does work :DFor you speed freaks out there it runs a full 0.5 seconds faster than RC in bash on a 2 Ghz laptop :jawdrop:Not much I know, but imagine a similar increase for each service as I intend to move most of runscript.sh into C runscript too. Now, this isn't ready for consumption yet, and won't be for sometime. I also don't intend this to ship in baselayout-1.13, although the library will so eINIT can use it but baselayout itself won't.And that's not the end goal either - once everything but our init scripts themselves are in C, there should be no more required reliance on bash itself. Current functions exposed by functions.sh (einfo, etc) are already built into C RC as mulitcall programs. The only issue with this is our lovely network scripts - purely because the user config is array based which is a bashism. The network scripts themselves use arrays very heavily and will have to be reworked a lot to work on other less powerful shells. I still think this needs to be done as running bash for every service on my Sparc64 is a major speed problem. Also, removing the bash requirement means that embedded devices would love us as bash is unsuitable for that environment.