Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-03 Thread Michael Biebl
Am 02.11.2014 um 03:06 schrieb Ben Hutchings:
 On Sun, 2014-11-02 at 02:34 +0100, Christian Hofstaedtler wrote:
 * Ben Hutchings b...@decadent.org.uk [141101 14:02]:
 On Sat, 2014-11-01 at 13:22 +0100, Christian Hofstaedtler wrote:

 dash backs up any FDs it redirects, so it can restore them
 later on. bash just closes them outright in this situation (forked
 subshell + parent exits), causing udev's spawn_read to immediately,
 thereby marking the udev event as finished.
 
 That makes *much* more sense.


[..]

 I'd suggest the following patch, as a stop gap for sysvinit users:

 Index: systemd-215/debian/extra/net.agent
 ===
 --- systemd-215.orig/debian/extra/net.agent 2014-09-27 
 17:50:52.0 +0200
 +++ systemd-215/debian/extra/net.agent  2014-11-02 02:33:40.970469131 +0100
 @@ -1,4 +1,4 @@
 -#!/bin/sh -e
 +#!/bin/bash -e

[..]

 This seems to work under both bash and dash:
 
 exec  /dev/null 2 /dev/null
 do_everything 

Thanks Ben and Christian for further debugging this.
I suspected the problem to be related to file descriptors when this
issue came up on debian-user [1] back in July.

There I suggested to use

( do_everything )  /dev/null 2 /dev/null 

as a possible workaround. I don't particularly like using a subshell but
I'm just posting it for completeness sake here.

I admit, I don't quite understand Ben's patch, which runs exec twice:
Once before do_everything() and later for the actual ifup/ifdown call.
What exactly does the first exec do to fix this?

Marco, do you have any preference?

Michael

[1] https://lists.debian.org/debian-user/2014/07/msg01509.html

-- 
Why is it that all of the instruments seeking intelligent life in the
universe are pointed away from Earth?



signature.asc
Description: OpenPGP digital signature


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-03 Thread Ben Hutchings
On Mon, 2014-11-03 at 13:03 +0100, Michael Biebl wrote:
 Am 02.11.2014 um 03:06 schrieb Ben Hutchings:
  On Sun, 2014-11-02 at 02:34 +0100, Christian Hofstaedtler wrote:
  * Ben Hutchings b...@decadent.org.uk [141101 14:02]:
  On Sat, 2014-11-01 at 13:22 +0100, Christian Hofstaedtler wrote:
 
  dash backs up any FDs it redirects, so it can restore them
  later on. bash just closes them outright in this situation (forked
  subshell + parent exits), causing udev's spawn_read to immediately,
  thereby marking the udev event as finished.
  
  That makes *much* more sense.
 
 
 [..]
 
  I'd suggest the following patch, as a stop gap for sysvinit users:
 
  Index: systemd-215/debian/extra/net.agent
  ===
  --- systemd-215.orig/debian/extra/net.agent 2014-09-27 
  17:50:52.0 +0200
  +++ systemd-215/debian/extra/net.agent  2014-11-02 02:33:40.970469131 +0100
  @@ -1,4 +1,4 @@
  -#!/bin/sh -e
  +#!/bin/bash -e
 
 [..]
 
  This seems to work under both bash and dash:
  
  exec  /dev/null 2 /dev/null
  do_everything 
 
 Thanks Ben and Christian for further debugging this.
 I suspected the problem to be related to file descriptors when this
 issue came up on debian-user [1] back in July.
 
 There I suggested to use
 
 ( do_everything )  /dev/null 2 /dev/null 
 
 as a possible workaround. I don't particularly like using a subshell but
 I'm just posting it for completeness sake here.
 
 I admit, I don't quite understand Ben's patch, which runs exec twice:
 Once before do_everything() and later for the actual ifup/ifdown call.
 What exactly does the first exec do to fix this?

The first exec does file redirection only, and this doesn't leave
duplicate file descriptors.

Ben.

 Marco, do you have any preference?
 
 Michael
 
 [1] https://lists.debian.org/debian-user/2014/07/msg01509.html
 

