This patchset fixes namespace in LNST that is currently broken. The fundamental problem was in use of libc calls with improper parameter types.
Thanks to Ondrej for the additional patch in [1].
[1] https://github.com/LNST-project/lnst/issues/202#issuecomment-820398056
Jan Tluka (4): Controller.NetNamespace: rename _nsname to _name lnst.NetTestSlave: fix namespace creation/deletion Controller.Host: pass NetNamespace to add_netns() Controller.Machine: update add_namespace and del_namespace arguments
lnst/Controller/Host.py | 2 +- lnst/Controller/Machine.py | 4 +-- lnst/Controller/NetNamespace.py | 2 +- lnst/Slave/NetTestSlave.py | 47 +++++++++++++++++++++++++-------- 4 files changed, 40 insertions(+), 15 deletions(-)
Commit da089a8c modified the parent class Namespace's attribute nsname to name. The NetNamespace class has not been updated accordingly.
Fixes commit da089a8c52bffc1edb155b4432d8f7e2847b2eee. Fixes issue 202.
Signed-off-by: Jan Tluka jtluka@redhat.com --- lnst/Controller/NetNamespace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lnst/Controller/NetNamespace.py b/lnst/Controller/NetNamespace.py index cb04b256..6c30d242 100644 --- a/lnst/Controller/NetNamespace.py +++ b/lnst/Controller/NetNamespace.py @@ -26,5 +26,5 @@ class NetNamespace(Namespace): def __init__(self, name): super(NetNamespace, self).__init__(None)
- self._nsname = name + self._name = name #self.jobs = None #TODO
Inspired by pyroute2 project.
The libc calls require bytestrings as arguments and additional encoding. The patch also adds few return code checks.
Signed-off-by: Jan Tluka jtluka@redhat.com --- lnst/Slave/NetTestSlave.py | 47 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py index 710dbce0..153aad8d 100644 --- a/lnst/Slave/NetTestSlave.py +++ b/lnst/Slave/NetTestSlave.py @@ -538,26 +538,50 @@ class SlaveMethods: MS_BIND = 4096 MS_SLAVE = 1<<19 MS_REC = 16384 + MS_SHARED = 1 << 20 libc = ctypes.CDLL(libc_name)
#based on ipnetns.c from the iproute2 project #bind to named namespace - netns_path = "/var/run/netns/" - if not os.path.exists(netns_path): - os.mkdir(netns_path, stat.S_IRWXU | stat.S_IRGRP | + netns_dir = "/var/run/netns/" + if not os.path.exists(netns_dir): + os.mkdir(netns_dir, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) - netns_path = netns_path + netns - f = os.open(netns_path, os.O_RDONLY | os.O_CREAT | os.O_EXCL, 0) + + done = False + while libc.mount(b'', netns_dir, b'none', MS_SHARED | MS_REC, None) != 0: + if done: + raise OSError(ctypes.get_errno(), 'share rundir failed', netns) + if libc.mount(netns_dir, netns_dir, b'none', MS_BIND | MS_REC, + None) != 0: + raise OSError(ctypes.get_errno(), 'mount rundir failed', netns) + done = True + + netns_path = netns_dir + netns + netns_path = netns_path.encode('ascii') + try: + f = os.open(netns_path, os.O_RDONLY | os.O_CREAT | os.O_EXCL, 0) + except FileExistsError: + raise Exception("Network namespace {} already exists".format(netns)) + os.close(f) - libc.unshare(CLONE_NEWNET) - libc.mount("/proc/self/ns/net", netns_path, "none", MS_BIND, 0) + if libc.unshare(CLONE_NEWNET) < 0: + raise OSError(ctypes.get_errno(), 'unshare failed', netns) + + if libc.mount( + '/proc/self/ns/net'.encode('utf-8'), + netns_path, + b'none', + MS_BIND, + None) < 0: + raise OSError(ctypes.get_errno(), 'mount failed', netns)
#map network sysfs to new net libc.unshare(CLONE_NEWNS) - libc.mount("", "/", "none", MS_SLAVE | MS_REC, 0) + libc.mount(b'', "/", b'none', MS_SLAVE | MS_REC, None) libc.umount2("/sys", MNT_DETACH) - libc.mount(netns, "/sys", "sysfs", 0, 0) + libc.mount(netns, "/sys", "sysfs", 0, None)
#set ctl socket to pipe to main netns self._server_handler.close_s_sock() @@ -588,6 +612,7 @@ class SlaveMethods: libc_name = ctypes.util.find_library("c") libc = ctypes.CDLL(libc_name) netns_path = "/var/run/netns/" + netns + netns_path = netns_path.encode('ascii')
netns_pid = self._net_namespaces[netns]["pid"] os.kill(netns_pid, signal.SIGUSR1) @@ -597,8 +622,8 @@ class SlaveMethods: try: libc.umount2(netns_path, MNT_DETACH) os.unlink(netns_path) - except: - logging.warning("Unable to remove named namespace %s." % netns_path) + except Exception as e: + logging.warning("Unable to remove named namespace %s. %s" % (netns_path, e))
logging.debug("Network namespace %s removed." % netns)
The whole NetNamespace object should be passed to the call instead of just the name.
Signed-off-by: Jan Tluka jtluka@redhat.com --- lnst/Controller/Host.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lnst/Controller/Host.py b/lnst/Controller/Host.py index a50a7ad1..f6c76b51 100644 --- a/lnst/Controller/Host.py +++ b/lnst/Controller/Host.py @@ -71,7 +71,7 @@ class Host(Namespace): def _custom_setattr(self, name, value): if not super(Host, self)._custom_setattr(name, value): if isinstance(value, NetNamespace): - self._machine.add_netns(value.name) + self._machine.add_netns(value) self._objects[name] = value value._machine = self._machine return True
The netns argument has been changed to NetNamespace, so this patch just updates the argument passed to the rpc_call method.
Signed-off-by: Jan Tluka jtluka@redhat.com --- lnst/Controller/Machine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py index 56d60cc5..ec0b1e6e 100644 --- a/lnst/Controller/Machine.py +++ b/lnst/Controller/Machine.py @@ -578,10 +578,10 @@ class Machine(object):
def add_netns(self, netns): self._namespaces.append(netns) - return self.rpc_call("add_namespace", netns) + return self.rpc_call("add_namespace", netns.name)
def del_netns(self, netns): - return self.rpc_call("del_namespace", netns) + return self.rpc_call("del_namespace", netns.name)
def del_namespaces(self): for netns in self._namespaces:
Mon, Apr 19, 2021 at 10:15:07AM CEST, jtluka@redhat.com wrote:
This patchset fixes namespace in LNST that is currently broken. The fundamental problem was in use of libc calls with improper parameter types.
Thanks to Ondrej for the additional patch in [1].
[1] https://github.com/LNST-project/lnst/issues/202#issuecomment-820398056
Jan Tluka (4): Controller.NetNamespace: rename _nsname to _name lnst.NetTestSlave: fix namespace creation/deletion Controller.Host: pass NetNamespace to add_netns() Controller.Machine: update add_namespace and del_namespace arguments
lnst/Controller/Host.py | 2 +- lnst/Controller/Machine.py | 4 +-- lnst/Controller/NetNamespace.py | 2 +- lnst/Slave/NetTestSlave.py | 47 +++++++++++++++++++++++++-------- 4 files changed, 40 insertions(+), 15 deletions(-)
-- 2.26.3
Please scratch this patch set as I will include additional fix in the next iteration.
-Jan
lnst-developers@lists.fedorahosted.org