From: Lennart Poettering Date: Thu, 7 Mar 2019 15:42:04 +0000 (+0100) Subject: core: add open_netns_path() helper X-Git-Tag: v242-rc1~158^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=51af7fb230e0d9eebf3810b46334d475e7536833;p=thirdparty%2Fsystemd.git core: add open_netns_path() helper The new call allows us to open a netns from the file system, and store it in a "storage fd pair". It's supposed to work with setup_netns() and allows pre-population of the netns used with one opened from the file system. --- diff --git a/src/core/namespace.c b/src/core/namespace.c index 87e4a8a25fc..02ac49d02cf 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -1703,6 +1703,59 @@ fail: return r; } +int open_netns_path(int netns_storage_socket[static 2], const char *path) { + _cleanup_close_ int netns = -1; + int q, r; + + assert(netns_storage_socket); + assert(netns_storage_socket[0] >= 0); + assert(netns_storage_socket[1] >= 0); + assert(path); + + /* If the storage socket doesn't contain a netns fd yet, open one via the file system and store it in + * it. This is supposed to be called ahead of time, i.e. before setup_netns() which will allocate a + * new anonymous netns if needed. */ + + if (lockf(netns_storage_socket[0], F_LOCK, 0) < 0) + return -errno; + + netns = receive_one_fd(netns_storage_socket[0], MSG_DONTWAIT); + if (netns == -EAGAIN) { + /* Nothing stored yet. Open the file from the file system. */ + + netns = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (netns < 0) { + r = -errno; + goto fail; + } + + r = fd_is_network_ns(netns); + if (r == 0) { /* Not a netns? Refuse early. */ + r = -EINVAL; + goto fail; + } + if (r < 0 && r != -EUCLEAN) /* EUCLEAN: we don't know */ + goto fail; + + r = 1; + + } else if (netns < 0) { + r = netns; + goto fail; + } else + r = 0; /* Already allocated */ + + q = send_one_fd(netns_storage_socket[1], netns, MSG_DONTWAIT); + if (q < 0) { + r = q; + goto fail; + } + +fail: + (void) lockf(netns_storage_socket[0], F_ULOCK, 0); + return r; +} + bool ns_type_supported(NamespaceType type) { const char *t, *ns_proc; diff --git a/src/core/namespace.h b/src/core/namespace.h index ab3983f790c..cd1e8b77bb2 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -93,6 +93,7 @@ int setup_tmp_dirs( char **var_tmp_dir); int setup_netns(int netns_storage_socket[static 2]); +int open_netns_path(int netns_storage_socket[static 2], const char *path); const char* protect_home_to_string(ProtectHome p) _const_; ProtectHome protect_home_from_string(const char *s) _pure_;