Hide Forgot
Description of problem: If we have unit "A" and unit "B" where both of them have "Also=C" in their unit configuration , a call to "systemctl disable B" disables automatically "C" as well, not taking into account that there's still (enabled) unit "A" using it. Systemd should detect this and it should disable any related units defined in "Also" unit config *only if* there's no other (still enabled) unit referencing it in its "Also" config line. Version-Release number of selected component (if applicable): systemd-39-1.fc17
Curious. What is the real-life usecase?
(In reply to comment #1) > Curious. What is the real-life usecase? For example device-mapper device monitoring. The dmeventd daemon is installed as dm-event.socket within systemd (with relevant dm-event.service). Today, only lvm2-monitor.service has the "Also=dm-event.socket" which works fine in this simple scenario - enabling the lvm2-monitor enables the dm-event socket and vice versa, disabling lvm2-monitor service disables the dm-event socket... That's OK. But not only lvm2 devices could be monitored, it could be any other subsystem that may come and may make use of device-mapper monitoring services (e.g. dmraid that comes into my mind now). In this scenario we have one service that provides the daemon itself (in this case dmeventd) and subsystems that register their devices with dmeventd, each subsystem registering/unregistering their own devices for monitoring with dmeventd - "<subsystem>-monitor.service". A more concrete example - LVM2 + dmraid: Enabling lvm2 should enable dm-event as well dmraid should enable dm-event since they both depend on it. But disabling lvm2 (or dmraid) monitor service should not disable the dm-event.socket/dm-event.service if dmraid (or lvm2) still uses it.
You already have "Requires=dm-event.socket" in lvm2-monitor.service. I don't think the "Also=..." then serves any useful purpose.
BTW, I recommend adding "After=dm-event.socket" to lvm2-monitor.service. Otherwise it is not obvious to me where the ordering is guaranteed. Also I suggest adding "Requires=dm-event.socket" to dm-event.service to ensure the service can never be started without systemd providing the sockets for it. And there's a minor optimization possibility: Since it uses socket activation, dm-event.service can be safely switched to "Type=simple" if /sbin/dmeventd were executed with "-f". "PIDFile=..." would not be needed then.
(In reply to comment #3) > You already have "Requires=dm-event.socket" in lvm2-monitor.service. I don't > think the "Also=..." then serves any useful purpose. Well, yes, that's an option too - to rely fully on the "Requires" field. But then we need to add the ordering you're mentioniong in the other comment... (In reply to comment #4) > BTW, I recommend adding "After=dm-event.socket" to lvm2-monitor.service. > Otherwise it is not obvious to me where the ordering is guaranteed. ...because until now I relied on the fact that sockets.target with the dm-event.socket gets always executed before. > Also I suggest adding "Requires=dm-event.socket" to dm-event.service to ensure > the service can never be started without systemd providing the sockets for it. > OK, that seems reasonable since we always want systemd to run dm-event.socket first... > And there's a minor optimization possibility: Since it uses socket activation, > dm-event.service can be safely switched to "Type=simple" if /sbin/dmeventd were > executed with "-f". "PIDFile=..." would not be needed then. No problem doing it this way as well, thanks for the tip! So, finally, we could change our units this way: dm-event.socket: ---------------- unchanged dm-event.service: ----------------- change "After=fedora-storage-init.service fedora-storage-init-late.service" --> "After=dm-event.socket" (I guess that ordering on fedora-storage-init is not required anymore since we have already have it in lvm2-monitor.service) change "ExecStart=/sbin/dmeventd" to "ExecStart=/sbin/dmeventd -f" and leaving out the PIDFile path. lvm2-monitor.service: --------------------- change "After=fedora-storage-init.service fedora-storage-init-late.service" --> "After=dm-event.socket fedora-storage-init.service fedora-storage-init-late.service" (so adding the dm-event.socket) Yup, that seems to clean it up a bit. Thanks. This way we don't need the "Also" anymore, but anyway, somebody else could use it in several units referencing the same target unit (as described in comment #0). As for us, we have the solution, so it's up to you now if you consider fixing the "Also" as well (if you don't plan to, feel free to close this bug, but it may reapear later... :))
Warning msg probably is the best way to handle comment 0 rather then blindly disable "Service A". Atleast an msg telling the user which services are disabled in the process would be needed as in systemctl disable B.service would output "Also disabling A.service C.service" which would give the user the opportunity to rethink what he's doing and re-enable it again...
Warning message sounds reasonable, however AFAIK we do not store dependencies from [Install] section. Unit file is loaded from disk every time enable/disable is requested, thus we should store information from [Install] section as well. Otherwise we'd have to load all unit files from disk and check dependencies every time disable is requested and this is not acceptable.
I don't think of "Also=" as "dependencies" and I don't think there needs to be such a check. (In reply to comment #6) > Atleast an msg telling the user which services are disabled in the process > would be needed as in systemctl disable B.service would output "Also > disabling A.service C.service" which would give the user the opportunity to > rethink what he's doing and re-enable it again... Yes, this is the maximum level of checks that I would consider appropriate for this case. Michal Sekletar is already looking into another BZ where there's a request for more user-friendly "systemctl enable/disable" output, so I am closing this one.