Merge ~mwhudson/ubuntu/+source/initramfs-tools:refactor-networking into ubuntu/+source/initramfs-tools:ubuntu/devel

Proposed by Michael Hudson-Doyle
Status: Merged
Merge reported by: Michael Hudson-Doyle
Merged at revision: 44a728c92d88b0dac65962bee6916ade3bb2c9d9
Proposed branch: ~mwhudson/ubuntu/+source/initramfs-tools:refactor-networking
Merge into: ubuntu/+source/initramfs-tools:ubuntu/devel
Diff against target: 168 lines (+51/-50)
5 files modified
debian/changelog (+16/-0)
debian/tests/check-results (+6/-0)
debian/tests/control (+1/-1)
debian/tests/prep-image (+1/-0)
scripts/functions (+27/-49)
Reviewer Review Type Date Requested Status
Scott Moser (community) Approve
Mathieu Trudel-Lapierre (community) Needs Information
Review via email: mp+353783@code.launchpad.net

Description of the change

This is a larger rewrite of configure_networking, as an alternative to https://code.launchpad.net/~mwhudson/ubuntu/+source/initramfs-tools/+git/initramfs-tools/+merge/353782

To post a comment you must log in.
Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

Why are you getting rid of all_netbootable_devices() and the loop for multiple devices? This tended to be important since the BOOTIF might not actually be the one where DHCP will respond (somehow?). That's why we tried to bring up DHCP on any interface possible.

review: Needs Information
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Because if you call DHCP with no interfaces it does ~the same scanning
itself.

On Tue, 28 Aug 2018, 00:37 Mathieu Trudel-Lapierre, <email address hidden>
wrote:

> Review: Needs Information
>
> Why are you getting rid of all_netbootable_devices() and the loop for
> multiple devices? This tended to be important since the BOOTIF might not
> actually be the one where DHCP will respond (somehow?). That's why we tried
> to bring up DHCP on any interface possible.
> --
>
> https://code.launchpad.net/~mwhudson/ubuntu/+source/initramfs-tools/+git/initramfs-tools/+merge/353783
> You are the owner of
> ~mwhudson/ubuntu/+source/initramfs-tools:refactor-networking.
>

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Oh wait, I think I see what you're asking. Will answer more when awake.

On Tue, 28 Aug 2018, 06:43 Michael Hudson-Doyle, <
<email address hidden>> wrote:

> Because if you call DHCP with no interfaces it does ~the same scanning
> itself.
>
> On Tue, 28 Aug 2018, 00:37 Mathieu Trudel-Lapierre, <email address hidden>
> wrote:
>
>> Review: Needs Information
>>
>> Why are you getting rid of all_netbootable_devices() and the loop for
>> multiple devices? This tended to be important since the BOOTIF might not
>> actually be the one where DHCP will respond (somehow?). That's why we tried
>> to bring up DHCP on any interface possible.
>> --
>>
>> https://code.launchpad.net/~mwhudson/ubuntu/+source/initramfs-tools/+git/initramfs-tools/+merge/353783
>> You are the owner of
>> ~mwhudson/ubuntu/+source/initramfs-tools:refactor-networking.
>>
>

Revision history for this message
Scott Moser (smoser) wrote :

A few comments inline + these here.

> Tidy up configure_networking a bit:
>
> - Just let dhclient scan the interfaces if none is specified for IPv6.

'a' below also applies here even though the change you've made does not change 'b' as we're already doing it for ipv6.

> - Do not handle ip=rarp specially (ipconfig hasn't supported it for some
> time)

this seems like we should forward it to debian. just to reduce delta, even
though we are high-delta here. I assume the fix applies in debian also.

> - Call dhclient in simple cases for IPv4 (this makes some small observable
> changes -- for example ip=bootp will now make a DHCP request too -- but
> nothing that seems important).

The reasons that we kept using ipconfig previously for ipv4 were
a.) it has known behavior. The loop over existing interfaces means only one is "found", and timeouts of ipconfig are specified on the command line versus hard coded into dhclient. That means that if you have 4 nics and the last one is the one that has a dhcp server on it, then you'll end up waiting 3 (failed) ROUNTTTT and then a hit. With dhclient, the value I think is 60 seconds meaning you'd wait much more than that.

