How to find out if a system uses SysV, Upstart or Systemd initsystem

117,333

Solution 1

You can poke around the system to find indicators. One way is to check for the existence of three directories:

  • /usr/lib/systemd tells you you're on a systemd based system.

  • /usr/share/upstart is a pretty good indicator that you're on an Upstart-based system.

  • /etc/init.d tells you the box has SysV init in its history

The thing is, these are heuristics that must be considered together, possibly with other data, not certain indicators by themselves. The Ubuntu 14.10 box I'm looking at right now has all three directories. Why? Because Ubuntu just switched to systemd from Upstart in that version, but keeps Upstart and SysV init for backwards compatibility.

In the end, I think the best answer is "experience." You will see that you have logged into a CentOS 7 box and know that it's systemd. How do you learn this? Playing around, RTFMing, etc. The same way you gain all experience.

I realize this is not a very satisfactory answer, but that's what happens when there is fragmentation in the market, creating nonstandard designs. It's like asking how you know whether ls accepts -C, or --color, or doesn't do color output at all. Again, the answer is "experience."

Solution 2

The init process is always assigned PID 1. The /proc filesystem provides a way to obtain the path to an executable given a PID.

In other words:

nathan@nathan-desktop:~$ sudo stat /proc/1/exe
  File: '/proc/1/exe' -> '/sbin/upstart'

As you can see, the init process on my Ubuntu 14.10 box is Upstart. Ubuntu 15.04 uses systemd, so running that command instead yields:

nathan@nathan-gnome:~$ sudo stat /proc/1/exe
  File: '/proc/1/exe' -> '/lib/systemd/systemd'

If the system you're on gives /sbin/init as a result, then you'll want to try statting that file:

nathan@nathan-gnome:~$ sudo stat /proc/1/exe
  File: '/proc/1/exe' -> '/sbin/init'
nathan@nathan-gnome:~$ stat /sbin/init
  File: ‘/sbin/init’ -> ‘/lib/systemd/systemd’

You can also execute it to find out more:

[user@centos ~]$ /sbin/init --version
init (upstart 0.6.5)
Copyright (C) 2010 Canonical Ltd.

Solution 3

This is actually quite a difficult problem. One of the major difficulties is that the places where one most often wants to do this are the places where it's quite likely that one will be in the middle of installing or changing stuff. Another is that there's a subtle but very important difference between the system management toolset that is installed, the system management toolset that is running right now, and the system management toolset that will run at next boot.

Determining what is installed one does with a package manager, of course. But this is complicated by the fact that several systems can be installed side by side.

On Debian Linux, for example, one can install the systemd package, but it is the installation of the separate systemd-sysv package that makes it the active system. The intention is that the systemd and sysvinit packages can be installed simultaneously. Indeed, the Debian Linux crowd has taken steps in Debian 8 to shift towards every program having a different name (/lib/sysvinit/init, /lib/systemd/systemd, /sbin/runit-init, /sbin/minit, /sbin/system-manager, and so forth) for this very reason, that the "non-activating" packages don't conflict on the name /sbin/init. /sbin/init is then a symbolic link to whichever was configured to run at next boot by an "activating package".

Determining what is running now and ready to run next one can only do with a series of toolset-specific tests, with varying degrees of risk from false positives, and with varying degrees of documentation. To check for what system manager is running right now, specifically, one really has to look at the process list or at the various APIs that system managers publish. But this isn't wholly without pitfalls.

General non-starters

