Saturday, January 9, 2016

A comparison of alternatives to init(8) and rc(8)

(Full disclosure: I am the author of relaunchd, one of the projects being evaluated in this article)

There are several projects underway to create a new system initialization and service management framework for FreeBSD and other Unix-like systems. This article compares three of these projects:

The boot process

For the purpose of this discussion, the boot process can be broken into three stages:
  1. the boot loader, loader(8)
  2. the primordial process, init(8)
  3. the run control service, rc(8)
The functions of the boot loader will not be covered in this article.

The boot loader hands control to init, which has the following basic responsibilites:
  • enter single user mode, if requested
  • spawn a number of getty(8) terminals for the console
  • launch the rc mechanism
After performing its duties for the early part of the boot process, the init process continues running in the background to perform several other duties:
  • restarting getty if it dies
  • reaping orphaned child processes
  • waiting for a signal to reboot or shutdown the system
The rc mechanism is a set of shell scripts that determine what services to start, and in what order. Once everything has been started, the rc process terminates.

Problems with the current process

While the current init and rc mechanism are classic parts of the Unix design, there are several reasons why people are interested in replacing them:
  • reliability - if a service dies, the rc mechanism will not automatically restart it;
  • performance - services are started in a serial fashion, which is slow and does not take advantage of the parallelism of today's multi-core hardware;
  • security - the shell scripts that rc uses do not allow for the enhanced security features that are possible in other systems.
  • complexity - shell scripts are programs, which makes them more difficult to manage than simple configuration files used by most modern alternatives.
  • dependency management - the rc system requires service dependencies to be explicitly defined in each rc script. In many alternative systems, dependencies are automatically handled through mechanisms like socket activation.
  • features - the rc system has a stable interface which limits the ability to extend it with new features. It is only able to handle basic functions like starting, stopping, and checking if the service has died.

Proposed solutions

This article takes a look at three of the proposed solutions.

launchd

The NextBSD project has ported the original launchd from Apple, and offers a very close approximation to the experience of using launchd in OS X. One major difference is that within NextBSD, the launchd.plist(5) jobs are specified using JSON instead of XML.

To achieve this feat, the NextBSD developers wrote a Mach compatibility layer that allows launchd to use Mach IPC and (possibly) other features of Mach.

relaunchd

The relaunchd project has started from scratch and built a workalike to launchd without using any of the original code. It is not yet feature-complete, but a lot of progress has been made. It works under FreeBSD and Linux, and uses LibUCL to parse its configuration files.

Unlike the two other projects in this article, relaunchd is explicitly designed not to replace init(8) and rc(8). Instead, it is intended to provide additional features and benefits to users programs that want them, and to not disrupt the existing initialization and boot system. The idea is that programs will gradually see the benefits of switching to relaunchd management, and the number of things being managed under the traditional rc mechanism will gradually shrink to almost nothing.

nosh

The nosh project does not aim to be a clone of launchd; rather, it tries to take the best features of all of the modern rc/init replacements and combine them into a new system. It has compatibility shims for systemd, Solaris' SMF, Red Hat's chkconfig/service, and OpenBSD's rcctl.

nosh has also been designed to work with FreeBSD and Linux.

Feature comparison


The table below gives a quick comparison between the three projects:

  launchd relaunchd nosh
Replaces init(8) and runs as PID #1 Yes No Yes1
Replaces rc(8) and manages all services Yes No Yes1
IPC mechanism Mach ports None currently; planned support for DBus and libipc None
Configuration file format JSON JSON2 Custom scripting language
Compatibility shims for systemd and other init systems No No Yes
Process supervision YesPlanned, but not implemented Yes
Cron replacement YesPlanned, but not implemented No
Milestones and targets No No Yes
Built-in syslog replacement No No Yes
1. Nosh allows you to experiment with running alongside an existing init/rc mechanism, but the documentation implies this is not the goal of the project.
2. Technically, jobs could be defined in any format that LibUCL supports, which (currently) is JSON, YAML, and nginx-style.


12 comments:

  1. This post is mainly concerned with projects that are actively developed with FreeBSD in mind. In my opinion, runit is no longer being actively developed, and does not have a focus on FreeBSD support.

    If you are interested in the topic of init systems in general, a good place to start is https://en.m.wikipedia.org/wiki/Init#Replacements_for_init

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. you forgot the kernel in the boot process.

    ReplyDelete
    Replies
    1. Yes, I glossed over the details of the boot loader, which are primarily concerned with loading the kernel. The kernel is agnostic about init systems, so I felt it was not relevant to mention.

      Delete
  4. the rc system has one major strength.
    it is written in shell scripts. Some consider this a weakness, but in my experience it has saved my bacon many times. You can run the scripts on their own, you can modify them when they do something you don't want, and you can read them if you need to find out what they do. Any system that hopes to replace the rc system needs to be able to do these things. Hand editing is a must. A system could be some sort of hybrid, but teh flexibility of the rc system is hard to beat.

    ReplyDelete
    Replies
    1. Shell scripts are good for hand-editing, but they are terrible for editing with automated programs like Chef, Ansible, or Puppet. Take a look at the documentation for launchd.plist(5)
      It's pretty easy to understand what's going on there, and you can easily edit the job definition and make it do whatever you want.

      Delete
  5. Wow, this is fantastic. I was researching init systems a couple months ago.

    I really liked the simplicity of nosh but never got it running. It's a very eligant design. It's a system of script files based on a file system structure. I think it speaks best to Mr. Elschers concerns. However, it doesn't have the ability to delay service startup and all the other neat stuff that launchd can do.

    I assume the delayed startup feature in relaunchd is waiting for DBus IPC? Relaunchd makes the most sense to me because why would you want to carry around all that mach baggage?

    My biggest concern for FreeBSD is that Linux-first applications start becoming tightly coupled with systemd and *BSD and Minix3 and others will lose out in cross compatibility. I don't know if there is any foundation for my concern though because I don't know what "tightly coupled with systemd" really means yet.

    ReplyDelete
    Replies
    1. Within relaunchd, the concept of "delayed startup" might cover several different things, including:
      * DBus service activation
      * socket activation
      * cron(8) emulation
      * directory monitoring

      Most of these do not depend on DBus, so they are just waiting for spare developer cycles to implement them.

      Delete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. What about OpenRC?
    https://wiki.gentoo.org/wiki/OpenRC
    OpenRC is developed by Gentoo, but it is BSD licensed and default on two little known FreeBSD distributions

    PacBSD (https://pacbsd.org FreeBSD with Arch Linux userland) and Gentoo/FreeBSD https://wiki.gentoo.org/wiki/Gentoo_FreeBSD

    ReplyDelete
  8. IMHO, OpenRC does not offer a lot of advantages over the existing BSD rc(8) system. Changing init systems is a costly exercise, so I don't think it would be worth the effort to switch to something that isn't significantly better.

    OpenRC is basically a portable version of the classic System V init system, with a some improvements and new features. Under the hood, it's still a collection of shell scripts.

    ReplyDelete