-- 
Ben Hutchings
Power corrupts.  Absolute power is kind of neat.
   - John Lehman, Secretary of the US Navy 1981-1987


signature.asc
Description: This is a digitally signed message part


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-03 Thread Michael Prokop
* Ben Hutchings [Sun Nov 02, 2014 at 02:06:29AM +]:
 On Sun, 2014-11-02 at 02:34 +0100, Christian Hofstaedtler wrote:

  dash backs up any FDs it redirects, so it can restore them
  later on. bash just closes them outright in this situation (forked
  subshell + parent exits), causing udev's spawn_read to immediately,
  thereby marking the udev event as finished.

 That makes *much* more sense.
[...]
 This seems to work under both bash and dash:

 exec  /dev/null 2 /dev/null
 do_everything 

I can confirm that also this works and solves the problem for
non-systemd systems.

Thanks, Ben!

regards,
-mika-


signature.asc
Description: Digital signature


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-03 Thread Michael Prokop
* Marco d'Itri [Sun Nov 02, 2014 at 02:35:42AM +0100]:
 On Nov 02, Christian Hofstaedtler z...@debian.org wrote:

  I'd suggest the following patch, as a stop gap for sysvinit users:

 If the others can confirm that it works then I have no objections.

I can confirm that this works as expected.

Thanks a ton for debugging this, Christian.

regards,
-mika-


signature.asc
Description: Digital signature


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-01 Thread Christian Hofstaedtler
* Ben Hutchings b...@decadent.org.uk [141101 06:26]:
 On Sat, 2014-11-01 at 04:44 +0100, Christian Hofstaedtler wrote:
  I've tried to debug this a bit more tonight, and after a good 4
  hours there are two things I can report:
  
  1. with the default ruleset, udev leaks an ethtool socket to
  net.agent (and by extension to ifup, dhclient, ...)
 
 This is a bug but probably harmless.  SIOCETHTOOL doesn't depend on any
 socket state so it is normally used with an unconnected socket of an
 arbitrary address family.

While it may be harmless from a security POV, the leaked FD causes
the udev worker to hold on to the forked-away net.agent process.
net.agent tries hard to close udev's logging sockets (see the last
few lines of net.agent), but it doesn't know about any leaked
sockets and therefore doesn't try to close them.

 
 -fd = socket(PF_INET, SOCK_DGRAM, 0);
 +fd = socket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);

Ah indeed. 4 AM is not the best time for such things ;-)

-- 
 ,''`.  Christian Hofstaedtler z...@debian.org
: :' :  Debian Developer
`. `'   7D1A CFFA D9E0 806C 9C4C  D392 5C13 D6DB 9305 2E03
  `-



pgpbQXeDgGjMY.pgp
Description: PGP signature


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-01 Thread Ben Hutchings
On Sat, 2014-11-01 at 13:22 +0100, Christian Hofstaedtler wrote:
 * Ben Hutchings b...@decadent.org.uk [141101 06:26]:
  On Sat, 2014-11-01 at 04:44 +0100, Christian Hofstaedtler wrote:
   I've tried to debug this a bit more tonight, and after a good 4
   hours there are two things I can report:
   
   1. with the default ruleset, udev leaks an ethtool socket to
   net.agent (and by extension to ifup, dhclient, ...)
  
  This is a bug but probably harmless.  SIOCETHTOOL doesn't depend on any
  socket state so it is normally used with an unconnected socket of an
  arbitrary address family.
 
 While it may be harmless from a security POV, the leaked FD causes
 the udev worker to hold on to the forked-away net.agent process.

How is that?

Ben.

 net.agent tries hard to close udev's logging sockets (see the last
 few lines of net.agent), but it doesn't know about any leaked
 sockets and therefore doesn't try to close them.
 
  
  -fd = socket(PF_INET, SOCK_DGRAM, 0);
  +fd = socket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
 
 Ah indeed. 4 AM is not the best time for such things ;-)
 

-- 
Ben Hutchings
Kids!  Bringing about Armageddon can be dangerous.  Do not attempt it in
your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'


