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 "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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
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.
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue