Escape from System D

Episode I: It’s obvious, init?

How is that for a title, right? I know, I know, they want me to call it “systemd” not “System D” or “Systemd” or anything else resembling a legitimate proper noun, but that doesn’t work quite so well for a sci-fi-esque sounding movie title as does the above.

Anyway, to cut straight to the chase: I’m writing an init system. I’m not happy with Systemd’s increasing feature creep, bugs and occasional developer attitude issues, and I know I’m not the only one; however, I do want an init system / service supervision and management system that is more capable than the ancient Sys V init, and which in theory – together with a number of other pieces of software – could effectively provide a fully functional replacement for Systemd, without taking its all-or-nothing approach, and without needlessly sacrificing backwards compatibility with pre-existing tools and workflows, while being simpler both conceptually and in implementation.

Yes, there are probably already other options. I have at least briefly looked at a number of them. (see here, though there are probably many that are missing from that list). In general I am not perfectly happy with any of them, which is why I’ve decided to write yet another. There may be a bit of NIH syndrome leading to this decision; that’s ok, I can live with that; partly we write software because there’s nothing else that will do the job, and party we write it just for the heck of it. This project is always going to be a large part for the latter.

So, what are my main goals? Let’s see:

  • This will be both an init system and a service manager / process supervisor, in this sense similar to Systemd. It both boots the system, runs services (and allows them to be controlled), and shuts the system down. It will be able to automatically restart services that fail, when it is sensible to do so.
  • The dependency model is simple, but effective. You should be able to express ordering between services that specifies one service requires another to have started first.
  • Simplicity in general is an explicit goal, as is ease of configuration and use. (Sometimes these conflict).
  • It will be cross-platform. At least, it should run on most POSIX systems, not just Linux.
  • It will be both efficient and maintainable.
  • It will be stable. Solid-as-a-rock stable.

That should probably do for now. I know that these could be considered lofty goals; I’ll discuss more on each point in a number of follow-up posts, and where applicable I’ll discuss differences to Systemd and other init systems and service managers, anything that will make this particular software special, and any ways in which things might be improved generally.

What I do need to say before I finish up, however, is that this software is real: it has a name – “Dinit” – and in fact it already has a good body of source code and documentation, as can be seen on the Github page. What’s more, I’m already using it to boot my own system (although I’m not going to recommend at this stage that anyone else should try to use it for that just yet).

And, oh yeah, it’s written in C++. I know a number of people are going to snub their noses at the project just because of that; I don’t care. As far as I’m concerned the realistic alternatives at this point in time are probably C and Rust; C++ beats C hands down and Rust just isn’t, in my eyes, quite ready yet, though it may be one day (maybe even soon). I’ll discuss the precise reasons for choosing C++ (beyond “I happen to like it”, which is certainly one reason) in a future post, but ultimately arguing about programming languages isn’t something I really want to get into.

In the next episode of Escape From System D, I will discuss the role of init and service management systems and why they are often combined.