signature.asc
Description: This is a digitally signed message part


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-01 Thread Christian Hofstaedtler
* Ben Hutchings b...@decadent.org.uk [141101 14:02]:
 On Sat, 2014-11-01 at 13:22 +0100, Christian Hofstaedtler wrote:
  * Ben Hutchings b...@decadent.org.uk [141101 06:26]:
   On Sat, 2014-11-01 at 04:44 +0100, Christian Hofstaedtler wrote:
I've tried to debug this a bit more tonight, and after a good 4
hours there are two things I can report:

1. with the default ruleset, udev leaks an ethtool socket to
net.agent (and by extension to ifup, dhclient, ...)
   
   This is a bug but probably harmless.  SIOCETHTOOL doesn't depend on any
   socket state so it is normally used with an unconnected socket of an
   arbitrary address family.
  
  While it may be harmless from a security POV, the leaked FD causes
  the udev worker to hold on to the forked-away net.agent process.
 
 How is that?

You're obviously correct; the extra FDs are red herrings.

dash backs up any FDs it redirects, so it can restore them
later on. bash just closes them outright in this situation (forked
subshell + parent exits), causing udev's spawn_read to immediately,
thereby marking the udev event as finished.

I've now looked at wheezy's udev, and the relevant functions are
virtually unchanged; IMVHO the redirection/fork hack likely never
worked the way it was meant to under dash.

Upstream commit 2004d23a0fcaa6e74631057a2ff75594a038d86e changed
udev's default log level from LOG_ERR to LOG_INFO (altough all older
versions always suggested that INFO was the default -- it wasn't).
That commit is part of systemd v209 and newer.

I'd suggest the following patch, as a stop gap for sysvinit users:

Index: systemd-215/debian/extra/net.agent
===
--- systemd-215.orig/debian/extra/net.agent 2014-09-27 17:50:52.0 
+0200
+++ systemd-215/debian/extra/net.agent  2014-11-02 02:33:40.970469131 +0100
@@ -1,4 +1,4 @@
-#!/bin/sh -e
+#!/bin/bash -e
 #
 # run /sbin/{ifup,ifdown} with the --allow=hotplug option.
 #
@@ -100,9 +100,12 @@ esac
 
 }
 
-# When udev_log=debug stdout and stderr are pipes connected to udevd.
+# When udev_log=info (default) or debug, stdout and stderr are
+# pipes connected to udevd.
 # They need to be closed or udevd will wait for this process which will
 # deadlock with udevsettle until the timeout.
+# Note that this trick does not work under dash, which backs up any
+# redirected FDs to FD 10 and higher.
 do_everything  /dev/null 2 /dev/null 
 
 exit 0

-- 
 ,''`.  Christian Hofstaedtler z...@debian.org
: :' :  Debian Developer
`. `'   7D1A CFFA D9E0 806C 9C4C  D392 5C13 D6DB 9305 2E03
  `-



signature.asc
Description: Digital signature


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-01 Thread Marco d'Itri
On Nov 02, Christian Hofstaedtler z...@debian.org wrote:

 I'd suggest the following patch, as a stop gap for sysvinit users:
If the others can confirm that it works then I have no objections.

-- 
ciao,
Marco


signature.asc
Description: Digital signature


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-11-01 Thread Ben Hutchings
On Sun, 2014-11-02 at 02:34 +0100, Christian Hofstaedtler wrote:
 * Ben Hutchings b...@decadent.org.uk [141101 14:02]:
  On Sat, 2014-11-01 at 13:22 +0100, Christian Hofstaedtler wrote:
   * Ben Hutchings b...@decadent.org.uk [141101 06:26]:
On Sat, 2014-11-01 at 04:44 +0100, Christian Hofstaedtler wrote:
 I've tried to debug this a bit more tonight, and after a good 4
 hours there are two things I can report:
 
 1. with the default ruleset, udev leaks an ethtool socket to
 net.agent (and by extension to ifup, dhclient, ...)

