diff --git a/src/libutil/namespaces.cc b/src/libutil/namespaces.cc index f66accb10..dec3a7189 100644 --- a/src/libutil/namespaces.cc +++ b/src/libutil/namespaces.cc @@ -8,31 +8,31 @@ namespace nix { +static void diagnoseUserNamespaces() +{ + if (!pathExists("/proc/self/ns/user")) { + warn("'/proc/self/ns/user' does not exist; your kernel was likely built without CONFIG_USER_NS=y"); + } + + Path maxUserNamespaces = "/proc/sys/user/max_user_namespaces"; + if (!pathExists(maxUserNamespaces) || + trim(readFile(maxUserNamespaces)) == "0") + { + warn("user namespaces appear to be disabled; check '/proc/sys/user/max_user_namespaces'"); + } + + Path procSysKernelUnprivilegedUsernsClone = "/proc/sys/kernel/unprivileged_userns_clone"; + if (pathExists(procSysKernelUnprivilegedUsernsClone) + && trim(readFile(procSysKernelUnprivilegedUsernsClone)) == "0") + { + warn("user namespaces appear to be disabled for unprivileged users; check '/proc/sys/kernel/unprivileged_userns_clone'"); + } +} + bool userNamespacesSupported() { static auto res = [&]() -> bool { - if (!pathExists("/proc/self/ns/user")) { - debug("'/proc/self/ns/user' does not exist; your kernel was likely built without CONFIG_USER_NS=y"); - return false; - } - - Path maxUserNamespaces = "/proc/sys/user/max_user_namespaces"; - if (!pathExists(maxUserNamespaces) || - trim(readFile(maxUserNamespaces)) == "0") - { - debug("user namespaces appear to be disabled; check '/proc/sys/user/max_user_namespaces'"); - return false; - } - - Path procSysKernelUnprivilegedUsernsClone = "/proc/sys/kernel/unprivileged_userns_clone"; - if (pathExists(procSysKernelUnprivilegedUsernsClone) - && trim(readFile(procSysKernelUnprivilegedUsernsClone)) == "0") - { - debug("user namespaces appear to be disabled; check '/proc/sys/kernel/unprivileged_userns_clone'"); - return false; - } - try { Pid pid = startProcess([&]() { @@ -44,7 +44,8 @@ bool userNamespacesSupported() auto r = pid.wait(); assert(!r); } catch (SysError & e) { - debug("user namespaces do not work on this system: %s", e.msg()); + warn("user namespaces do not work on this system: %s", e.msg()); + diagnoseUserNamespaces(); return false; }