util.{hh,cc}: Split out namespaces.{hh,cc}

Change-Id: I8fd3f3b50c15ede29d489066b4e8d99c2c4636a6
This commit is contained in:
Tom Hubrecht 2024-05-28 16:01:11 +02:00
parent f79ee66646
commit 8b6d2d3915
7 changed files with 85 additions and 77 deletions

View file

@ -1,5 +1,5 @@
#include "filetransfer.hh" #include "filetransfer.hh"
#include "util.hh" #include "namespaces.hh"
#include "globals.hh" #include "globals.hh"
#include "store-api.hh" #include "store-api.hh"
#include "s3.hh" #include "s3.hh"

View file

@ -1,6 +1,7 @@
#include "current-process.hh" #include "current-process.hh"
#include "file-system.hh" #include "file-system.hh"
#include "logging.hh" #include "logging.hh"
#include "namespaces.hh"
#include "signals.hh" #include "signals.hh"
#include "util.hh" #include "util.hh"
#include "strings.hh" #include "strings.hh"

View file

@ -1,5 +1,4 @@
#if __linux__ #include "file-descriptor.hh"
#include "file-system.hh" #include "file-system.hh"
#include "logging.hh" #include "logging.hh"
#include "namespaces.hh" #include "namespaces.hh"
@ -8,8 +7,67 @@
#include <sys/mount.h> #include <sys/mount.h>
#if __linux__
# include <mutex>
# include <sys/resource.h>
#endif
namespace nix { namespace nix {
#if __linux__
static AutoCloseFD fdSavedMountNamespace;
static AutoCloseFD fdSavedRoot;
#endif
void saveMountNamespace()
{
#if __linux__
static std::once_flag done;
std::call_once(done, []() {
fdSavedMountNamespace = AutoCloseFD{open("/proc/self/ns/mnt", O_RDONLY)};
if (!fdSavedMountNamespace)
throw SysError("saving parent mount namespace");
fdSavedRoot = AutoCloseFD{open("/proc/self/root", O_RDONLY)};
});
#endif
}
void restoreMountNamespace()
{
#if __linux__
try {
auto savedCwd = absPath(".");
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
throw SysError("restoring parent mount namespace");
if (fdSavedRoot) {
if (fchdir(fdSavedRoot.get()))
throw SysError("chdir into saved root");
if (chroot("."))
throw SysError("chroot into saved root");
}
if (chdir(savedCwd.c_str()) == -1)
throw SysError("restoring cwd");
} catch (Error & e) {
debug(e.msg());
}
#endif
}
void unshareFilesystem()
{
#ifdef __linux__
if (unshare(CLONE_FS) != 0 && errno != EPERM)
throw SysError("unsharing filesystem state in download thread");
#endif
}
#if __linux__
static void diagnoseUserNamespaces() static void diagnoseUserNamespaces()
{ {
if (!pathExists("/proc/self/ns/user")) { if (!pathExists("/proc/self/ns/user")) {
@ -95,6 +153,6 @@ bool mountAndPidNamespacesSupported()
return res; return res;
} }
}
#endif #endif
}

View file

@ -3,6 +3,26 @@
namespace nix { namespace nix {
/**
* Save the current mount namespace. Ignored if called more than
* once.
*/
void saveMountNamespace();
/**
* Restore the mount namespace saved by saveMountNamespace(). Ignored
* if saveMountNamespace() was never called.
*/
void restoreMountNamespace();
/**
* Cause this thread to not share any FS attributes with the main
* thread, because this causes setns() in restoreMountNamespace() to
* fail.
*/
void unshareFilesystem();
#if __linux__ #if __linux__
bool userNamespacesSupported(); bool userNamespacesSupported();

View file

@ -88,56 +88,4 @@ void ignoreException(Verbosity lvl)
#if __linux__
static AutoCloseFD fdSavedMountNamespace;
static AutoCloseFD fdSavedRoot;
#endif
void saveMountNamespace()
{
#if __linux__
static std::once_flag done;
std::call_once(done, []() {
fdSavedMountNamespace = AutoCloseFD{open("/proc/self/ns/mnt", O_RDONLY)};
if (!fdSavedMountNamespace)
throw SysError("saving parent mount namespace");
fdSavedRoot = AutoCloseFD{open("/proc/self/root", O_RDONLY)};
});
#endif
}
void restoreMountNamespace()
{
#if __linux__
try {
auto savedCwd = absPath(".");
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
throw SysError("restoring parent mount namespace");
if (fdSavedRoot) {
if (fchdir(fdSavedRoot.get()))
throw SysError("chdir into saved root");
if (chroot("."))
throw SysError("chroot into saved root");
}
if (chdir(savedCwd.c_str()) == -1)
throw SysError("restoring cwd");
} catch (Error & e) {
debug(e.msg());
}
#endif
}
void unshareFilesystem()
{
#ifdef __linux__
if (unshare(CLONE_FS) != 0 && errno != EPERM)
throw SysError("unsharing filesystem state in download thread");
#endif
}
} }

View file

@ -39,26 +39,6 @@ struct Source;
extern const std::string nativeSystem; extern const std::string nativeSystem;
/**
* Save the current mount namespace. Ignored if called more than
* once.
*/
void saveMountNamespace();
/**
* Restore the mount namespace saved by saveMountNamespace(). Ignored
* if saveMountNamespace() was never called.
*/
void restoreMountNamespace();
/**
* Cause this thread to not share any FS attributes with the main
* thread, because this causes setns() in restoreMountNamespace() to
* fail.
*/
void unshareFilesystem();
/** /**
* Exception handling in destructors: print an error message, then * Exception handling in destructors: print an error message, then
* ignore the exception. * ignore the exception.

View file

@ -8,6 +8,7 @@
#include "eval-settings.hh" #include "eval-settings.hh"
#include "globals.hh" #include "globals.hh"
#include "legacy.hh" #include "legacy.hh"
#include "namespaces.hh"
#include "shared.hh" #include "shared.hh"
#include "store-api.hh" #include "store-api.hh"
#include "filetransfer.hh" #include "filetransfer.hh"