This is a bug but probably harmless.  SIOCETHTOOL doesn't depend on any
socket state so it is normally used with an unconnected socket of an
arbitrary address family.
   
   While it may be harmless from a security POV, the leaked FD causes
   the udev worker to hold on to the forked-away net.agent process.
  
  How is that?
 
 You're obviously correct; the extra FDs are red herrings.
 
 dash backs up any FDs it redirects, so it can restore them
 later on. bash just closes them outright in this situation (forked
 subshell + parent exits), causing udev's spawn_read to immediately,
 thereby marking the udev event as finished.

That makes *much* more sense.

[...]
 I'd suggest the following patch, as a stop gap for sysvinit users:
 
 Index: systemd-215/debian/extra/net.agent
 ===
 --- systemd-215.orig/debian/extra/net.agent 2014-09-27 17:50:52.0 
 +0200
 +++ systemd-215/debian/extra/net.agent  2014-11-02 02:33:40.970469131 +0100
 @@ -1,4 +1,4 @@
 -#!/bin/sh -e
 +#!/bin/bash -e
  #
  # run /sbin/{ifup,ifdown} with the --allow=hotplug option.
  #
 @@ -100,9 +100,12 @@ esac
  
  }
  
 -# When udev_log=debug stdout and stderr are pipes connected to udevd.
 +# When udev_log=info (default) or debug, stdout and stderr are
 +# pipes connected to udevd.
  # They need to be closed or udevd will wait for this process which will
  # deadlock with udevsettle until the timeout.
 +# Note that this trick does not work under dash, which backs up any
 +# redirected FDs to FD 10 and higher.
  do_everything  /dev/null 2 /dev/null 

This seems to work under both bash and dash:

exec  /dev/null 2 /dev/null
do_everything 

Ben.

  exit 0
 

-- 
Ben Hutchings
A free society is one where it is safe to be unpopular. - Adlai Stevenson


signature.asc
Description: This is a digitally signed message part


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-10-31 Thread Christian Hofstaedtler
I've tried to debug this a bit more tonight, and after a good 4
hours there are two things I can report:

1. with the default ruleset, udev leaks an ethtool socket to
net.agent (and by extension to ifup, dhclient, ...)

Details: 80-net-setup-link.rules loads the udev builtin
net_setup_link, which in turn creates a static object of type
link_config_ctx, and then goes on to call link_config_apply,
which calls link_config_ctx_connect. This function opens both an
ethtool and a netlink socket. The netlink socket is correctly marked
as CLOEXEC, but the ethtool socket is not marked this way.
With net_setup_link loaded, the Debian-specific net rules run, and
call into the /lib/udev/net.agent shell script.
The end result is that dhclient (and many other programs!) inherit an
ethtool socket opened by udev.

2. Replacing #!/bin/sh with #!/bin/bash magically makes the problem
go away in my VM. I believe this is because bash closes all sorts of
things on startup, while dash doesn't do that.

Unfortunately, fixing the fdleak from #1 above doesn't fix the
overall problem -- likely there's another fdleak somewhere that I
didn't find.


A patch for #1 that totally ignores error branches, but could serve
as a starting point for somebody else:

--- systemd-215/src/udev/net/link-config.c  2014-11-01 04:40:50.0 
+0100
+++ systemd-215.ch/src/udev/net/link-config.c   2014-11-01 04:41:50.603183984 
+0100
@@ -130,6 +130,16 @@
 }
 }
 
+void link_config_ctx_disconnect(link_config_ctx *ctx) {
+if (!ctx)
+return;
+
+safe_close(ctx-ethtool_fd);
+ctx-ethtool_fd = -1;
+sd_rtnl_unref(ctx-rtnl);
+ctx-rtnl = NULL;
+}
+
 void link_config_ctx_free(link_config_ctx *ctx) {
 if (!ctx)
 return;
@@ -410,6 +420,7 @@
 return r;
 }
 
+link_config_ctx_disconnect(ctx);
 return 0;
 }
 
@@ -430,6 +441,7 @@
 if (r  0)
 return r;
 
