]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
namespace: fall back gracefully when kernel doesn't support network namespaces (...
authorMichal Sekletar <msekletar@users.noreply.github.com>
Tue, 10 Oct 2017 07:46:13 +0000 (09:46 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Oct 2017 07:46:13 +0000 (09:46 +0200)
TODO
src/core/execute.c
src/core/namespace.c
src/core/namespace.h

diff --git a/TODO b/TODO
index c9968178ce8f94e1b20fb46e0f9edd8d0a49b0d3..9abee502bc3e4bc8bf46c0fcc6c2fe68a7eba35f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -126,9 +126,6 @@ Features:
 
 * maybe introduce gpt auto discovery for /var/tmp?
 
-* fix PrivateNetwork= so that we fall back gracefully on kernels lacking
-  namespacing support (similar for the other namespacing options)
-
 * maybe add gpt-partition-based user management: each user gets his own
   LUKS-encrypted GPT partition with a new GPT type. A small nss module
   enumerates users via udev partition enumeration. UIDs are assigned in a fixed
index c4dfac96d95560b03c16734debeda64bf8d11923..645b6bf3b7afec3d8b7eccd354dcc3fdce46aae4 100644 (file)
@@ -3070,11 +3070,14 @@ static int exec_child(
         }
 
         if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
-                r = setup_netns(runtime->netns_storage_socket);
-                if (r < 0) {
-                        *exit_status = EXIT_NETWORK;
-                        return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
-                }
+                if (ns_type_supported(NAMESPACE_NET)) {
+                        r = setup_netns(runtime->netns_storage_socket);
+                        if (r < 0) {
+                                *exit_status = EXIT_NETWORK;
+                                return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
+                        }
+                } else
+                        log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring.");
         }
 
         needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
index 6d74b8da674e9a3f01af6b95791efc4d56d9a0b5..df32d666bfadbcb030304f2df1326b3a2bb2339c 100644 (file)
@@ -1428,6 +1428,18 @@ fail:
         return r;
 }
 
+bool ns_type_supported(NamespaceType type) {
+        const char *t, *ns_proc;
+
+        if (type <= _NAMESPACE_TYPE_INVALID || type >= _NAMESPACE_TYPE_MAX)
+                return false;
+
+        t = namespace_type_to_string(type);
+        ns_proc = strjoina("/proc/self/ns/", t);
+
+        return access(ns_proc, F_OK) == 0;
+}
+
 static const char *const protect_home_table[_PROTECT_HOME_MAX] = {
         [PROTECT_HOME_NO] = "no",
         [PROTECT_HOME_YES] = "yes",
@@ -1444,3 +1456,15 @@ static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem);
+
+static const char* const namespace_type_table[] = {
+        [NAMESPACE_MOUNT] = "mnt",
+        [NAMESPACE_CGROUP] = "cgroup",
+        [NAMESPACE_UTS] = "uts",
+        [NAMESPACE_IPC] = "ipc",
+        [NAMESPACE_USER] = "user",
+        [NAMESPACE_PID] = "pid",
+        [NAMESPACE_NET] = "net",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(namespace_type, NamespaceType);
index da8d85dbc55425d77cf46f59ab1358b1c8d6dafb..b244c8f337524c7a5278cf4f57423b063410f9c2 100644 (file)
@@ -36,6 +36,18 @@ typedef enum ProtectHome {
         _PROTECT_HOME_INVALID = -1
 } ProtectHome;
 
+typedef enum NamespaceType {
+        NAMESPACE_MOUNT,
+        NAMESPACE_CGROUP,
+        NAMESPACE_UTS,
+        NAMESPACE_IPC,
+        NAMESPACE_USER,
+        NAMESPACE_PID,
+        NAMESPACE_NET,
+        _NAMESPACE_TYPE_MAX,
+        _NAMESPACE_TYPE_INVALID = -1,
+} NamespaceType;
+
 typedef enum ProtectSystem {
         PROTECT_SYSTEM_NO,
         PROTECT_SYSTEM_YES,
@@ -94,3 +106,8 @@ ProtectSystem protect_system_from_string(const char *s) _pure_;
 
 void bind_mount_free_many(BindMount *b, unsigned n);
 int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item);
+
+const char* namespace_type_to_string(NamespaceType t) _const_;
+NamespaceType namespace_type_from_string(const char *s) _pure_;
+
+bool ns_type_supported(NamespaceType type);