summary refs log tree commit diff
path: root/src/platform/nmp-netns.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
committerMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
commit80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch)
treee3b229aa94e8dcf0590f2317664176e7b8f7607b /src/platform/nmp-netns.c
parent65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff)
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/platform/nmp-netns.c')
-rw-r--r--src/platform/nmp-netns.c764
1 files changed, 0 insertions, 764 deletions
diff --git a/src/platform/nmp-netns.c b/src/platform/nmp-netns.c
deleted file mode 100644
index 07f7a7c9..00000000
--- a/src/platform/nmp-netns.c
+++ /dev/null
@@ -1,764 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2016 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nmp-netns.h"
-
-#include <fcntl.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <pthread.h>
-
-/*****************************************************************************/
-
-/* NOTE: NMPNetns and all code used here must be thread-safe! */
-
-/* we may not call logging functions from the main-thread alone. Hence, we
- * require locking from nm-logging. Indicate that by setting NM_THREAD_SAFE_ON_MAIN_THREAD
- * to zero. */
-#undef NM_THREAD_SAFE_ON_MAIN_THREAD
-#define NM_THREAD_SAFE_ON_MAIN_THREAD 0
-
-/*****************************************************************************/
-
-#define PROC_SELF_NS_MNT "/proc/self/ns/mnt"
-#define PROC_SELF_NS_NET "/proc/self/ns/net"
-
-#define _CLONE_NS_ALL   ((int) (CLONE_NEWNS | CLONE_NEWNET))
-#define _CLONE_NS_ALL_V CLONE_NEWNS, CLONE_NEWNET
-
-static NM_UTILS_FLAGS2STR_DEFINE(_clone_ns_to_str,
-                                 int,
-                                 NM_UTILS_FLAGS2STR(CLONE_NEWNS, "mnt"),
-                                 NM_UTILS_FLAGS2STR(CLONE_NEWNET, "net"), );
-
-static const char *
-__ns_types_to_str(int ns_types, int ns_types_already_set, char *buf, gsize len)
-{
-    const char *b = buf;
-    char        bb[200];
-
-    nm_utils_strbuf_append_c(&buf, &len, '[');
-    if (ns_types & ~ns_types_already_set) {
-        nm_utils_strbuf_append_str(
-            &buf,
-            &len,
-            _clone_ns_to_str(ns_types & ~ns_types_already_set, bb, sizeof(bb)));
-    }
-    if (ns_types & ns_types_already_set) {
-        if (ns_types & ~ns_types_already_set)
-            nm_utils_strbuf_append_c(&buf, &len, '/');
-        nm_utils_strbuf_append_str(
-            &buf,
-            &len,
-            _clone_ns_to_str(ns_types & ns_types_already_set, bb, sizeof(bb)));
-    }
-    nm_utils_strbuf_append_c(&buf, &len, ']');
-    return b;
-}
-#define _ns_types_to_str(ns_types, ns_types_already_set, buf) \
-    __ns_types_to_str(ns_types, ns_types_already_set, buf, sizeof(buf))
-
-/*****************************************************************************/
-
-#define _NMLOG_DOMAIN      LOGD_PLATFORM
-#define _NMLOG_PREFIX_NAME "netns"
-#define _NMLOG(level, netns, ...)                                     \
-    G_STMT_START                                                      \
-    {                                                                 \
-        NMLogLevel _level = (level);                                  \
-                                                                      \
-        if (nm_logging_enabled(_level, _NMLOG_DOMAIN)) {              \
-            NMPNetns *_netns = (netns);                               \
-            char      _sbuf[20];                                      \
-                                                                      \
-            _nm_log(_level,                                           \
-                    _NMLOG_DOMAIN,                                    \
-                    0,                                                \
-                    NULL,                                             \
-                    NULL,                                             \
-                    "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),      \
-                    _NMLOG_PREFIX_NAME,                               \
-                    (_netns ? nm_sprintf_buf(_sbuf, "[%p]", _netns)   \
-                            : "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
-        }                                                             \
-    }                                                                 \
-    G_STMT_END
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_FD_NET, PROP_FD_MNT, );
-
-typedef struct {
-    int fd_net;
-    int fd_mnt;
-} NMPNetnsPrivate;
-
-struct _NMPNetns {
-    GObject         parent;
-    NMPNetnsPrivate _priv;
-};
-
-struct _NMPNetnsClass {
-    GObjectClass parent;
-};
-
-G_DEFINE_TYPE(NMPNetns, nmp_netns, G_TYPE_OBJECT);
-
-#define NMP_NETNS_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMPNetns, NMP_IS_NETNS)
-
-/*****************************************************************************/
-
-typedef struct {
-    NMPNetns *netns;
-    int       count;
-    int       ns_types;
-} NetnsInfo;
-
-static void      _stack_push(GArray *netns_stack, NMPNetns *netns, int ns_types);
-static NMPNetns *_netns_new(GError **error);
-
-/*****************************************************************************/
-
-static NMPNetns *
-_netns_get(NetnsInfo *info)
-{
-    nm_assert(!info || NMP_IS_NETNS(info->netns));
-    return info ? info->netns : NULL;
-}
-
-/*****************************************************************************/
-
-static _nm_thread_local GArray *_netns_stack = NULL;
-
-static void
-_netns_stack_clear_cb(gpointer data)
-{
-    NetnsInfo *info = data;
-
-    nm_assert(NMP_IS_NETNS(info->netns));
-    g_object_unref(info->netns);
-}
-
-static GArray *
-_netns_stack_get_impl(void)
-{
-    gs_unref_object NMPNetns *netns = NULL;
-    gs_free_error GError *error     = NULL;
-    pthread_key_t         key;
-    GArray *              s;
-
-    s = g_array_new(FALSE, FALSE, sizeof(NetnsInfo));
-    g_array_set_clear_func(s, _netns_stack_clear_cb);
-    _netns_stack = s;
-
-    /* at the bottom of the stack we must try to create a netns instance
-     * that we never pop. It's the base to which we need to return. */
-    netns = _netns_new(&error);
-    if (!netns) {
-        _LOGE(NULL, "failed to create initial netns: %s", error->message);
-        return s;
-    }
-
-    /* we leak this instance inside the stack. */
-    _stack_push(s, netns, _CLONE_NS_ALL);
-
-    /* finally, register a destructor function to cleanup the array. If we fail
-     * to do so, we will leak NMPNetns instances (and their file descriptor) when the
-     * thread exits. */
-    if (pthread_key_create(&key, (void (*)(void *)) g_array_unref) != 0)
-        _LOGE(NULL, "failure to initialize thread-local storage");
-    else if (pthread_setspecific(key, s) != 0)
-        _LOGE(NULL, "failure to set thread-local storage");
-
-    return s;
-}
-
-#define _netns_stack_get()                \
-    ({                                    \
-        GArray *_s = _netns_stack;        \
-                                          \
-        if (G_UNLIKELY(!_s))              \
-            _s = _netns_stack_get_impl(); \
-        _s;                               \
-    })
-
-/*****************************************************************************/
-
-static NMPNetns *
-_stack_current_netns(GArray *netns_stack, int ns_types)
-{
-    guint j;
-
-    nm_assert(netns_stack && netns_stack->len > 0);
-
-    /* we search the stack top-down to find the netns that has
-     * all @ns_types set. */
-    for (j = netns_stack->len; ns_types && j >= 1;) {
-        NetnsInfo *info;
-
-        info = &g_array_index(netns_stack, NetnsInfo, --j);
-
-        if (NM_FLAGS_ALL(info->ns_types, ns_types))
-            return info->netns;
-    }
-
-    g_return_val_if_reached(NULL);
-}
-
-static int
-_stack_current_ns_types(GArray *netns_stack, NMPNetns *netns, int ns_types)
-{
-    const int ns_types_check[] = {_CLONE_NS_ALL_V};
-    guint     i, j;
-    int       res = 0;
-
-    nm_assert(netns);
-    nm_assert(netns_stack && netns_stack->len > 0);
-
-    /* we search the stack top-down to check which of @ns_types
-     * are already set to @netns. */
-    for (j = netns_stack->len; ns_types && j >= 1;) {
-        NetnsInfo *info;
-
-        info = &g_array_index(netns_stack, NetnsInfo, --j);
-        if (info->netns != netns) {
-            ns_types = NM_FLAGS_UNSET(ns_types, info->ns_types);
-            continue;
-        }
-
-        for (i = 0; i < G_N_ELEMENTS(ns_types_check); i++) {
-            if (NM_FLAGS_ANY(ns_types, ns_types_check[i])
-                && NM_FLAGS_ANY(info->ns_types, ns_types_check[i])) {
-                res      = NM_FLAGS_SET(res, ns_types_check[i]);
-                ns_types = NM_FLAGS_UNSET(ns_types, ns_types_check[i]);
-            }
-        }
-    }
-
-    return res;
-}
-
-static NetnsInfo *
-_stack_peek(GArray *netns_stack)
-{
-    if (netns_stack->len > 0)
-        return &g_array_index(netns_stack, NetnsInfo, (netns_stack->len - 1));
-    return NULL;
-}
-
-static NetnsInfo *
-_stack_bottom(GArray *netns_stack)
-{
-    if (netns_stack->len > 0)
-        return &g_array_index(netns_stack, NetnsInfo, 0);
-    return NULL;
-}
-
-static void
-_stack_push(GArray *netns_stack, NMPNetns *netns, int ns_types)
-{
-    NetnsInfo *info;
-
-    nm_assert(netns_stack);
-    nm_assert(NMP_IS_NETNS(netns));
-    nm_assert(NM_FLAGS_ANY(ns_types, _CLONE_NS_ALL));
-    nm_assert(!NM_FLAGS_ANY(ns_types, ~_CLONE_NS_ALL));
-
-    g_array_set_size(netns_stack, netns_stack->len + 1);
-
-    info  = &g_array_index(netns_stack, NetnsInfo, (netns_stack->len - 1));
-    *info = (NetnsInfo){
-        .netns    = g_object_ref(netns),
-        .ns_types = ns_types,
-        .count    = 1,
-    };
-}
-
-static void
-_stack_pop(GArray *netns_stack)
-{
-    NetnsInfo *info;
-
-    nm_assert(netns_stack);
-    nm_assert(netns_stack->len > 1);
-
-    info = &g_array_index(netns_stack, NetnsInfo, (netns_stack->len - 1));
-
-    nm_assert(NMP_IS_NETNS(info->netns));
-    nm_assert(info->count == 1);
-
-    g_array_set_size(netns_stack, netns_stack->len - 1);
-}
-
-static guint
-_stack_size(GArray *netns_stack)
-{
-    nm_assert(netns_stack);
-
-    return netns_stack->len;
-}
-
-/*****************************************************************************/
-
-static NMPNetns *
-_netns_new(GError **error)
-{
-    NMPNetns *self;
-    int       fd_net, fd_mnt;
-    int       errsv;
-
-    fd_net = open(PROC_SELF_NS_NET, O_RDONLY | O_CLOEXEC);
-    if (fd_net == -1) {
-        errsv = errno;
-        g_set_error(error,
-                    NM_UTILS_ERROR,
-                    NM_UTILS_ERROR_UNKNOWN,
-                    "Failed opening netns: %s",
-                    nm_strerror_native(errsv));
-        errno = errsv;
-        return NULL;
-    }
-
-    fd_mnt = open(PROC_SELF_NS_MNT, O_RDONLY | O_CLOEXEC);
-    if (fd_mnt == -1) {
-        errsv = errno;
-        g_set_error(error,
-                    NM_UTILS_ERROR,
-                    NM_UTILS_ERROR_UNKNOWN,
-                    "Failed opening mntns: %s",
-                    nm_strerror_native(errsv));
-        nm_close(fd_net);
-        errno = errsv;
-        return NULL;
-    }
-
-    self = g_object_new(NMP_TYPE_NETNS, NMP_NETNS_FD_NET, fd_net, NMP_NETNS_FD_MNT, fd_mnt, NULL);
-
-    _LOGD(self, "new netns (net:%d, mnt:%d)", fd_net, fd_mnt);
-
-    return self;
-}
-
-static int
-_setns(NMPNetns *self, int type)
-{
-    char             buf[100];
-    int              fd;
-    NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self);
-
-    nm_assert(NM_IN_SET(type, _CLONE_NS_ALL_V));
-
-    fd = (type == CLONE_NEWNET) ? priv->fd_net : priv->fd_mnt;
-
-    _LOGt(self, "set netns(%s, %d)", _ns_types_to_str(type, 0, buf), fd);
-
-    return setns(fd, type);
-}
-
-static gboolean
-_netns_switch_push(GArray *netns_stack, NMPNetns *self, int ns_types)
-{
-    int errsv;
-
-    if (NM_FLAGS_HAS(ns_types, CLONE_NEWNET)
-        && !_stack_current_ns_types(netns_stack, self, CLONE_NEWNET)
-        && _setns(self, CLONE_NEWNET) != 0) {
-        errsv = errno;
-        _LOGE(self, "failed to switch netns: %s", nm_strerror_native(errsv));
-        return FALSE;
-    }
-    if (NM_FLAGS_HAS(ns_types, CLONE_NEWNS)
-        && !_stack_current_ns_types(netns_stack, self, CLONE_NEWNS)
-        && _setns(self, CLONE_NEWNS) != 0) {
-        errsv = errno;
-        _LOGE(self, "failed to switch mntns: %s", nm_strerror_native(errsv));
-
-        /* try to fix the mess by returning to the previous netns. */
-        if (NM_FLAGS_HAS(ns_types, CLONE_NEWNET)
-            && !_stack_current_ns_types(netns_stack, self, CLONE_NEWNET)) {
-            self = _stack_current_netns(netns_stack, CLONE_NEWNET);
-            if (self && _setns(self, CLONE_NEWNET) != 0) {
-                errsv = errno;
-                _LOGE(self, "failed to restore netns: %s", nm_strerror_native(errsv));
-            }
-        }
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static gboolean
-_netns_switch_pop(GArray *netns_stack, NMPNetns *self, int ns_types)
-{
-    int       errsv;
-    NMPNetns *current;
-    int       success = TRUE;
-
-    if (NM_FLAGS_HAS(ns_types, CLONE_NEWNET)
-        && (!self || !_stack_current_ns_types(netns_stack, self, CLONE_NEWNET))) {
-        current = _stack_current_netns(netns_stack, CLONE_NEWNET);
-        if (!current) {
-            g_warn_if_reached();
-            success = FALSE;
-        } else if (_setns(current, CLONE_NEWNET) != 0) {
-            errsv = errno;
-            _LOGE(self, "failed to switch netns: %s", nm_strerror_native(errsv));
-            success = FALSE;
-        }
-    }
-    if (NM_FLAGS_HAS(ns_types, CLONE_NEWNS)
-        && (!self || !_stack_current_ns_types(netns_stack, self, CLONE_NEWNS))) {
-        current = _stack_current_netns(netns_stack, CLONE_NEWNS);
-        if (!current) {
-            g_warn_if_reached();
-            success = FALSE;
-        } else if (_setns(current, CLONE_NEWNS) != 0) {
-            errsv = errno;
-            _LOGE(self, "failed to switch mntns: %s", nm_strerror_native(errsv));
-            success = FALSE;
-        }
-    }
-
-    return success;
-}
-
-/*****************************************************************************/
-
-int
-nmp_netns_get_fd_net(NMPNetns *self)
-{
-    g_return_val_if_fail(NMP_IS_NETNS(self), 0);
-
-    return NMP_NETNS_GET_PRIVATE(self)->fd_net;
-}
-
-int
-nmp_netns_get_fd_mnt(NMPNetns *self)
-{
-    g_return_val_if_fail(NMP_IS_NETNS(self), 0);
-
-    return NMP_NETNS_GET_PRIVATE(self)->fd_mnt;
-}
-
-/*****************************************************************************/
-
-static gboolean
-_nmp_netns_push_type(NMPNetns *self, int ns_types)
-{
-    GArray *   netns_stack = _netns_stack_get();
-    NetnsInfo *info;
-    char       sbuf[100];
-
-    info = _stack_peek(netns_stack);
-    g_return_val_if_fail(info, FALSE);
-
-    if (info->netns == self && info->ns_types == ns_types) {
-        info->count++;
-        _LOGt(self,
-              "push#%u* %s (increase count to %d)",
-              _stack_size(netns_stack) - 1,
-              _ns_types_to_str(ns_types, ns_types, sbuf),
-              info->count);
-        return TRUE;
-    }
-
-    _LOGD(self,
-          "push#%u %s",
-          _stack_size(netns_stack),
-          _ns_types_to_str(ns_types, _stack_current_ns_types(netns_stack, self, ns_types), sbuf));
-
-    if (!_netns_switch_push(netns_stack, self, ns_types))
-        return FALSE;
-
-    _stack_push(netns_stack, self, ns_types);
-    return TRUE;
-}
-
-gboolean
-nmp_netns_push(NMPNetns *self)
-{
-    g_return_val_if_fail(NMP_IS_NETNS(self), FALSE);
-
-    return _nmp_netns_push_type(self, _CLONE_NS_ALL);
-}
-
-gboolean
-nmp_netns_push_type(NMPNetns *self, int ns_types)
-{
-    g_return_val_if_fail(NMP_IS_NETNS(self), FALSE);
-    g_return_val_if_fail(!NM_FLAGS_ANY(ns_types, ~_CLONE_NS_ALL), FALSE);
-
-    return _nmp_netns_push_type(self, ns_types == 0 ? _CLONE_NS_ALL : ns_types);
-}
-
-NMPNetns *
-nmp_netns_new(void)
-{
-    GArray *      netns_stack = _netns_stack_get();
-    NMPNetns *    self;
-    int           errsv;
-    GError *      error      = NULL;
-    unsigned long mountflags = 0;
-
-    if (!_stack_peek(netns_stack)) {
-        /* there are no netns instances. We cannot create a new one
-         * (because after unshare we couldn't return to the original one). */
-        errno = ENOTSUP;
-        return NULL;
-    }
-
-    if (unshare(_CLONE_NS_ALL) != 0) {
-        errsv = errno;
-        _LOGE(NULL, "failed to create new net and mnt namespace: %s", nm_strerror_native(errsv));
-        return NULL;
-    }
-
-    if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL) != 0) {
-        errsv = errno;
-        _LOGE(NULL, "failed mount --make-rslave: %s", nm_strerror_native(errsv));
-        goto err_out;
-    }
-
-    if (umount2("/sys", MNT_DETACH) != 0) {
-        errsv = errno;
-        _LOGE(NULL, "failed umount /sys: %s", nm_strerror_native(errsv));
-        goto err_out;
-    }
-
-    if (access("/sys", W_OK) == -1)
-        mountflags = MS_RDONLY;
-
-    if (mount("sysfs", "/sys", "sysfs", mountflags, NULL) != 0) {
-        errsv = errno;
-        _LOGE(NULL, "failed mount /sys: %s", nm_strerror_native(errsv));
-        goto err_out;
-    }
-
-    self = _netns_new(&error);
-    if (!self) {
-        errsv = errno;
-        _LOGE(NULL, "failed to create netns after unshare: %s", error->message);
-        g_clear_error(&error);
-        goto err_out;
-    }
-
-    _stack_push(netns_stack, self, _CLONE_NS_ALL);
-
-    return self;
-err_out:
-    _netns_switch_pop(netns_stack, NULL, _CLONE_NS_ALL);
-    errno = errsv;
-    return NULL;
-}
-
-gboolean
-nmp_netns_pop(NMPNetns *self)
-{
-    GArray *   netns_stack = _netns_stack_get();
-    NetnsInfo *info;
-    int        ns_types;
-
-    g_return_val_if_fail(NMP_IS_NETNS(self), FALSE);
-
-    info = _stack_peek(netns_stack);
-
-    g_return_val_if_fail(info, FALSE);
-    g_return_val_if_fail(info->netns == self, FALSE);
-
-    if (info->count > 1) {
-        info->count--;
-        _LOGt(self, "pop#%u* (decrease count to %d)", _stack_size(netns_stack) - 1, info->count);
-        return TRUE;
-    }
-    g_return_val_if_fail(info->count == 1, FALSE);
-
-    /* cannot pop the original netns. */
-    g_return_val_if_fail(_stack_size(netns_stack) > 1, FALSE);
-
-    _LOGD(self, "pop#%u", _stack_size(netns_stack) - 1);
-
-    ns_types = info->ns_types;
-
-    _stack_pop(netns_stack);
-
-    return _netns_switch_pop(netns_stack, self, ns_types);
-}
-
-NMPNetns *
-nmp_netns_get_current(void)
-{
-    return _netns_get(_stack_peek(_netns_stack_get()));
-}
-
-NMPNetns *
-nmp_netns_get_initial(void)
-{
-    return _netns_get(_stack_bottom(_netns_stack_get()));
-}
-
-gboolean
-nmp_netns_is_initial(void)
-{
-    GArray *netns_stack = _netns_stack_get();
-
-    return (_netns_get(_stack_peek(netns_stack)) == _netns_get(_stack_bottom(netns_stack)));
-}
-
-/*****************************************************************************/
-
-gboolean
-nmp_netns_bind_to_path(NMPNetns *self, const char *filename, int *out_fd)
-{
-    gs_free char *    dirname = NULL;
-    int               errsv;
-    int               fd;
-    nm_auto_pop_netns NMPNetns *netns_pop = NULL;
-
-    g_return_val_if_fail(NMP_IS_NETNS(self), FALSE);
-    g_return_val_if_fail(filename && filename[0] == '/', FALSE);
-
-    if (!nmp_netns_push_type(self, CLONE_NEWNET))
-        return FALSE;
-    netns_pop = self;
-
-    dirname = g_path_get_dirname(filename);
-    if (mkdir(dirname, 0) != 0) {
-        errsv = errno;
-        if (errsv != EEXIST) {
-            _LOGE(self,
-                  "bind: failed to create directory %s: %s",
-                  dirname,
-                  nm_strerror_native(errsv));
-            return FALSE;
-        }
-    }
-
-    if ((fd = creat(filename, S_IRUSR | S_IRGRP | S_IROTH)) == -1) {
-        errsv = errno;
-        _LOGE(self, "bind: failed to create %s: %s", filename, nm_strerror_native(errsv));
-        return FALSE;
-    }
-    nm_close(fd);
-
-    if (mount(PROC_SELF_NS_NET, filename, "none", MS_BIND, NULL) != 0) {
-        errsv = errno;
-        _LOGE(self,
-              "bind: failed to mount %s to %s: %s",
-              PROC_SELF_NS_NET,
-              filename,
-              nm_strerror_native(errsv));
-        unlink(filename);
-        return FALSE;
-    }
-
-    if (out_fd) {
-        if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) {
-            errsv = errno;
-            _LOGE(self, "bind: failed to open %s: %s", filename, nm_strerror_native(errsv));
-            umount2(filename, MNT_DETACH);
-            unlink(filename);
-            return FALSE;
-        }
-        *out_fd = fd;
-    }
-
-    return TRUE;
-}
-
-gboolean
-nmp_netns_bind_to_path_destroy(NMPNetns *self, const char *filename)
-{
-    int errsv;
-
-    g_return_val_if_fail(NMP_IS_NETNS(self), FALSE);
-    g_return_val_if_fail(filename && filename[0] == '/', FALSE);
-
-    if (umount2(filename, MNT_DETACH) != 0) {
-        errsv = errno;
-        _LOGE(self, "bind: failed to unmount2 %s: %s", filename, nm_strerror_native(errsv));
-        return FALSE;
-    }
-    if (unlink(filename) != 0) {
-        errsv = errno;
-        _LOGE(self, "bind: failed to unlink %s: %s", filename, nm_strerror_native(errsv));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
-    NMPNetns *       self = NMP_NETNS(object);
-    NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self);
-
-    switch (prop_id) {
-    case PROP_FD_NET:
-        /* construct-only */
-        priv->fd_net = g_value_get_int(value);
-        g_return_if_fail(priv->fd_net > 0);
-        break;
-    case PROP_FD_MNT:
-        /* construct-only */
-        priv->fd_mnt = g_value_get_int(value);
-        g_return_if_fail(priv->fd_mnt > 0);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-nmp_netns_init(NMPNetns *self)
-{}
-
-static void
-dispose(GObject *object)
-{
-    NMPNetns *       self = NMP_NETNS(object);
-    NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self);
-
-    nm_close(priv->fd_net);
-    priv->fd_net = -1;
-
-    nm_close(priv->fd_mnt);
-    priv->fd_mnt = -1;
-
-    G_OBJECT_CLASS(nmp_netns_parent_class)->dispose(object);
-}
-
-static void
-nmp_netns_class_init(NMPNetnsClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
-    object_class->set_property = set_property;
-    object_class->dispose      = dispose;
-
-    obj_properties[PROP_FD_NET] =
-        g_param_spec_int(NMP_NETNS_FD_NET,
-                         "",
-                         "",
-                         0,
-                         G_MAXINT,
-                         0,
-                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-    obj_properties[PROP_FD_MNT] =
-        g_param_spec_int(NMP_NETNS_FD_MNT,
-                         "",
-                         "",
-                         0,
-                         G_MAXINT,
-                         0,
-                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-}