Check systemd-initctl Compatibility Without Disabling It

systemd-initctl exists purely so old SysV-style clients still find a working /dev/initctl on a modern systemd host. This guide is a read-only tour of that compatibility path: the systemd-initctl.socket unit, the /run/initctl FIFO, and the on-demand systemd-initctl.service. On this machine the installed package is systemd 255.4-1ubuntu8.17, providing systemd 255. Nothing here changes unit state, boot configuration or the contents of the FIFO.

Allow about ten minutes. You need a shell and, for some unit details, permission to query the system manager. The commands shown do not normally need sudo. Do not disable or stop this on a host that may still run software expecting /dev/initctl.

1. Check the installed version

Start by recording which systemd build you are examining. This is an ordinary, read-only command:

$ systemd --version
systemd 255 (255.4-1ubuntu8.17)
...

Your feature list can differ. The manpage and unit behaviour discussed here come from the installed systemd 255 package, not from an assumed distribution release. If the command is missing, inspect the package through your normal package-management tools rather than copying output from another host.

Checkpoint: Keep the version output with any incident notes. A later upgrade can replace the unit files and change implementation details.

2. Inspect both units without changing them

The service and socket have different jobs. Ask systemd to print their loaded unit definitions:

$ systemctl cat systemd-initctl.service systemd-initctl.socket
# /usr/lib/systemd/system/systemd-initctl.service
[Service]
ExecStart=/usr/lib/systemd/systemd-initctl

# /usr/lib/systemd/system/systemd-initctl.socket
[Socket]
ListenFIFO=/run/initctl
Symlinks=/dev/initctl
SocketMode=0600

The exact comments and surrounding sections vary by package, but the useful facts are the executable, the FIFO path, the compatibility symlink and the restrictive mode. The service is marked static in the packaged unit, so systemctl enable is not the normal way to manage it.

For a shorter, script-friendly view, query selected properties:

$ systemctl show systemd-initctl.service \
    -p Id -p LoadState -p ActiveState -p SubState -p UnitFileState -p TriggeredBy
Id=systemd-initctl.service
LoadState=loaded
ActiveState=inactive
SubState=dead
UnitFileState=static
TriggeredBy=systemd-initctl.socket
$ systemctl show systemd-initctl.socket \
    -p Id -p LoadState -p ActiveState -p SubState -p UnitFileState -p Listen
Id=systemd-initctl.socket
LoadState=loaded
ActiveState=active
SubState=listening
UnitFileState=static
Listen=/run/initctl (FIFO)

An inactive service alongside an active, listening socket is normally the expected idle shape. The manpage says the compatibility service is activated on request and terminates when unused, so do not treat inactive (dead) for the service alone as a failure.

3. Confirm the FIFO and compatibility name

Check the filesystem objects directly. This is read-only and does not open the FIFO, so it will not wait for a writer:

$ ls -l /run/initctl /dev/initctl
prw------- 1 root root 0 ... /run/initctl
lrwxrwxrwx 1 root root ... /dev/initctl -> /run/initctl
$ file /run/initctl /dev/initctl
/run/initctl:  fifo (named pipe)
/dev/initctl: symbolic link to /run/initctl

The timestamps and file size are host-specific. The first path should identify a named pipe, and the second should resolve to it when the compatibility link is present. Mode 0600 means only the owner, normally root, can access the FIFO.

Warning: Do not run cat /run/initctl as a test. Reading a FIFO can block until a writer appears, and consuming messages can interfere with the client that sent them. Do not replace it with a regular file or manually recreate the symlink either; those changes can break the system-managed interface.

4. Read the human-facing status

Use status when you need a compact diagnostic, including the socket relationship and recent journal context:

$ systemctl status systemd-initctl.socket --no-pager
● systemd-initctl.socket - initctl Compatibility Named Pipe
     Loaded: loaded (.../systemd-initctl.socket; static)
     Active: active (listening) ...
   Triggers: ● systemd-initctl.service
     Listen: /run/initctl (FIFO)

The timestamp and any journal warning are variable; the useful result is active (listening) and a listener at /run/initctl. You can inspect the service separately:

$ systemctl status systemd-initctl.service --no-pager
○ systemd-initctl.service - initctl Compatibility Daemon
     Loaded: loaded (.../systemd-initctl.service; static)
     Active: inactive (dead)
TriggeredBy: ● systemd-initctl.socket

If a legacy client has recently used the interface, the service may instead be active or show a recent activation. A failed service needs context from the journal and the client that triggered it; an idle, dead service by itself is not evidence of a fault.

5. Diagnose before considering a state change

Compare the unit's current state with the filesystem and ask for recent service messages:

$ systemctl is-active systemd-initctl.socket
active
$ systemctl is-enabled systemd-initctl.socket
static
$ journalctl -u systemd-initctl.service -b --no-pager -n 30
$ journalctl -u systemd-initctl.socket -b --no-pager -n 30

static is a unit-file state, not a failure: it means the unit is not managed through the usual enablement symlinks. Socket activation supplies the relationship, with the socket listening first and the service available when the interface is used.

If the socket is not listening, first check whether the unit is loaded and whether /run/initctl exists, then read the journal. Avoid jumping straight to systemctl restart: stopping or restarting the socket is service-disrupting for any legacy client using this path.

Recovery: If a maintenance action is unavoidable, record the current state, use an approved maintenance window, and restore the socket afterwards with systemctl start systemd-initctl.socket. That command requires elevated privileges on systems where your account cannot control system units. Verify with systemctl is-active systemd-initctl.socket and ls -l /run/initctl.

Done means