Hello,

I must admit not being perfectly up to date as to how Debian's
networking stack is working at boot time, so to hopefully try to explain
why Ubuntu did these changes, here's a quick explanation of how things
work on our side.

Ubuntu essentially supports two different tools to initialize the
network. For desktop systems, that's Network Manager (only loopback is
setup by ifupdown) and for servers, that's ifupdown.

As you also know, Ubuntu uses upstart as its init system. Upstart has a
udev bridge that's used to trigger init jobs on hotplug events.

Take my usual test setup as an example:
> auto lo
> iface lo inet loopback
> 
> auto eth0
> iface eth0 inet manual
>     bond-master bond0
> 
> auto eth1
> iface eth1 inet manual
>     bond-master bond0
> 
> auto bond0
> iface bond0 inet static
>     bond-slaves none
>     bond-mode 802.3ad
>     bond-miimon 100
> 
>     address 172.17.0.55
>     netmask 255.255.255.0
>     gateway 172.17.0.1
>     dns-nameservers 2607:f2c0:f00f:2720:e084:d1ff:fe38:c4f5 
> 2001:470:714b:1020:218:51ff:fe5a:9949
> 
> auto br1005
> iface br1005 inet dhcp
>     bridge-ports bond0.1005
>     bridge_stp off
> 
> auto br1005:0
> iface br1005:0 inet static
>     address 192.168.99.1
>     netmask 255.255.255.0

In this example you can see a nice mix of:
 - 802.3ad bonding (eth0 is an onboard e1000e, eth1 is a USB 3com
adapter that's usually NOT plugged in)
 - br1005 depends on bond0.1005 but bond0.1005 itself isn't defined

The boot time sequence on this machine looks like this:
1) Kernel initialize
2) Upstart, udev and udev-bridge start

3) net-device-added is emitted for eth0
  - upstart starts an instance of the network-interface job for eth0
    1) this job runs "ifup --allow auto eth0"
    2) ifenslave pre-up is called by ifupdown, creating the parent bond0
device
    3) net-device-added is emitted for bond0
      - upstart starts an instance of the network-interface job for bond0
        1) this job runs "ifup --allow auto bond0"
        2) ifenslave pre-up configures the bond device, not joining any
slave
        3) The ifup instance configuring bond0 detects that a slave was
added and adds the IP/run dhcp (not possible until a slave is joined)
      - the vlan udev hook detects that bond0 now exists and creates
bond0.10015
        - upstart starts an instance of the network-interface job for
bond0.1015
          1) Nothing to do, it's not defined in /e/n/i
        - the bridge udev hook detects that bond0.1005 now exists,
creates br1005 and joins bond0.1005
          - net-device-added is emitted for br1005
            - upstart starts an instance of the network-interface job
for br1005
              1) this job runs "ifup --allow auto br1005"
              2) ifupdown configures br1005 (starts dhclient)
    4) Now that bond0 is configured (ifenslave pre-up waits for that
state on Ubuntu), join the first slave

4) upstart hits the fallback/legacy networking job and calls "ifup -a"
  - ifupdown brings the remaining "virtual" interfaces, in this case,
br1005:0

5) some time later (days/weeks), net-device-added is emitted for eth1
  - upstart starts an instance of the network-interface job for eth1
    1) this job runs "ifup --allow auto eth1"
    2) ifenslave pre-up is called by ifupdown, joining eth1 to bond0

Numbered items are run sequentially, non-numbered items are typically
run in parallel. Also note, that I wrote these down based on what I
remember from the work I did the past 6 months, it might be slightly
inaccurate.

In this example, not having the udev hooks might (race condition) cause
br1005 to come up with bond0.1005 bridged into it. A similar thing can
happen with the vlan code if an explicit definition of a vlan exists in
/e/n/i and "ifup -a" is hit before the parent interface exists.

I already had multiple users reporting some systems with a lot of
storage and network hardware that'd take up to 5 minutes until all the
udev network events would be emitted, so most of their ethX devices
would appear on the system a long time after "ifup -a" was run.

The only way of properly supporting these systems as well as the hotplug
use cases is to have as much of the network stack as possible brought up
by events and until such time that ifupdown supports bringing up reverse
dependencies when an interface is brought up, these udev hooks will
still be required.

Sorry for it to be so complicated, but that's really the setup that
explains the best what we're supporting in Ubuntu and the kind of setups
we need to deal with.

I hope this all helps explain why we've done these changes in Ubuntu, I
hope that some of that work can be merged in Debian, for anything that's
problematic, I'm certainly happy to continue maintaining that delta in
Ubuntu as regression in that area simply isn't acceptable for us.

An higher level view of the things can be found here:
http://www.stgraber.org/2012/01/04/networking-in-ubuntu-12-04-lts/

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to