Let's start with things that definitely will not work.

  • /proc/1/exe will point to the same /sbin/init when either upstart or System 5 init are running right now. And on some systems, it's also /sbin/init when systemd is running.

    The Debian Linux crowd wanted to shift towards every program having a different name, as mentioned earlier. But this is Debian-specific, far from universal, and doesn't really help when the program is invoked as /sbin/init (by the initramfs phase of the bootstrap) anyway. Only Felix von Leitner's minit is actually packaged by Debian 8 to be invoked with its own name.

  • The existence of the control API file /dev/initctl isn't specific to System 5 init. systemd has a (non process #1) systemd-initctl server that serves this. Joachim Nilsson's finit serves it too. (Just to make things extra fun, on Debian it's now located at /run/initctl. See https://superuser.com/a/888936/38062 for details.)
  • systemd, upstart, System 5 rc, and OpenRC all process /etc/init.d/, for backwards compatibility in the case of the former two. Its existence does not indicate the presence of any given system.

Detecting System 5 init

Ironically, as explained at https://unix.stackexchange.com/a/196197/5132 , one way on Debian Linux at least for detecting the absence of System 5 init is the absence of /etc/inittab. However:

  • This is an side-effect of Debian's way of packaging things like /etc/inittab.
  • One part of the overall problem is that /etc/inittab sticks around if System 5 init was used at any point in the past, because uninstalling the package does not delete its configuration file. (This has been a sizeable problem for Debian 8 work, since there are several packages in Debian 7 which install themselves by adding entries to /etc/inittab.)
  • It's an inverted test.

Detecting systemd

To check for systemd as the running system manager in the "official" manner, one checks for the existence of /run/systemd/system. This is a directory, in /run, that systemd itself creates at boot, and that other system managers are unlikely to create.

But that's merely unlikely. This check is already broken, because uselessd creates this directory too.

Other, unofficial, checks won't work:

  • systemd publishes a whole RPC API over D-Bus, which even contains a version name and number; but:
  • The existence of /run/systemd/private is similarly not guaranteed and similarly duplicated by uselessd.

Detecting nosh

The system-manager in nosh creates a /run/system-manager directory. But this shares the weaknesses of the equivalent systemd check.

Further non-starters:

  • The nosh system-manager by design doesn't create pipes or sockets in the filesystem, and doesn't have an RPC API in the first place.
  • The nosh service-manager conventionally has an API socket at /run/service-manager/control, but one can run the nosh service manager under some other system manager; so this doesn't tell one what system manager is running as process #1. In any case, it doesn't set that name itself; whatever invoked it does.
  • The existence of a nosh version string, emitted by system-control version, systemctl version (if one has the systemd compatibility shims installed) and initctl version (if one has the upstart compatibility shims installed) only indicates the presence of the toolset, as these tools make no query of the running system.

Detecting upstart

Upstart's own initctl makes an API call over D-Bus, and the official check is to both check that one can run initctl and that its output contains the string "upstart" somewhere.

But, like the systemd API:

  • There's no guarantee that the API will be around tomorrow or not changed at whim.
  • There's no guarantee that some compatibility shim doesn't exist or won't exist in the future.

    Indeed, there already is one compatibility shim. nosh has an upstart compatibility package that provides shims for the upstart initctl, start, stop, and status commands. Luckily (although this was intentional), the initctl shim does not emit the word "upstart".

    root ~ #initctl version
    nosh version 1.14
    root ~ #

Solution 4

On RPM-based systems, you can query the RPM database to see what package provides /sbin/init. For example:

fedora:~$ rpm -qf /sbin/init
systemd-216-24.fc21.x86_64

centos:~$ rpm -qf /sbin/init
upstart-0.6.5-12.el6_4.1.x86_64

opensuse:~$ rpm -qf /sbin/init
systemd-sysvinit-44-10.1.1.i586

If you just want the package name, and not version, you could add the --qf option to RPM ("queryformat", not to be confused with the other -qf with one hyphen, which means "query: file"), like this: rpm --qf '%{name}\n' -qf /sbin/init.

On Debian-based systems, you can do a similar thing with dpkg:

ubuntu:~$ dpkg -S /sbin/init
upstart: /sbin/init

And, most package managers will have a similar command. Of course, then you need to know what package manager your distro uses, which might just be trading one problem for another.

Also, on some distros, it's possible that /sbin/init is not the right file to look at, most likely because init=/something/else is given on the kernel command line. Another possibility would be that /sbin/init is a symlink owned by some helper package tasked with switching between init systems, and not owned by any of them directly. One or both of these may be the case on Arch (although I don't have an Arch box handy to check right now).

Share:
117,333

Related videos on Youtube

Marek Zakrzewski
Author by

Marek Zakrzewski

“The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge.” "Daniel J. Boorstin Member of RedHat Accelerators: https://www.redhat.com/sysadmin/users/valentin-bajrami See also my article on reddit: https://www.reddit.com/r/linux/comments/hxrwfe/stupid_bash_tricks_history_reusing_arguments/ Further contributions at https://mywiki.wooledge.org/BashGuide https://mywiki.wooledge.org/NoClobber http://mywiki.wooledge.org/BashFAQ/094 https://mywiki.wooledge.org/UsingFind

Updated on September 18, 2022

