[systemd-devel] Transaction contains conflicting jobs 'restart' and 'stop'

Andrei Borzenkov arvidjaar at gmail.com
Sat Mar 12 13:21:56 UTC 2016


12.03.2016 13:41, Marcos Mello пишет:
> Orion Poplawski <orion <at> cora.nwra.com> writes:
> 
>>
>> Andrei Borzenkov <arvidjaar <at> gmail.com> writes:
>>> 11.03.2016 00:11, Orion Poplawski пишет:
>>>> Uoti Urpala <uoti.urpala <at> pp1.inet.fi> writes:
>>>>> On Thu, 2016-03-10 at 17:51 +0000, Orion Poplawski wrote:
>>>>>> It appears that this is a trigger for this issue.  Removing the
>>>>>> conflicts=iptables.service removes it.  This seems like a bug to me
>>>>>> though -
>>>>>> why is iptables being brought in if the PartOf= is a one-way dep?
>>>>>
>>>>> I guess it's because it's because firewalld.service has
>>>>> "Conflicts=iptables.service", and thus (re)starting firewalld.service
>>>>> stops iptables.service; fail2ban.service has PartOf to both, thus both
>>>>> the restart and stop are propagated, and conflict.
>>>>
>>>> Can't the stop of iptables be dropped because the service is already
> stopped
>>>> (or more likely not even present)?
>>>
>>> One possible implementation is to have firewall.target and make all
>>> other services (firewalld, iptables and fail2ban) PartOf this target.
>>> You would then start/stop firewall.target instead of individual services.
>>
>> I tried this, but I get the same problem:
>>
>> # systemctl restart firewall.target
>> Failed to restart firewall.target: Transaction contains conflicting jobs
>> 'restart' and 'stop' for iptables.service. Probably contradicting
>> requirement dependencies configured.
>>
>> Also, this doesn't solve the issue of restarting fail2ban if firewalld is
>> restarted via "systemctl restart fail2ban" (which someone will do I'm sure),
>> unless there is some other dependency that needs to be setup between the
>> various units that I don't understand.  Not very familiar with configuring
>> targets.
> 
> 
> # /usr/lib/systemd/system/firewall.target
> [Unit]
> Description=Firewall
> StopWhenUnneeded=yes
> 
> [Install]
> WantedBy=basic.target
> 
> 
> # /usr/lib/systemd/system/firewalld.service
> [Unit]
> Description=firewalld - dynamic firewall daemon
> Before=network.target
> Before=libvirtd.service
> Before=NetworkManager.service
> After=dbus.service
> After=polkit.service
> Conflicts=iptables.service ip6tables.service ebtables.service ipset.service
> PartOf=firewall.target
> 
> [Service]
> EnvironmentFile=-/etc/sysconfig/firewalld
> ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS
> ExecReload=/bin/kill -HUP $MAINPID
> # supress to log debug and error output also to /var/log/messages
> StandardOutput=null
> StandardError=null
> Type=dbus
> BusName=org.fedoraproject.FirewallD1
> 
> [Install]
> WantedBy=firewall.target
> Alias=dbus-org.fedoraproject.FirewallD1.service
> 
> 
> # /usr/lib/systemd/system/fail2ban.service
> [Unit]
> Description=Fail2Ban Service
> Documentation=man:fail2ban(1)
> After=network.target iptables.service firewalld.service firewalld.service
> PartOf=firewall.target
> 
> [Service]
> Type=forking
> ExecStart=/usr/bin/fail2ban-client -x start
> ExecStop=/usr/bin/fail2ban-client stop
> ExecReload=/usr/bin/fail2ban-client reload
> PIDFile=/var/run/fail2ban/fail2ban.pid
> Restart=always
> 
> [Install]
> WantedBy=multi-user.target
> 
> 
> Then enable firewall.target and make all firewall services be
> WantedBy=firewall.target instead of basic.target.
> 
> However it is troublesome, because users will not restart firewall.target.
> They will restart firewalld.service, or iptables.service, or whatever.
> 

You can set RefuseManualStart, RefuseManualStop on each individual
service and educate users ...

> Each firewall package could drop a snippet adding a reverse PartOf=
> dependency in firewall.target:
> 
> # /usr/lib/systemd/system/firewall.target.d/firewalld.conf
> [Unit]
> PartOf=firewalld.service
> 
> This works, as firewalld.service restart will trigger firewall.target
> restart and finally fail2ban.service restart. But do not you think it is too
> much?
> 
> Cannot the restart job for the conflict units be dropped? IMO this is a
> valid use case and would make things a lot easier for packagers.


The problem apparently comes from the fact that systemd adds STOP jobs
for each conflicting unit which propagates this STOP to all units it
ConsistsOf. As conflicting unit is presumed to be already stopped at
this point, this can be considered as redundant. But I am not sure how
easy it is to avoid it. Unit state is checked when job is dispatched,
nto when job is enqueued ...


More information about the systemd-devel mailing list