Hacker News new | ask | show | jobs
by gosub 3537 days ago
Could you elaborate on why `systemctl disable` was not working? I do not uderstand the difference between mask and disable.
4 comments

'disable' can still start the service, if another service claims it as a dependency. It will not start the service, if it is the last one in the dependency chain.

'mask' will not start the service, not even as a dependency to another service; instead it will rather let the dependent service fail to start.

That would surprise me at some point. Kind of counter intuitive. Good to know, thanks for the info.
Difficulty of naming in software. If they'd named it "block" instead of "mask", perhaps it'd be clearer?
In everyday usage, "disabled" is stronger than "masked". It is indeed surprising that masking is a stronger operation than disabling. It would be clearer if the systemd operation names were reversed.
You need to understand what systemctl disable is really doing. "Enabling" in systemd means look at the unit file and see what target should start it when enabled and then it goes and adds a symlink to that target. Masking is replacing the unit file entirely so that systemd doesn't even load it. In systemd, you can have unit files in /etc, /run, or /usr. If there is a file in /usr and /etc with the same name, /etc takes priority. By masking a unit that you want to block, you're just creating a symlink to /dev/null. Disabling a service might not be what you want to do as that service might just be a dependency of what you really want to stop. Disabling a unit just removes the explicit dependency to that unit from a particular target but that doesn't mean that the unit can't be started, just that it won't be started unless something else pulls it into the dependency tree.
enable/disable is whether the unit's own definitions of where it fits into the dependency tree are used. So even when A is disabled, a Requires dependency from another enabled unit B will cause unit A to start.

Masking removes the unit from consideration altogether, so even if a unit depends on it, it won't start. That means that units with a Requires dependency will also fail, as a dependency is missing.

So typically a fairly top-level unit (like postgresql) will declare itself that it's wanted by a top-level target (`WantedBy=multi-user.target`) which means that enabling/disabling will actually turn the service on and off, unless something else depends on it in which case disabling it does mean the explicit dependency to multi-user.target will be missing, but the unit will be pulled in wherever it's actually depended on.

The concepts are not that far removed from the Windows NT concepts for service management, where services can be automatic start, manual start, and disabled. These are, respectively, "enabled", "disabled", and "masked" in the systemd world.

There are some differences in the details, of course. But a "disabled" service can be manually started.