From bf05b63f1b102b3bedde1c637d272982d8d4813a Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 30 Aug 2019 12:09:45 +0000 Subject: [PATCH] Implement "list_ns_pids" inside Neutron Instead of using Pyroute2.netns.ns_pids() [1], while [2] is not solved, a method to list a namespace PIDs is implemented in this patch. This implementation is based on the Pyroute2 method. [1]https://github.com/svinota/pyroute2/blob/80f6e7fcdd4136933a7f164ba2cee25f134dc85c/pyroute2/netns/__init__.py#L163 [2]https://github.com/svinota/pyroute2/issues/633 Conflicts: neutron/privileged/agent/linux/ip_lib.py Change-Id: Ic00c02035a0dabf1a1efd1995c84692649c6ad27 Related-Bug: #1841753 (cherry picked from commit 085e9d8b3de44a6edd71f2de7e9c2acde053b331) --- neutron/privileged/agent/linux/ip_lib.py | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/neutron/privileged/agent/linux/ip_lib.py b/neutron/privileged/agent/linux/ip_lib.py index 546655ab2dd..364e2148c61 100644 --- a/neutron/privileged/agent/linux/ip_lib.py +++ b/neutron/privileged/agent/linux/ip_lib.py @@ -12,6 +12,7 @@ import errno import functools +import os import socket from neutron_lib import constants @@ -32,6 +33,8 @@ from neutron import privileged _IP_VERSION_FAMILY_MAP = {4: socket.AF_INET, 6: socket.AF_INET6} +NETNS_RUN_DIR = '/var/run/netns' + @lockutils.synchronized("privileged-ip-lib") # NOTE(slaweq): Because of issue with pyroute2.NetNS objects running in threads @@ -202,6 +205,33 @@ def open_namespace(namespace): pass +@privileged.default.entrypoint +def list_ns_pids(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): if e.code == errno.ENODEV: raise NetworkInterfaceNotFound(device=device, namespace=namespace)