24 thoughts on “Escape from System D

  1. Doomed before you even start. Aiming for POSIX compat in an init system just ensures you end up with a lowest common denominator set of features. Pretty much every other POSIX system besides Linux has a monolithic source tree with their own in-tree init system. Your chances of actually being used by any mainstream POSIX OS are near zero. Oh and you’re using C++? *puke*!

    1. I know I’m going to be tempted to just delete C++-hate comments by the time I’m through with this. This time, I won’t bite.

      You’re wrong about the least-common-denominator thing though; I didn’t say that I was restricting the feature set to POSIX, just that it should run on any POSIX system.

      As for it never being picked up by “any mainstream POSIX OS” – you’re almost certainly right about that, and I don’t care a jot.

      Thanks for the negativity, though. It’s always good to have something to rally against…

      1. C++ is weird to hate on, C and C++ both suffer from user created memory leaks and are hard to get into efficiently, RUST won’t even compile right on other than x86…
        Wonder why an init based on shell scripts is not the way to go, as long there is no bashism it would be enough to bring up a system.
        Ether way, system d’s insanity of refusing to allow everything to be a filesystem. Why not go that route?
        Using a Plan 9 style filesystem where a script can ls a dir for running services. and cp/mv/edit files to have services change/stop/restart ?

      2. > As for it never being picked up by “any mainstream POSIX OS” – you’re almost certainly right about that, and I don’t care a jot.

        You should care about adoption. If your software was not used by others, it would become a technical debt, no matter how well and beautifully written the software is.

    1. in all seriousness, whats the holdup? what other options have you discarded and why? (perhaps youre stuck with a particular distro, in which case just saying “i use red hat” ought to do it.)

  2. Best of luck with your endeavor!
    I hope you will find the time to add systemd-style configuration overrides (system files in /usr/lib/systemd, generator files in /run/systemd, admin files in /etc/systemd, each able to extend/change the previous ones). I love that system, since it allows me to modify my distributions services without having to fear that my changes will vanish on the next upgrade:-)
    If your README on Github is up to date, then your current implementation is rather too simplistic for my taste.

    1. Thanks – and yes, the service loading logic will be reworked soon to allow for multiple service directories with a defined order of precedence.

  3. Good luck! I love the list services implimentation and I’m looking forward to a more ‘UNIX-y’ one thing well idea.

    1. I have heard of procd (and ubus) but documentation on it is a little light. It’s not clear whether it handles service dependencies at all, and I assume that a lot of functionality that is needed on (eg) desktop systems but not on routers is not provided. Would be happy to hear more about it though!

  4. Sounds like an interesting project at the very least! Looking forward to see the results, going to try to follow this project.

      1. Well, as far as I understand it, runit lacks first-class support for handling service dependencies, for supervising double-forking processes, for socket activation and for explicitly running services “in the foreground” (on the console/terminal). It also doesn’t allow pinning service state (which admittedly may turn out to be a fairly niche feature). I’m not aware of any features runit has that Dinit hasn’t or won’t have.

  5. I really wonder why I see so many C++ people, who hates C but love to rewrite all “stupid and wrong” low/middle level linux functionality. It’s really amazing. They usually have many brilliant ideas and instead of joining already existing and used open/free-software project to discuss their ideas and get involved, they create own, which will be read maybe by 3 people overall and in 2 months even author will forgot to maintain it, because another brilliant idea to create in amazing C++ language will show up.

    Good luck.

  6. thanks very much, one more alternative to systemd isnt going to hurt anything, especially when canonical has scrapped theirs.

    not that i was ever a fan of upstart, but i would have grown to like it had they kept it instead of folding. seems like any feature canonical wastes user patience with is going to have gnome sooner or later.

  7. A wise member of the FreeBSD core-team made a presentation about init systems during a sysadmin conference (in french, sorry:
    He’s right about how SMF solved a lot of the main issues from init systems. Solaris’ was always intended for big-business and their specific needs.
    Solaris’ projects & resources are like cgroups & namespaces : they contains the daemons and children within their project, kills them all when the leader exits (if requested). There was a lot of very nice features within smf, so you should analyze their implementation.

    That is to say : should you create an init system, please consider these as a motto, and keep them in mind :
    – Somewhere, someday, things will go terribly wrong. Stability is the key, especially in the worse situation : not enough memory (filled or fragmented), not enough disk space, stalled I/O due to bus error, corrupted environment variables, garbled communications, flapping network… init *must* be paranoid. The best way to avoid pitfalls is to keep it simple.
    – There will be bugs. Do fuzzing before releasing a stable version. You’ll avoid the situation where a end-user hit them and have to report it. Use a buildchain to have repeatable and logged builds.
    – Don’t add features where there is no need. You don’t want to replace crontab, ntp, syslog. Once the pid1 process will be production-ready, you may try to provide features like that, but let the end-user chose wether they want it or not.
    – Use cgroups and namespaces for following process. They provide reliable way to track process and their consumption, without possibility of escaping (double fork, etc…).
    – Non-root users want to use services too. Either by providing their own configuration with non-privileged ports and own filesystem and keeping the nice daemon/service/keepalive features.
    – Multiple instances are useful. Gentoo provides them by symlinking to main script and checking the name from which they were called. This allows to use a single script with different included configuration
    – Dependencies are hard. Don’t dive into code asap, think a lot about the different situations and use-cases the users will want to get the best architecture available.
    – Avoid maintainers having to write stratup scripts (they proved to be unequal quality) by providing unified management. But do provide custom-features too. There will be cases where one-size does not fit all.

    Keep these in mind, and you’ll end with a way more professional software that what’s currently in use.

    Good luck.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.