+link_config_ctx_disconnect(ctx);
 *ret = driver;
 return 0;
 }

-- 
 ,''`.  Christian Hofstaedtler z...@debian.org
: :' :  Debian Developer
`. `'   7D1A CFFA D9E0 806C 9C4C  D392 5C13 D6DB 9305 2E03
  `-


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-10-31 Thread Christian Hofstaedtler
BTW, I meant to document how net.agent and the networking init script
interact, so the next person doesn't have to figure this out.

1. /etc/init.d/networking start creates /run/network/ifstate. (it
does nothing if it detects upstart is the running init.)

2. ifupdown does nothing when /run/network/ifstate is missing.

3. ifupdown -a sets up lo, even if lo is not configured in
/etc/network/interfaces (see the man page of ifupdown).

4. ifupdown -a (no further args) only brings up interfaces marked as
auto in /etc/network/interfaces.

5. /lib/udev/net.agent defers its work to ifup@.service if it
detects systemd is the running init. With other inits, it waits for
the lo device to become not-down (usually it will become unknown),
and then calls ifup --allow=hotplug $INTERFACE. (net.agent exits if
$INTERFACE is lo or some of the common 'virtual' interface names.)

6. ifup@.service pulls in networking.service (- networking init
script), and then calls ifup --allow=hotplug %i.

Therefore, under sysvinit, net.agent waits (by extension of waiting
for the lo device) for the networking init script to start. If one
forces 'lo' to become up before that, net.agent will immediately
call ifupdown, which then does nothing (because /run/network/ifstate
will be absent).

-- 
 ,''`.  Christian Hofstaedtler z...@debian.org
: :' :  Debian Developer
`. `'   7D1A CFFA D9E0 806C 9C4C  D392 5C13 D6DB 9305 2E03
  `-


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-10-31 Thread Ben Hutchings
On Sat, 2014-11-01 at 04:44 +0100, Christian Hofstaedtler wrote:
 I've tried to debug this a bit more tonight, and after a good 4
 hours there are two things I can report:
 
 1. with the default ruleset, udev leaks an ethtool socket to
 net.agent (and by extension to ifup, dhclient, ...)

This is a bug but probably harmless.  SIOCETHTOOL doesn't depend on any
socket state so it is normally used with an unconnected socket of an
arbitrary address family.

[...]
 A patch for #1 that totally ignores error branches, but could serve
 as a starting point for somebody else:
 
 --- systemd-215/src/udev/net/link-config.c2014-11-01 04:40:50.0 
 +0100
 +++ systemd-215.ch/src/udev/net/link-config.c 2014-11-01 04:41:50.603183984 
 +0100
 @@ -130,6 +130,16 @@
  }
  }
  
 +void link_config_ctx_disconnect(link_config_ctx *ctx) {
 +if (!ctx)
 +return;
 +
 +safe_close(ctx-ethtool_fd);
 +ctx-ethtool_fd = -1;
 +sd_rtnl_unref(ctx-rtnl);
 +ctx-rtnl = NULL;
 +}
 +
[...]

I think the proper fix for #1 is:

--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -53,7 +53,7 @@ int ethtool_connect(int *ret) {
 
 assert_return(ret, -EINVAL);
 
-fd = socket(PF_INET, SOCK_DGRAM, 0);
+fd = socket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
 if (fd  0) {
 return -errno;
 }
--- END ---

Ben.

-- 
Ben Hutchings
Kids!  Bringing about Armageddon can be dangerous.  Do not attempt it in
your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'


signature.asc
Description: This is a digitally signed message part


Bug#754987: udevadm settle causes 30 sec delay under sysvinit

2014-09-16 Thread dimas
hello!
i can confirm the same issue, and /lib/udev/net.agent is the reason.
after trying the tips given above, i thought: why the hell udev should raise up
the network when it starts? we have /etc/init.d/networking for this!
and i've just added exit 0 at the very beginning of /lib/udev/net.agent
folks, this speeded up boot process like noting else)) network is maintained
fine by good old init script.
PS. seems that it's not only thing, that is duplucating init scripts
functions...


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org