b.) At least as it is right now, the dhclient process is not at all cleaned up. ipconfig exits after it receives a lease, dhclient backgrounds itself. Then we pivot root out of that initramfs and the process stil lives. What happens when it goes to renew a lease? Or when it fails? Those were unknowns.

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

> A few comments inline + these here.
>
> > Tidy up configure_networking a bit:
> >
> > - Just let dhclient scan the interfaces if none is specified for IPv6.
>
> 'a' below also applies here even though the change you've made does not change
> 'b' as we're already doing it for ipv6.
>
> > - Do not handle ip=rarp specially (ipconfig hasn't supported it for some
> > time)
>
> this seems like we should forward it to debian. just to reduce delta, even
> though we are high-delta here. I assume the fix applies in debian also.

Yes I guess so.

>
> > - Call dhclient in simple cases for IPv4 (this makes some small
> observable
> > changes -- for example ip=bootp will now make a DHCP request too -- but
> > nothing that seems important).
>
> The reasons that we kept using ipconfig previously for ipv4 were

At the same time, I guess the argument for getting off ipconfig is to reduce the number of dhcp implementations we have to worry about. Although having read the dhclient source a bit now I'm not sure I'm happy about relying on it either :(

> a.) it has known behavior. The loop over existing interfaces means only one
> is "found", and timeouts of ipconfig are specified on the command line versus
> hard coded into dhclient. That means that if you have 4 nics and the last one
> is the one that has a dhcp server on it, then you'll end up waiting 3 (failed)
> ROUNTTTT and then a hit. With dhclient, the value I think is 60 seconds
> meaning you'd wait much more than that.

I'm faiiirly sure that if dhclient is trying multiple interfaces, it tries them all in parallel. So I think this branch improves the situation for IPv6.

I think the default timeout for dhclient is 300 seconds btw (!)

> b.) At least as it is right now, the dhclient process is not at all cleaned
> up. ipconfig exits after it receives a lease, dhclient backgrounds itself.
> Then we pivot root out of that initramfs and the process stil lives. What
> happens when it goes to renew a lease? Or when it fails? Those were
> unknowns.

Hm yes, this is true. I'd thought -1 made it exit when it found an address, but that only means it exits on failure.

Revision history for this message
Michael Hudson-Doyle (mwhudson) :
1cbcdf7... by Michael Hudson-Doyle

review comments

a93733b... by Michael Hudson-Doyle

Do not let dhclient processes hang around past the pivot and have them respect the shorter timeouts ipconfig was given.

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

> > A few comments inline + these here.
> >
> > > Tidy up configure_networking a bit:
> > >
> > > - Just let dhclient scan the interfaces if none is specified for IPv6.
> >
> > 'a' below also applies here even though the change you've made does not
> change
> > 'b' as we're already doing it for ipv6.
> >
> > > - Do not handle ip=rarp specially (ipconfig hasn't supported it for
> some
> > > time)
> >
> > this seems like we should forward it to debian. just to reduce delta, even
> > though we are high-delta here. I assume the fix applies in debian also.
>
> Yes I guess so.
>
> >
> > > - Call dhclient in simple cases for IPv4 (this makes some small
> > observable
> > > changes -- for example ip=bootp will now make a DHCP request too --
> but
> > > nothing that seems important).
> >
> > The reasons that we kept using ipconfig previously for ipv4 were
>
> At the same time, I guess the argument for getting off ipconfig is to reduce
> the number of dhcp implementations we have to worry about. Although having
> read the dhclient source a bit now I'm not sure I'm happy about relying on it
> either :(
>
> > a.) it has known behavior. The loop over existing interfaces means only one
> > is "found", and timeouts of ipconfig are specified on the command line
> versus
> > hard coded into dhclient. That means that if you have 4 nics and the last
> one
> > is the one that has a dhcp server on it, then you'll end up waiting 3
> (failed)
> > ROUNTTTT and then a hit. With dhclient, the value I think is 60 seconds
> > meaning you'd wait much more than that.
>
> I'm faiiirly sure that if dhclient is trying multiple interfaces, it tries
> them all in parallel. So I think this branch improves the situation for IPv6.
>
> I think the default timeout for dhclient is 300 seconds btw (!)

