From 1c3c2ec5d5cfaed50118032a192ec5150bd27c6b Mon Sep 17 00:00:00 2001 From: Jack O'Sullivan Date: Fri, 20 Sep 2019 12:21:18 +0100 Subject: [PATCH] Fix `NSPopen` proxy leaks --- net-dhcp/network.py | 11 ++++++++--- net-dhcp/udhcpc.py | 36 +++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/net-dhcp/network.py b/net-dhcp/network.py index 1a76824..85c0fc5 100644 --- a/net-dhcp/network.py +++ b/net-dhcp/network.py @@ -324,9 +324,12 @@ class ContainerDHCPManager: logger.info('[dhcp container] Replacing gateway with %s', dhcp.gateway) proc = NSPopen(dhcp.netns, ['/sbin/ip', 'route', 'replace', 'default', 'via', str(dhcp.gateway)]) - if proc.wait(timeout=1) != 0: - raise NetDhcpError(f'Failed to replace default route; "ip route" command exited with non-zero code %d', \ - proc.returncode) + try: + if proc.wait(timeout=1) != 0: + raise NetDhcpError(f'Failed to replace default route; "ip route" command exited with non-zero code %d', \ + proc.returncode) + finally: + proc.release() # TODO: Adding default route with NDB seems to be broken (because of the dst syntax?) #for route in ndb.routes: @@ -362,6 +365,8 @@ class ContainerDHCPManager: self.dhcp6.netns) except Exception as e: logger.exception(e) + if self.dhcp: + self.dhcp.finish(timeout=1) def stop(self): if not self.dhcp: diff --git a/net-dhcp/udhcpc.py b/net-dhcp/udhcpc.py index ebbfb38..c0e0c83 100644 --- a/net-dhcp/udhcpc.py +++ b/net-dhcp/udhcpc.py @@ -126,21 +126,23 @@ class DHCPClient: if self._shutdown_event.is_set(): return - if self.proc.returncode is not None and (not self.once or self.proc.returncode != 0): - raise DHCPClientError(f'udhcpc{self._suffix} exited early with code {self.proc.returncode}') - if self.once: - self.await_ip() - else: - self.proc.terminate() - - if self.proc.wait(timeout=timeout) != 0: - raise DHCPClientError(f'udhcpc{self._suffix} exited with non-zero exit code {self.proc.returncode}') - if self.netns: - self.proc.release() - - self._shutdown_event.set() - self._event_thread.join() - self._event_queue.close() - self._event_queue.unlink() + try: + if self.proc.returncode is not None and (not self.once or self.proc.returncode != 0): + raise DHCPClientError(f'udhcpc{self._suffix} exited early with code {self.proc.returncode}') + if self.once: + self.await_ip() + else: + self.proc.terminate() - return self.ip + if self.proc.wait(timeout=timeout) != 0: + raise DHCPClientError(f'udhcpc{self._suffix} exited with non-zero exit code {self.proc.returncode}') + + return self.ip + finally: + if self.netns: + self.proc.release() + + self._shutdown_event.set() + self._event_thread.join() + self._event_queue.close() + self._event_queue.unlink()