diff --git a/neutron/privileged/agent/linux/ip_lib.py b/neutron/privileged/agent/linux/ip_lib.py index e4c58bf8929..2edecb515bf 100644 --- a/neutron/privileged/agent/linux/ip_lib.py +++ b/neutron/privileged/agent/linux/ip_lib.py @@ -11,6 +11,7 @@ # under the License. import errno +import os import socket from neutron_lib import constants @@ -30,6 +31,8 @@ from neutron import privileged _IP_VERSION_FAMILY_MAP = {4: socket.AF_INET, 6: socket.AF_INET6} +NETNS_RUN_DIR = '/var/run/netns' + def _get_scope_name(scope): """Return the name of the scope (given as a number), or the scope number @@ -189,8 +192,29 @@ def open_namespace(namespace): @privileged.default.entrypoint def list_ns_pids(namespace): - """List namespace process PIDs""" - return netns.ns_pids().get(namespace, []) + """List namespace process PIDs + + Based on Pyroute2.netns.ns_pids(). Remove when + https://github.com/svinota/pyroute2/issues/633 is fixed. + """ + ns_pids = [] + try: + ns_path = os.path.join(NETNS_RUN_DIR, namespace) + ns_inode = os.stat(ns_path).st_ino + except OSError: + return ns_pids + + for pid in os.listdir('/proc'): + if not pid.isdigit(): + continue + try: + pid_path = os.path.join('/proc', pid, 'ns', 'net') + if os.stat(pid_path).st_ino == ns_inode: + ns_pids.append(int(pid)) + except OSError: + continue + + return ns_pids def _translate_ip_device_exception(e, device=None, namespace=None):