Ah I see that it's actually 30s as you say for the initramfs.

> > b.) At least as it is right now, the dhclient process is not at all cleaned
> > up. ipconfig exits after it receives a lease, dhclient backgrounds itself.
> > Then we pivot root out of that initramfs and the process stil lives. What
> > happens when it goes to renew a lease? Or when it fails? Those were
> > unknowns.
>
> Hm yes, this is true. I'd thought -1 made it exit when it found an address,
> but that only means it exits on failure.

I hacked up a fix for both the timeout and this part, what do you think?

Not tested yet.

e8d30bc... by Michael Hudson-Doyle

fix name of dhclient.conf

0adcd8e... by Michael Hudson-Doyle

check for stray dhclient processes in check-results

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

I've tested this now, and am happy with it. I'd still appreciate a re-review :)

d06550d... by Michael Hudson-Doyle

semicolons--

Revision history for this message
Scott Moser (smoser) wrote :

Minor comments inline.

I think this looks good though. Thank you for handling the timeout and the cleaning up of the process.

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Thanks for the comments. I've addressed your comments, will run the tests again locally and upload.

81ceabc... by Michael Hudson-Doyle

more review feedback

e7ddf7f... by Michael Hudson-Doyle

tyop

fc47f9a... by Michael Hudson-Doyle

stuff

44a728c... by Michael Hudson-Doyle

and things

Revision history for this message
Scott Moser (smoser) wrote :

I've only done code review, not tested any of this, but this "looks good to me".

review: Approve
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

Was this merged?

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

