12

It seems like whenever I try to disable a systemd service, the service finds some way to reenable itself. The most recent example has been PackageKit, which I have discovered is the source of the problem I asked about in this question. If I run this:

systemctl disable packagekit

And then for a few days my disk stays stable, but after a few days, PackageKit reenables itself, and runs, and fills /var/cache/yum back up again, pegging my disk at 100%.

I’m not asking about PackageKit specifically; really I’m trying to understand how systemd service deactivation is supposed to work.

Is there any general-purpose way to say, “Disable this service, and also disable any way of automatically reenabling it?” Or is my only choice to outright delete the package that I don’t want running?


UPDATE: Part of my question was misguided: It's not systemctl disable's job to make sure a service never runs no matter what; all systemctl disable does is say that the service shouldn't run automatically on boot.

Per a suggestion in user1686's answer, I tried

busctl --activatable | grep -i packagekit

and got

org.freedesktop.PackageKit      - -     -    (activatable) -       -

so that may well indicate what sort of thing was kicking it off (if not at boot). But I didn't think to try busctl tree before moving on to the next step.

Again per user1686's suggestion, I tried

systemctl mask packagekit

and that seems to have done the trick — whatever was starting that thing up before, isn't starting it up any more. I don't know if this would be considered an ugly or brute-force or dangerous solution; I don't know if it will work forever, but it seems to be working for now.

0

1 Answer 1

22

"Disabling" a service in systemd is mostly equivalent to "removing from runlevel" in other init systems (it removes the service from 'multi-user.target' dependency tree). Most of the time, it means the service will no longer be explicitly started during boot.

But it does not mean that the service can't be started in other ways – e.g. you can still manually systemctl start a disabled service, just like you could /etc/init.d/foo start it in the past.

Some services are set up to be started in more indirect ways than simple "on boot", but which could still trigger its startup while the system is still booting:

  • They might be started as an explicit dependency of some other service. If that other service happens to start on boot, this one will get started too.

    Try systemctl list-dependencies --reverse <unit> to see if anything wants or requires that service.

  • They might have an associated .socket unit that will start the service "on demand" as soon as a client attempts to connect. (If there is a connection attempt during boot, it will certainly look like the service was started "on boot".)

    The service's systemctl status should show if it's activated by a socket or timer unit – those units can also be stopped & disabled.

  • Similarly to on-demand socket activation, services might be "D-Bus activated" by a program trying to speak to them through the message bus. (For example, it's possible that packagekitd would be started because gnome-software tried to query it around the time of your logon.)

    Often such services have an Alias that "systemctl disable" removes, preventing unwanted D-Bus activation of a disabled service – but that's not always implemented correctly.1

However, beyond that, systemd does not automatically enable units that you've disabled. If you see that a unit is explicitly enabled again (e.g. the symlink within multi-user.target.wants has been re-created), then it must have been triggered by something external.

  • Some distributions use systemd presets to re-enable or re-disable units according to their overall policy, by invoking systemctl preset every time some relevant package is updated. (See the systemd.preset manual page.) If you create a custom preset that tells systemctl to always disable the service, it will override the distro's policy:

    (/etc/systemd/system-preset/00-steve.preset)
    
    disable packagekit*.service
    
  • Some distributions have a direct call to systemctl enable hardcoded in their post-upgrade scripts. In this case, masking the unit would make systemd behave as if it doesn't exist at all – it can no longer be enabled, started, or otherwise touched:

    % systemctl disable --now packagekit
    % systemctl mask packagekit
    

    Your distribution's package manager may also have an option to skip extracting certain files entirely, so that they would literally no longer exist as far as systemd is concerned – e.g. pacman:

    (/etc/pacman.conf)
    
    [options]
    NoExtract = usr/lib/systemd/system/packagekit*
    

D-Bus activation

1 If your service is listed in busctl --activatable, try using e.g. busctl tree on its bus name and see if that makes the service start up.

If talking to org.freedesktop.PackageKit1 (or whatever name) does cause a disabled systemd service to start, this generally means that the D-Bus .service file is pointing to the wrong systemd .service file (yes, those are different things), or it's not pointing to a systemd service at all (causing dbus-daemon to spawn the service directly).

In the former case, you can mask the systemd .service and dbus-daemon will no longer be able to start it. In the latter case, you'll have to either override the D-Bus .service via /usr/local/share/dbus-1 or make your package manager not extract it at all (as dbus-daemon doesn't have an equivalent to enable/disable, nor mask/unmask).

4
  • Thanks for all this information. I haven't had a chance to try these things (I'm away from the system in question now), and it may take 24 hours to test each suggestion (that is, to discover whether packagekit does/doesn't reenable itself), but I appreciate your help. Aug 4, 2022 at 11:52
  • 6
    Thanks for such a comprehensive overview.
    – kostix
    Aug 4, 2022 at 12:32
  • 1
    It looks like — fingers crossed — systemctl mask packagekit has worked. Thanks again. Additional information added to question. Aug 5, 2022 at 20:22
  • I had a service that I could not get rid of until I thought to check root's crontab. There it was, started by an @reboot command. I had to comment-out that command and use systemctl disable to get rid of it.
    – garyjohn
    Apr 26 at 0:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .