1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 06:31:14 +02:00

Merge pull request #13241 from fzakaria/lix-2100

cherry-pick https://gerrit.lix.systems/c/lix/+/2100
This commit is contained in:
Jörg Thalheim 2025-05-22 18:56:40 +02:00 committed by GitHub
commit b4bea57667
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 43 additions and 58 deletions

View file

@ -176,16 +176,6 @@ void initNix(bool loadConfig)
now. In particular, store objects should be readable by now. In particular, store objects should be readable by
everybody. */ everybody. */
umask(0022); umask(0022);
/* Initialise the PRNG. */
struct timeval tv;
gettimeofday(&tv, 0);
#ifndef _WIN32
srandom(tv.tv_usec);
#endif
srand(tv.tv_usec);
} }

View file

@ -10,7 +10,7 @@
#include "nix/util/util.hh" #include "nix/util/util.hh"
#include "nix/util/compression.hh" #include "nix/util/compression.hh"
#include "nix/store/common-protocol.hh" #include "nix/store/common-protocol.hh"
#include "nix/store/common-protocol-impl.hh" #include "nix/store/common-protocol-impl.hh" // Don't remove is actually needed
#include "nix/store/local-store.hh" // TODO remove, along with remaining downcasts #include "nix/store/local-store.hh" // TODO remove, along with remaining downcasts
#include <fstream> #include <fstream>

View file

@ -34,7 +34,7 @@ SSHMaster::SSHMaster(
throw Error("invalid SSH host name '%s'", host); throw Error("invalid SSH host name '%s'", host);
auto state(state_.lock()); auto state(state_.lock());
state->tmpDir = std::make_unique<AutoDelete>(createTempDir("", "nix", true, true, 0700)); state->tmpDir = std::make_unique<AutoDelete>(createTempDir("", "nix", 0700));
} }
void SSHMaster::addCommonSSHOpts(Strings & args) void SSHMaster::addCommonSSHOpts(Strings & args)

View file

