forked from lix-project/lix
Merge branch 'fix-writable-shell' of https://github.com/yorickvP/nix
This commit is contained in:
commit
7a71621b7c
|
@ -544,6 +544,14 @@ struct curlFileTransfer : public FileTransfer
|
||||||
stopWorkerThread();
|
stopWorkerThread();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
/* Cause this thread to not share any FS attributes with the main thread,
|
||||||
|
because this causes setns() in restoreMountNamespace() to fail.
|
||||||
|
Ideally, this would happen in the std::thread() constructor. */
|
||||||
|
if (unshare(CLONE_FS) != 0)
|
||||||
|
throw SysError("unsharing filesystem state in download thread");
|
||||||
|
#endif
|
||||||
|
|
||||||
std::map<CURL *, std::shared_ptr<TransferItem>> items;
|
std::map<CURL *, std::shared_ptr<TransferItem>> items;
|
||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
|
|
|
@ -504,6 +504,7 @@ void LocalStore::makeStoreWritable()
|
||||||
throw SysError("getting info about the Nix store mount point");
|
throw SysError("getting info about the Nix store mount point");
|
||||||
|
|
||||||
if (stat.f_flag & ST_RDONLY) {
|
if (stat.f_flag & ST_RDONLY) {
|
||||||
|
saveMountNamespace();
|
||||||
if (unshare(CLONE_NEWNS) == -1)
|
if (unshare(CLONE_NEWNS) == -1)
|
||||||
throw SysError("setting up a private mount namespace");
|
throw SysError("setting up a private mount namespace");
|
||||||
|
|
||||||
|
|
|
@ -1631,10 +1631,34 @@ void setStackSize(size_t stackSize)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
static AutoCloseFD fdSavedMountNamespace;
|
||||||
|
|
||||||
void restoreProcessContext()
|
void saveMountNamespace()
|
||||||
|
{
|
||||||
|
#if __linux__
|
||||||
|
static std::once_flag done;
|
||||||
|
std::call_once(done, []() {
|
||||||
|
fdSavedMountNamespace = open("/proc/self/ns/mnt", O_RDONLY);
|
||||||
|
if (!fdSavedMountNamespace)
|
||||||
|
throw SysError("saving parent mount namespace");
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void restoreMountNamespace()
|
||||||
|
{
|
||||||
|
#if __linux__
|
||||||
|
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
|
||||||
|
throw SysError("restoring parent mount namespace");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void restoreProcessContext(bool restoreMounts)
|
||||||
{
|
{
|
||||||
restoreSignals();
|
restoreSignals();
|
||||||
|
if (restoreMounts) {
|
||||||
|
restoreMountNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
restoreAffinity();
|
restoreAffinity();
|
||||||
|
|
||||||
|
@ -1774,7 +1798,7 @@ void commonChildInit(Pipe & logPipe)
|
||||||
logger = makeSimpleLogger();
|
logger = makeSimpleLogger();
|
||||||
|
|
||||||
const static string pathNullDevice = "/dev/null";
|
const static string pathNullDevice = "/dev/null";
|
||||||
restoreProcessContext();
|
restoreProcessContext(false);
|
||||||
|
|
||||||
/* Put the child in a separate session (and thus a separate
|
/* Put the child in a separate session (and thus a separate
|
||||||
process group) so that it has no controlling terminal (meaning
|
process group) so that it has no controlling terminal (meaning
|
||||||
|
|
|
@ -300,7 +300,15 @@ void setStackSize(size_t stackSize);
|
||||||
|
|
||||||
/* Restore the original inherited Unix process context (such as signal
|
/* Restore the original inherited Unix process context (such as signal
|
||||||
masks, stack size, CPU affinity). */
|
masks, stack size, CPU affinity). */
|
||||||
void restoreProcessContext();
|
void restoreProcessContext(bool restoreMounts = true);
|
||||||
|
|
||||||
|
/* 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();
|
||||||
|
|
||||||
|
|
||||||
class ExecError : public Error
|
class ExecError : public Error
|
||||||
|
|
Loading…
Reference in a new issue