Turns out this was all just an illusion. ifup@.service already has "After=network-pre.target", i. e. is actual execution will already be deferred until after network-pre.target. cloud-init-local.service is Before=network-pre.target, so the effect of any hotplug event will sort correctly.
I added a "ExecStart=/bin/sleep 5" to cloud-init-local.service, and this shows that network-pre.target and ifup@ correctly blocks: May 04 14:57:05 autopkgtest cloud-init[336]: [CLOUDINIT] stages.py[INFO]: network config is disabled by /var/lib/cloud/data/upgraded-network May 04 14:57:05 autopkgtest cloud-init[336]: Cloud-init v. 0.7.7 running 'init-local' at Wed, 04 May 2016 12:57:04 +0000. Up 3.64 seconds. May 04 14:57:10 autopkgtest systemd[1]: Started Initial cloud-init job (pre-networking). May 04 14:57:10 autopkgtest systemd[1]: Reached target Network (Pre). May 04 14:57:10 autopkgtest systemd[1]: Starting Raise network interfaces... May 04 14:57:11 autopkgtest systemd[1]: Started ifup for ens3. So there is nothing to fix in ifupdown, and it should be safe to drop all the hackery in cloud-init: /run/cloud-init/network-config-ready from cloud-init-local.service, the whole cloud-init-wait, and /lib/udev/rules.d/79-cloud-init-net-wait.rules. ** Changed in: ifupdown (Ubuntu) Status: In Progress => Invalid ** Changed in: cloud-init (Ubuntu) Status: New => Triaged ** Summary changed: - don't run ifup@.service before networking.service + Drop unnecessary blocking of all net udev rules ** Description changed: + cloud-inits networking setup currently jumps through a lot of bad hoops + to make sure that ifup@ does not run until after cloud-init- + local.service. This includes blocking udev rules for an indefinite time, + which is racy, a potential deadlock, and highly non-elegant. + + This is also not necessary: while ifupdown's net udev rule certainly can + fire before cloud-init-local, it only asynchronously starts + ifup@.service which will be deferred until after network-pre.target and + thus after cloud-init-local.service. + + ------- + Original description, which turned out to be completely false and just us being misled: + ifup@.service can (and often does) run for a particular interface before networking.service runs. This is brittle as during early boot ifup is prone to fail: / might still be read-only, /var might not yet exist or be writable, dhclient-enter-hooks.d/ or if-up.d/ hooks might silently fail, etc. It is also unnecessary as networking.service will bring up all "auto" and all present "allow-hotplug" interfaces anyway, and it runs at the right time. We should make either 80-ifupdown.rules or ifup@.service ignore events until networking.service is active, or wait until after it has run (slower, but avoids race conditions when hotplug events happen while networking.service is running). Thus we need to add After=networking.service to ifup@.service, so that this only does stuff after doing the "coldplug" configuration. This also affects cloud-init's setup of networking: this currently jumps through a lot of bad hoops to make sure that ifup@ does not run until after cloud-init-local.service. This includes blocking udev rules for an indefinite time, which is racy, a potential deadlock, and highly non- elegant. https://bugs.debian.org/752919 is related to this issue. ** Changed in: cloud-init (Ubuntu) Assignee: (unassigned) => Scott Moser (smoser) ** Changed in: ifupdown (Ubuntu) Assignee: Martin Pitt (pitti) => (unassigned) -- You received this bug notification because you are a member of Ubuntu Touch seeded packages, which is subscribed to ifupdown in Ubuntu. https://bugs.launchpad.net/bugs/1577844 Title: Drop unnecessary blocking of all net udev rules Status in cloud-init package in Ubuntu: Triaged Status in ifupdown package in Ubuntu: Invalid Bug description: cloud-inits networking setup currently jumps through a lot of bad hoops to make sure that ifup@ does not run until after cloud-init- local.service. This includes blocking udev rules for an indefinite time, which is racy, a potential deadlock, and highly non-elegant. This is also not necessary: while ifupdown's net udev rule certainly can fire before cloud-init-local, it only asynchronously starts ifup@.service which will be deferred until after network-pre.target and thus after cloud-init-local.service. ------- Original description, which turned out to be completely false and just us being misled: ifup@.service can (and often does) run for a particular interface before networking.service runs. This is brittle as during early boot ifup is prone to fail: / might still be read-only, /var might not yet exist or be writable, dhclient-enter-hooks.d/ or if-up.d/ hooks might silently fail, etc. It is also unnecessary as networking.service will bring up all "auto" and all present "allow-hotplug" interfaces anyway, and it runs at the right time. We should make either 80-ifupdown.rules or ifup@.service ignore events until networking.service is active, or wait until after it has run (slower, but avoids race conditions when hotplug events happen while networking.service is running). Thus we need to add After=networking.service to ifup@.service, so that this only does stuff after doing the "coldplug" configuration. This also affects cloud-init's setup of networking: this currently jumps through a lot of bad hoops to make sure that ifup@ does not run until after cloud-init-local.service. This includes blocking udev rules for an indefinite time, which is racy, a potential deadlock, and highly non-elegant. https://bugs.debian.org/752919 is related to this issue. To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1577844/+subscriptions -- Mailing list: https://launchpad.net/~touch-packages Post to : touch-packages@lists.launchpad.net Unsubscribe : https://launchpad.net/~touch-packages More help : https://help.launchpad.net/ListHelp