@ -1,22 +1,15 @@
#include "nix/store/build/derivation-builder.hh" #include "nix/store/build/derivation-builder.hh"
#include "nix/util/file-system.hh"
#include "nix/store/local-store.hh" #include "nix/store/local-store.hh"
#include "nix/util/processes.hh" #include "nix/util/processes.hh"
#include "nix/store/indirect-root-store.hh"
#include "nix/store/build/hook-instance.hh"
#include "nix/store/build/worker.hh"
#include "nix/store/builtins.hh" #include "nix/store/builtins.hh"
#include "nix/store/builtins/buildenv.hh"
#include "nix/store/path-references.hh" #include "nix/store/path-references.hh"
#include "nix/util/finally.hh" #include "nix/util/finally.hh"
#include "nix/util/util.hh" #include "nix/util/util.hh"
#include "nix/util/archive.hh" #include "nix/util/archive.hh"
#include "nix/util/git.hh" #include "nix/util/git.hh"
#include "nix/util/compression.hh"
#include "nix/store/daemon.hh" #include "nix/store/daemon.hh"
#include "nix/util/topo-sort.hh" #include "nix/util/topo-sort.hh"
#include "nix/util/callback.hh"
#include "nix/util/json-utils.hh"
#include "nix/util/current-process.hh"
#include "nix/store/build/child.hh" #include "nix/store/build/child.hh"
#include "nix/util/unix-domain-socket.hh" #include "nix/util/unix-domain-socket.hh"
#include "nix/store/posix-fs-canonicalise.hh" #include "nix/store/posix-fs-canonicalise.hh"
@ -671,23 +664,33 @@ static void replaceValidPath(const Path & storePath, const Path & tmpPath)
tmpPath (the replacement), so we have to move it out of the tmpPath (the replacement), so we have to move it out of the
way first. We'd better not be interrupted here, because if way first. We'd better not be interrupted here, because if
we're repairing (say) Glibc, we end up with a broken system. */ we're repairing (say) Glibc, we end up with a broken system. */
Path oldPath = fmt("%1%.old-%2%-%3%", storePath, getpid(), rand()); Path oldPath;
if (pathExists(storePath))
if (pathExists(storePath)) {
// why do we loop here?
// although makeTempPath should be unique, we can't
// guarantee that.
do {
oldPath = makeTempPath(storePath, ".old");
// store paths are often directories so we can't just unlink() it
// let's make sure the path doesn't exist before we try to use it
} while (pathExists(oldPath));
movePath(storePath, oldPath); movePath(storePath, oldPath);
}
try { try {
movePath(tmpPath, storePath); movePath(tmpPath, storePath);
} catch (...) { } catch (...) {
try { try {
// attempt to recover // attempt to recover
movePath(oldPath, storePath); if (!oldPath.empty())
movePath(oldPath, storePath);
} catch (...) { } catch (...) {
ignoreExceptionExceptInterrupt(); ignoreExceptionExceptInterrupt();
} }
throw; throw;
} }
if (!oldPath.empty())
deletePath(oldPath); deletePath(oldPath);
} }
@ -877,7 +880,7 @@ void DerivationBuilderImpl::startBuilder()
/* Create a temporary directory where the build will take /* Create a temporary directory where the build will take
place. */ place. */
topTmpDir = createTempDir(settings.buildDir.get().value_or(""), "nix-build-" + std::string(drvPath.name()), false, false, 0700); topTmpDir = createTempDir(settings.buildDir.get().value_or(""), "nix-build-" + std::string(drvPath.name()), 0700);
#ifdef __APPLE__ #ifdef __APPLE__
if (false) { if (false) {
#else #else

View file

@ -7,6 +7,7 @@
#include "nix/store/globals.hh" #include "nix/store/globals.hh"
#include "nix/store/pathlocks.hh" #include "nix/store/pathlocks.hh"
#include "nix/util/users.hh" #include "nix/util/users.hh"
#include "nix/util/logging.hh"
namespace nix { namespace nix {

View file

@ -8,12 +8,12 @@
#include "nix/util/util.hh" #include "nix/util/util.hh"
#include <atomic> #include <atomic>
#include <random>
#include <cerrno> #include <cerrno>
#include <climits> #include <climits>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <deque> #include <deque>
#include <sstream>
#include <filesystem> #include <filesystem>
#include <fcntl.h> #include <fcntl.h>
@ -27,10 +27,6 @@
# include <io.h> # include <io.h>
#endif #endif
#include "nix/util/strings-inline.hh"
#include "util-config-private.hh"
namespace nix { namespace nix {
DirectoryIterator::DirectoryIterator(const std::filesystem::path& p) { DirectoryIterator::DirectoryIterator(const std::filesystem::path& p) {
@ -582,26 +578,11 @@ std::string defaultTempDir() {
return getEnvNonEmpty("TMPDIR").value_or("/tmp"); return getEnvNonEmpty("TMPDIR").value_or("/tmp");
} }
static Path tempName(Path tmpRoot, const Path & prefix, bool includePid, Path createTempDir(const Path & tmpRoot, const Path & prefix, mode_t mode)
std::atomic<unsigned int> & counter)
{ {
tmpRoot = canonPath(tmpRoot.empty() ? defaultTempDir() : tmpRoot, true);
if (includePid)
return fmt("%1%/%2%-%3%-%4%", tmpRoot, prefix, getpid(), counter++);
else
return fmt("%1%/%2%-%3%", tmpRoot, prefix, counter++);
}
Path createTempDir(const Path & tmpRoot, const Path & prefix,
bool includePid, bool useGlobalCounter, mode_t mode)
{
static std::atomic<unsigned int> globalCounter = 0;
std::atomic<unsigned int> localCounter = 0;
auto & counter(useGlobalCounter ? globalCounter : localCounter);
while (1) { while (1) {
checkInterrupt(); checkInterrupt();
Path tmpDir = tempName(tmpRoot, prefix, includePid, counter); Path tmpDir = makeTempPath(tmpRoot, prefix);
if (mkdir(tmpDir.c_str() if (mkdir(tmpDir.c_str()
#ifndef _WIN32 // TODO abstract mkdir perms for Windows #ifndef _WIN32 // TODO abstract mkdir perms for Windows
, mode , mode
@ -641,6 +622,14 @@ std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
return {std::move(fd), tmpl}; return {std::move(fd), tmpl};
} }
Path makeTempPath(const Path & root, const Path & suffix)
{
// start the counter at a random value to minimize issues with preexisting temp paths
static std::atomic<uint32_t> counter(std::random_device{}());
auto tmpRoot = canonPath(root.empty() ? defaultTempDir() : root, true);
return fmt("%1%/%2%-%3%-%4%", tmpRoot, suffix, getpid(), counter.fetch_add(1, std::memory_order_relaxed));
}
void createSymlink(const Path & target, const Path & link) void createSymlink(const Path & target, const Path & link)
{ {
try { try {

View file

@ -6,8 +6,6 @@
*/ */
#include "nix/util/types.hh" #include "nix/util/types.hh"
#include "nix/util/error.hh"
#include "nix/util/logging.hh"
#include "nix/util/file-descriptor.hh" #include "nix/util/file-descriptor.hh"
#include "nix/util/file-path.hh" #include "nix/util/file-path.hh"
@ -18,12 +16,8 @@
#ifdef _WIN32 #ifdef _WIN32
# include <windef.h> # include <windef.h>
#endif #endif
#include <signal.h>
#include <atomic>
#include <functional> #include <functional>
#include <map>
#include <sstream>
#include <optional> #include <optional>
/** /**
@ -316,8 +310,8 @@ typedef std::unique_ptr<DIR, DIRDeleter> AutoCloseDir;
/** /**
* Create a temporary directory. * Create a temporary directory.
*/ */
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755); mode_t mode = 0755);
/** /**
* Create a temporary file, returning a file handle and its path. * Create a temporary file, returning a file handle and its path.
@ -335,6 +329,14 @@ Path defaultTempDir();
*/ */
bool isExecutableFileAmbient(const std::filesystem::path & exe); bool isExecutableFileAmbient(const std::filesystem::path & exe);
/**
* Return temporary path constructed by appending a suffix to a root path.
*
* The constructed path looks like `<root><suffix>-<pid>-<unique>`. To create a
* path nested in a directory, provide a suffix starting with `/`.
*/
Path makeTempPath(const Path & root, const Path & suffix = ".tmp");
/** /**
* Used in various places. * Used in various places.
*/ */

View file

@ -1,5 +1,5 @@
#include <atomic>
#include "nix/util/source-accessor.hh" #include "nix/util/source-accessor.hh"
#include "nix/util/archive.hh"
namespace nix { namespace nix {