Am 10.07.2014 17:05, schrieb Stefano Zacchiroli:
> On Wed, Jul 09, 2014 at 05:31:57PM +0200, Michael Biebl wrote:
>> So, try to guard your restarts like this:
>>
>> ===
>> if [ -d /run/systemd/system ]; then
>>        systemctl list-jobs | grep -q network.target && exit 0
>> fi
>> service shorewall restart
>> service shorewall6 restart
>> ===
> 
> This did the trick! (and I quite like the fact that it will work
> properly both with and without systemd running)


I thought about this issue a bit.

It is arguably a bug / configuration error to (re)start a service from a
hook at a point where the dependencies of the service are not yet satisfied.

The resulting dependency loop is silently ignored  by sysvinit, which
isn't great.
The failure mode of systemd to simply "dead lock" isn't great either.

I think we should do two things:

1/ document in the release notes / systemd FAQ that restarting services
from hooks script (ifupdown, dhclient, etc) is problematic.

2/ change invoke-rc.d/service//lib/lsb/init-functions.d/40-systemd to
special case (re)start requests while sysinit.target/network.target is
scheduled (i.e. during early boot), i.e. use --no-block.
This will make systemctl non-blocking and simply enqueue the job.

A sample patch for the lsb init hook is attached


Comments/feedback most welcome.


Michael





-- 
Why is it that all of the instruments seeking intelligent life in the
universe are pointed away from Earth?
diff --git a/debian/init-functions.d/40-systemd b/debian/init-functions.d/40-systemd
index 3260d84..1e6ca11 100644
--- a/debian/init-functions.d/40-systemd
+++ b/debian/init-functions.d/40-systemd
@@ -33,6 +33,7 @@ fi
 systemctl_redirect () {
     local s
     local rc
+    local args
     local prog=${1##*/}
     local command=$2
 
@@ -53,6 +54,11 @@ systemctl_redirect () {
 
     service="${prog%.sh}.service"
 
+    # This is a workaround for users which start services via hook scripts
+    # during early boot which can lead to deadlocks.
+    if systemctl list-jobs | grep -q -E "(network|sysinit)\.target" ; then
+        args="--no-block"
+    fi
     # Don't try to run masked services. Don't check for errors, if
     # this errors, we'll just call systemctl and possibly explode
     # there.
@@ -60,7 +66,7 @@ systemctl_redirect () {
     [ "$state" = "LoadState=masked" ] && return 0
 
     [ "$command" = status ] || log_daemon_msg "$s" "$service"
-    /bin/systemctl $command "$service"
+    /bin/systemctl $args $command "$service"
     rc=$?
     [ "$command" = status ] || log_end_msg $rc
 

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to