user@argobox:~/journal/2025-11-30-the-day-i-learned-openrc-isnt-systemd
$ cat entry.md

The Day I Learned OpenRC Isn't Systemd

○ NOT REVIEWED

The Day I Learned OpenRC Isn’t Systemd

Date: November 30, 2025 Issue: KDE Plasma crashed, no recovery possible Root Cause: Services that should have been running weren’t Key Learning: OpenRC requires explicit service management


The Crash

KDE Plasma crashed. Not unusual — it’s a complex desktop on bleeding-edge Gentoo packages. Things happen.

What was unusual: I couldn’t get a terminal. Switched to TTY, got nothing. System required a hard reboot.

After the reboot, I started digging.


The Error Spam

Found this repeating in the logs:

kf.solid.backends.udisks2: Failed enumerating UDisks2 objects:
"org.freedesktop.DBus.Error.Spawn.ExecFailed"
"Failed to execute program org.freedesktop.UDisks2: Permission denied"

KDE Solid (the hardware detection framework) was trying to talk to UDisks2. UDisks2 wasn’t responding. This error was firing constantly, destabilizing Plasma until it crashed.


The Missing Services

Checked service status:

rc-status

UDisks2 wasn’t in the list. Neither was Polkit. Neither was UPower.

These services were installed. They just weren’t running. And they weren’t set to start at boot.


The OpenRC vs Systemd Difference

On systemd, services can auto-start via D-Bus activation. An application requests org.freedesktop.UDisks2, and if it’s not running, systemd starts it.

On OpenRC, that doesn’t work. D-Bus tries to activate the service, OpenRC says “I don’t do that,” and you get “Permission denied.”

Systemd flow:

Application → D-Bus → systemd auto-starts service → Success

OpenRC flow:

Application → D-Bus → "start this" → OpenRC says no → Permission denied

Every KDE component that depends on UDisks2, Polkit, or UPower was getting permission errors. Constantly. Until Plasma gave up.


The Fix: Enable Everything

Started each service:

sudo rc-service udisks start
sudo rc-service polkit start
sudo rc-service upower start

Enabled them at boot:

sudo rc-update add udisks default
sudo rc-update add polkit default
sudo rc-update add upower default

But wait. Polkit still wouldn’t start.


The /run/ Problem

* Starting polkit ...
* start-stop-daemon: fopen `/run/polkit-1/polkitd.pid': No such file or directory

Polkit couldn’t write its PID file because /run/polkit-1/ didn’t exist.

Here’s the thing about /run/: it’s a tmpfs filesystem. RAM-based. Volatile. It gets cleared on every reboot.

The directory Polkit needed was gone. Every boot. And nobody was creating it.

Fixed the init script:

# /etc/init.d/polkit
start_pre() {
    checkpath --directory --owner root:root --mode 0755 /run/polkit-1
}

Now the init script creates the directory before trying to start the service.


The Bluetooth Firmware

While I was fixing things, I noticed this in dmesg:

bluetooth hci0: Direct firmware load for rtl_bt/rtl8761bu_fw.bin failed with error -2

Missing Realtek Bluetooth firmware.

sudo emerge -av sys-kernel/linux-firmware

Note: It’s sys-kernel/linux-firmware, not sys-firmware/linux-firmware. Gentoo naming.

After that:

sudo rc-service bluetooth start
sudo rc-update add bluetooth default

Bluetooth worked.


The Wireplumber and UPower Crashes

Also found these in the logs:

wireplumber[4065]: segfault at 8 ... in libglib-2.0.so.0.8400.4
upowerd[3448]: trap int3 ... in libglib-2.0.so.0.8400.4

Both crashing in glib. INT3 is a CPU debug breakpoint — either a failed assertion or memory corruption hitting the right bytes.

Rebuilt glib and the affected services:

sudo glib-compile-schemas /usr/share/glib-2.0/schemas/
sudo gio-querymodules /usr/lib64/gio/modules/
sudo emerge -av1 dev-libs/glib sys-power/upower media-video/wireplumber

Wireplumber stabilized. UPower still crashes occasionally, but it’s not critical on a desktop — it’s mainly for battery management on laptops.


The Final Service List

After all the fixes, here’s what I have enabled:

rc-update show default | grep -E "dbus|elogind|polkit|udisks|upower|snapper|bluetooth"

dbus — Everything needs this

elogind — Session management

polkit — Authentication/authorization

udisks — Disk management (KDE Solid needs this)

upower — Power management

snapperd — Btrfs snapshots (critical for my sanity)

bluetooth — Bluetooth stack


The Lessons

OpenRC doesn’t auto-start services. If systemd would have started it automatically, you need to explicitly enable it on OpenRC.

/run/ is volatile. Init scripts must create their runtime directories in start_pre() because /run/ is empty after every reboot.

D-Bus activation fails silently on OpenRC. You get “Permission denied” errors, not “service not running” errors. The error message is misleading.

KDE expects certain services to be running. UDisks2, Polkit, and (optionally) UPower. Without them, Solid fails, and Plasma gets unstable.

Check rc-status after problems. Half my issues would have been obvious if I’d checked which services were actually running.


The Commands I Now Know By Heart

# Check service status
rc-service <service> status

# Start a service
sudo rc-service <service> start

# Enable at boot
sudo rc-update add <service> default

# List all enabled services
rc-update show default

# Check what's running right now
rc-status

Never use: systemctl, journalctl, or any systemd commands. They don’t exist on OpenRC.


The Meta-Lesson

I’d been running Gentoo for weeks, coming from systemd-based distros. The muscle memory was wrong.

Systemd is automatic. OpenRC is explicit.

Neither is better — they’re just different philosophies. But if you don’t understand which one you’re running, you’ll spend an afternoon wondering why Plasma keeps crashing.


OpenRC and systemd: same services, very different expectations.