yes

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 1e97be0..7b57d04 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,19 @@
6+initramfs-tools (0.131ubuntu10) UNRELEASED; urgency=medium
7+
8+ * Tidy up configure_networking a bit:
9+ - Just let dhclient scan the interfaces if none is specified for IPv6.
10+ - Do not handle ip=rarp specially (ipconfig hasn't supported it for some
11+ time)
12+ - Call dhclient in simple cases for IPv4 (this makes some small observable
13+ changes -- for example ip=bootp will now make a DHCP request too -- but
14+ nothing that seems important).
15+ - Do not let dhclient processes hang around past the pivot and have them
16+ respect the shorter timeouts ipconfig was given.
17+ * debian/tests/control: add some dependencies that happened to already be
18+ installed on the test runners used so far.
19+
20+ -- Michael Hudson-Doyle <michael.hudson@ubuntu.com> Mon, 27 Aug 2018 13:57:05 +1200
21+
22 initramfs-tools (0.131ubuntu9) cosmic; urgency=medium
23
24 [ John Gallagher ]
25diff --git a/debian/tests/check-results b/debian/tests/check-results
26index 9016baa..0cb58ec 100755
27--- a/debian/tests/check-results
28+++ b/debian/tests/check-results
29@@ -57,6 +57,12 @@ with open(os.path.join(result_dir, 'link.json')) as fp:
30 with open(os.path.join(result_dir, 'addr.json')) as fp:
31 addrs = json.load(fp)
32
33+with open(os.path.join(result_dir, 'ps.txt'), encoding='utf-8', errors='replace') as fp:
34+ ps_output = fp.read()
35+
36+if 'dhclient' in ps_output:
37+ error("dhclient appears to be running")
38+
39 i = 2
40 while i < len(sys.argv):
41 a = sys.argv[i]
42diff --git a/debian/tests/control b/debian/tests/control
43index 9d49717..9f505fa 100644
44--- a/debian/tests/control
45+++ b/debian/tests/control
46@@ -1,3 +1,3 @@
47 Tests: net
48-Depends: initramfs-tools, linux-image-generic, python3, qemu-system, curl
49+Depends: initramfs-tools, linux-image-generic, python3, qemu-system, curl, lsb-release, parted
50 Restrictions: needs-root, allow-stderr
51diff --git a/debian/tests/prep-image b/debian/tests/prep-image
52index a173c9c..377a99f 100755
53--- a/debian/tests/prep-image
54+++ b/debian/tests/prep-image
55@@ -46,6 +46,7 @@ for file in /run/net-*.conf /run/net6-*.conf; do
56 done
57 ip -json addr > /result/addr.json
58 ip -json link > /result/link.json
59+ps aux | tee /result/ps.txt
60 sync
61 exec /lib/systemd/systemd-shutdown poweroff
62 EOF
63diff --git a/scripts/functions b/scripts/functions
64index 9b51c32..1d1845b 100644
65--- a/scripts/functions
66+++ b/scripts/functions
67@@ -216,32 +216,24 @@ get_fstype ()
68 return ${RET}
69 }
70
71-all_netbootable_devices()
72-{
73- for device in /sys/class/net/* ; do
74- if [ ! -e $device/flags ]; then
75- continue
76- fi
77+run_dhclient() {
78+ local timeout conffile pidfile pid
79
80- loop=$(($(cat $device/flags) & 0x8 && 1 || 0))
81- bc=$(($(cat $device/flags) & 0x2 && 1 || 0))
82- ptp=$(($(cat $device/flags) & 0x10 && 1 || 0))
83-
84- # Skip any device that is a loopback
85- if [ $loop = 1 ]; then
86- continue
87- fi
88+ timeout=$1
89+ shift
90
91- # Skip any device that isn't a broadcast
92- # or point-to-point.
93- if [ $bc = 0 ] && [ $ptp = 0 ]; then
94- continue
95- fi
96+ conffile="/etc/dhcp/dhclient.conf.$timeout"
97+ pidfile="/tmp/dhclient.pid.$timeout"
98+ cp /etc/dhcp/dhclient.conf $conffile
99+ echo "timeout $timeout;" >> $conffile
100
101- DEVICE="$DEVICE $(basename $device)"
102- done
103+ rm -f $pidfile
104+ dhclient -v -1 -cf $conffile -pf $pidfile "$@"
105
106- echo $DEVICE
107+ # We do not want the dhclient persisting past the initramfs so
108+ # just kill it here (the pid file will only be written if
109+ # dhclient daemonized, i.e. found an address).
110+ [ -f $pidfile ] && read pid < $pidfile && [ -n "$pid" ] && kill $pid
111 }
112
113 configure_networking()
114@@ -319,12 +311,9 @@ configure_networking()
115 # Do nothing
116 IP=done
117 ;;
118- ""|on|any)
119- # Bring up device
120- ipconfig -t ${ROUNDTTT} "${DEVICE}"
121- ;;
122- dhcp|bootp|rarp|both)
123- ipconfig -t ${ROUNDTTT} -c ${IP} -d "${DEVICE}"
124+ ""|on|any|dhcp|bootp|both)
125+ run_dhclient $ROUNDTTT -4 ${DEVICE:+"${DEVICE}"}
126+
127 ;;
128 *)
129 ipconfig -t ${ROUNDTTT} -d $IP
130@@ -349,28 +338,17 @@ configure_networking()
131 IP6=done
132 ;;
133 *)
134- # if this is not the first loop, sleep to provide the backoff.
135- [ "$(($ROUNDTTT-2))" = "0" ] || sleep $ROUNDTTT
136-
137- # check the content of IP6, if we have something other
138- # than a device name there and BOOTIF isn't set, clear
139- # DEVICE6 and we'll try all available devices.
140- if echo "${IP6}" | grep -v '^\(on\|dhcp\|any\)$'; then
141- DEVICE6="$IP6"
142- fi
143-
144- # if we don't have a device specified, try to bring up
145- # any eligible device.
146- if [ -z "${DEVICE6}" ]; then
147- DEVICE6=$(all_netbootable_devices)
148- fi
149-
150- # Bring up device
151- for dev in ${DEVICE6} ; do
152- dhclient -6 -1 -v "${dev}"
153- done
154+ # check the content of IP6 and if it is not on/dhcp/any use it as
155+ # a device name. Otherwise all devices will be tried (unless
156+ # BOOTIF was set, see above).
157+ case "${IP6}" in
158+ on|dhcp|any)
159+ ;;
160+ *)
161+ DEVICE6="$IP6" ;;
162+ esac
163
164- DEVICE6=$dev
165+ run_dhclient $ROUNDTTT -6 ${DEVICE6:+"${DEVICE6}"}
166 ;;
167 esac
168 done

Subscribers

People subscribed via source and target branches