Comments

  • Marek Zakrzewski
    Marek Zakrzewski over 1 year

    Is there a simple way to find out which initsystem is being used e.g by a recent Debian wheezy or Fedora system? I'm aware that Fedora 21 uses systemd initsystem but that is because I read that and because all relevant scripts/symlinks are stored in /etc/systemd/. However, I'm not sure about e.g Debian squeeze or CentOS 6 or 7 and so on.

    Which techniques exist to verify such initsystem?

    • Admin
      Admin about 9 years
      Since default installation will only have one init system, wouldn't dpkg -l, yum or whatever package manager be enough to identify the init system?
    • Admin
      Admin about 9 years
      @YoMismo I'm not sure how I would use dpkg -l or yum to identify the initsystem. On Fedora for example: ps -p 1 -o command shows /usr/lib/systemd/systemd --switched-root --system --deserialize 20 On Debian wheezy the same command produces init [2]
    • Admin
      Admin about 9 years
      dpkg -l|grep systemd gives me an answer when asked in Debian while dpkg -l|grep upstart doesn't, so I can say that my Debian install is using systemd instead any other init system. I'm not saying it is the answer, only that testing debian pakages can give an answer, but I can't say about red hat, suse or others. I'm guessing that if only one init system is installed by default then querying packages may give an answer.
    • Admin
      Admin about 9 years
      @YoMismo, no. Firstly there is the whole issue that different package management tools have different syntax and may not be used at all. Secondly debian at a minimum may install multiple init systems and switch between them at boot time.
    • Admin
      Admin about 9 years
      I should also mention there are other init systems including BSD.
    • Admin
      Admin about 9 years
      Why are you asking, exactly? I mean, you've given us the "if" clause, but what are the "then" and "else" clauses? If it's systemd, then what do you do? If it's upstart instead, what else do you do?
    • Admin
      Admin about 9 years
      @WarrenYoung since I work on different platforms, I want to be able to see instantly what initsystem is running on what platform so I can focus on organizing startup scripts, creating and modifying new ones and so on. Eventually I want to modify the motd(Message of the Day) which tells me what initsystem runs once I log in on a system.
    • Admin
      Admin about 9 years
      Very handwavy, couldn't you see what process has pid 1 and what strings says about it? For my Ubuntu box here, the results contain "upstart", now it's just data gathering ;)
    • Admin
      Admin about 9 years
      Strictly speaking, this is not a duplicate. This question asked about Linux operating systems, specifically. The other question included BSDs, MacOS, Solaris, and minix. None of these answers, including mine, address those. With good reason: it would make the already long answers even longer still. Plus it was not the question asked, of course.
    • Admin
      Admin about 9 years
      Prior asking this question, I surely checked if it was asked already. I'm not sure how this question is related to the other one, let alone being a duplicate
  • Marek Zakrzewski
    Marek Zakrzewski about 9 years
    Alright. I think the answer is acceptable considering the undefined nature of the initsystem. Checking the existence of /usr/share/upstart, /sr/lib/systemd and /etc/init.d/ could help me to write an automated script which somehow will determine the initsystem. Thanks you!
  • Warren Young
    Warren Young about 9 years
    @val0x00ff: That's actually why I asked the question in the comment above. When you start doing automatic probing for system features, you have to do so very carefully if you want it to actually be portable. The Ubuntu 14.10 lesson is that you have to do them in the order listed above. This doesn't tell you that Ubuntu 15.10 isn't going to do something else that will break your script, though.
  • Marek Zakrzewski
    Marek Zakrzewski about 9 years
    that makes sense. I'm aware that there is no 100% guarantee without checking everything carefully. Thanks again for your time and effort!
  • Marek Zakrzewski
    Marek Zakrzewski about 9 years
    wow I didn't know about the -S option. This gives some more insights about the initsystem. Thanks a bunch!
  • Scott - Слава Україні
    Scott - Слава Україні about 9 years
    "Also, on some distros, it's possible that /sbin/init is not the right file to look at, ..."  So, maybe the full answer is to do ps -p1 or look at /proc/1 to identify the program to query for.  (And, of course, use readlink, if appropriate.)
  • Warren Young
    Warren Young about 9 years
    That's a bit chicken-and-egg. That library won't exist on a system without systemd components at least present. You'd have to be using something like autoconf that can check for the existence of the library first.
  • mattdm
    mattdm about 9 years
    But, RHEL 6 (and therefore CentOS, Scientific Linux, etc.) uses upstart, and stat /proc/1/exe yields File: '/proc/1/exe' -> '/sbin/init', which doesn't tell you much.
  • dbush
    dbush about 9 years
    @mattdm: that's odd - on Fedora 21, I get File: '/proc/1/exe' -> '/usr/lib/systemd/systemd'.
  • mattdm
    mattdm about 9 years
    @Scott Yes, although I think in practice looking at /sbin/init should get you the right answer for most rpm and dpkg-based distributions, and others might need their own special-casing anyway. I'm in favor of not engineering in unnecessarily complexity just for theory. (I'll change my mind if you have a good example distro, though!)
  • Scott - Слава Україні
    Scott - Слава Україні about 9 years
    @mattdm Well, I was just responding to your last paragraph regarding init=/something/else.
  • mattdm
    mattdm about 9 years
    Yeah, me too. I think one of the goals with the previous Fedora/RHEL switch from SysVInit to upstart was user invisibility (we never made use of Upstart features, just SysVInit compatibility), and I think that explains it — while systemd is, shall we say, very clear about being new and different.
  • Warren Young
    Warren Young about 9 years
    You're not going to find it on a CentOS 5 or FreeBSD box. I, too, look forward to a world maybe 5 years hence where people have stopped trying to push back the tide, but today, you absolutely cannot count on being able to blindly link against libsystemd.
  • Random832
    Random832 about 9 years
    What might one want to do with this information for which uselessd is not compatible with systemd? A brief look at that site seems to show that it is a "cut-down systemd".
  • sleblanc
    sleblanc about 9 years
    The mere presence of an artifact is not enough to claim that it is in use. On an Ubuntu server I manage, systemd is installed, yet the machine is still using upstart.
  • Amitav Pajni
    Amitav Pajni about 9 years
    And CentOS 6 technically has upstart, but uses little or no of its features; init scripts are almost all SysV scripts, for instance.
  • Shadur
    Shadur about 9 years
    @val0x00ff Also possibly useful to know is the fact that all three of the init systems you know can and will honor standard LSB init.d scripts if they're found...
  • Warren Young
    Warren Young about 9 years
    +1, but a couple of niggles: 1) The presence of /etc/init.d does indeed not tell you that SysVinit is the main init system, but it does tell you that you aren't on a traditional BSD box. Put it last in the list of checks, after you've ruled out all the other options. 2) The fact that uselessd mimics systemd in some ways is not necessarily a problem. If you're deciding whether to install a *.service file vs an init script, a check that happens to lump systemd and uselessd together is fine. If you're trying to use one of the features uselessd purposely does not provide, then it's a problem.
  • terdon
    terdon about 9 years
    I also get ‘/proc/1/exe’ -> ‘/sbin/init’ on Debian.
  • JdeBP
    JdeBP about 9 years
    If you look carefully, you'll see that the question doesn't extend to BSDs. ☺
  • Warren Young
    Warren Young about 9 years
    @JdeBP: Yes, but that's because it's a rather blinkered question, which is why there are so many upvoted answers. There really isn't a simple, good answer to this question. The "right" answer will depend on why one is really asking the question, and what conditions apply. Pointing out holes where the existing answers fail is worthwhile. It reminds me of early Autoconf documentation that pushed you towards if test x"$y" = "x" instead of if [ -z "$y" ] because the latter didn't work on the original Bourne shell. When striving for wide portability, you need to be aware of all the traps.
  • JdeBP
    JdeBP about 9 years
    A question that doesn't fulfil our desire to cover every operating system covered by the site in one massive answer, but limits itself to the several Linux systems that the questioner actually intends to use, is not really "blinkered". There's no simple answer not because the question doesn't ask about operating systems that you want to talk about, but because it's a difficult thing to do (and not just for system management toolsets) . I wrote that above, you'll find. ☺
  • Warren Young
    Warren Young about 9 years
    He's going to write this tool today, and it'll work, and then when he ports it to something else tomorrow, it'll probably break.
  • Elder Geek
    Elder Geek almost 9 years
    for what it's worth, stat /sbin/init provides File: sbin/init under Ubuntu 14.04
  • askb
    askb about 8 years
    This can also be achieved with simple ps -p 1 command, the output should point your to init|upstartd|systemd process, its its init then do /sbin/init --version.
  • Daniel Bingham
    Daniel Bingham over 7 years
    This is a terrible answer. Any question could be answered with "experience" but doing so is the epitome of condescension. Your experience gives you an algorithm that you employ to find the answer to this question. For the ls -c bit, it may be as simple as trying ls -c and seeing if it errors. For this question, there must be some way in which the system records for itself which init system it is going to use. Some configuration file somewhere that can be checked. Your "experience" tells you what it is. Unless you're willing to share it, you shouldn't be posting answers.
  • user2718606
    user2718606 over 7 years
    Arch Linux also has systemd in /usr/lib/systemd/systemd (not /lib/systemd/systemd)
  • Phil
    Phil about 5 years
    This does not work on docker images running with -it /bin/bash because then bash is the first process to start