forked from lix-project/lix
util.{hh,cc}: Split out namespaces.{hh,cc}
Change-Id: I8fd3f3b50c15ede29d489066b4e8d99c2c4636a6
This commit is contained in:
parent
f79ee66646
commit
8b6d2d3915
|
@ -1,5 +1,5 @@
|
|||
#include "filetransfer.hh"
|
||||
#include "util.hh"
|
||||
#include "namespaces.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "s3.hh"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "current-process.hh"
|
||||
#include "file-system.hh"
|
||||
#include "logging.hh"
|
||||
#include "namespaces.hh"
|
||||
#include "signals.hh"
|
||||
#include "util.hh"
|
||||
#include "strings.hh"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#if __linux__
|
||||
|
||||
#include "file-descriptor.hh"
|
||||
#include "file-system.hh"
|
||||
#include "logging.hh"
|
||||
#include "namespaces.hh"
|
||||
|
@ -8,8 +7,67 @@
|
|||
|
||||
#include <sys/mount.h>
|
||||
|
||||
#if __linux__
|
||||
# include <mutex>
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
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()
|
||||
{
|
||||
if (!pathExists("/proc/self/ns/user")) {
|
||||
|
@ -95,6 +153,6 @@ bool mountAndPidNamespacesSupported()
|
|||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,26 @@
|
|||
|
||||
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__
|
||||
|
||||
bool userNamespacesSupported();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -39,26 +39,6 @@ struct Source;
|
|||
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
|
||||
* ignore the exception.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "eval-settings.hh"
|
||||
#include "globals.hh"
|
||||
#include "legacy.hh"
|
||||
#include "namespaces.hh"
|
||||
#include "shared.hh"
|
||||
#include "store-api.hh"
|
||||
#include "filetransfer.hh"
|
||||
|
|
Loading…
Reference in a new issue