Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion maintainers/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@
''^src/libutil/json-utils\.cc$''
''^src/libutil/include/nix/util/json-utils\.hh$''
''^src/libutil/linux/cgroup\.cc$''
''^src/libutil/linux/namespaces\.cc$''
''^src/libutil/linux/linux-namespaces\.cc$''
''^src/libutil/logging\.cc$''
''^src/libutil/include/nix/util/logging\.hh$''
''^src/libutil/memory-source-accessor\.cc$''
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/filetransfer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#endif

#ifdef __linux__
# include "nix/util/namespaces.hh"
# include "nix/util/linux-namespaces.hh"
#endif

#include <unistd.h>
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Settings::Settings()
builders = concatStringsSep("\n", ss);
}

#if defined(__linux__) && defined(SANDBOX_SHELL)
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(SANDBOX_SHELL)
sandboxPaths = tokenizeString<StringSet>("/bin/sh=" SANDBOX_SHELL);
#endif

Expand Down
2 changes: 2 additions & 0 deletions src/libstore/include/nix/store/globals.hh
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,9 @@ public:
description of the `size` option of `tmpfs` in mount(8). The default
is `50%`.
)"};
#endif

#if defined(__linux__) || defined(__FreeBSD__)
Setting<Path> sandboxBuildDir{this, "/build", "sandbox-build-dir",
R"(
*Linux only*
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/unix/build/linux-derivation-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# include "nix/store/personality.hh"
# include "nix/util/cgroup.hh"
# include "nix/util/namespaces.hh"
# include "nix/util/linux-namespaces.hh"
# include "linux/fchmodat2-compat.hh"

# include <sys/ioctl.h>
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/unix/user-lock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ bool useBuildUsers()
#ifdef __linux__
static bool b = (settings.buildUsersGroup != "" || settings.autoAllocateUids) && isRootUser();
return b;
#elif defined(__APPLE__)
#elif defined(__APPLE__) && defined(__FreeBSD__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed this in review, but fixed in #13455

static bool b = settings.buildUsersGroup != "" && isRootUser();
return b;
#else
Expand Down
25 changes: 24 additions & 1 deletion src/libutil/current-process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
#ifdef __linux__
# include <mutex>
# include "nix/util/cgroup.hh"
# include "nix/util/namespaces.hh"
# include "nix/util/linux-namespaces.hh"
#endif

#ifdef __FreeBSD__
# include <sys/param.h>
# include <sys/sysctl.h>
#endif

namespace nix {
Expand Down Expand Up @@ -115,6 +120,24 @@ std::optional<Path> getSelfExe()
return buf;
else
return std::nullopt;
#elif defined(__FreeBSD__)
int sysctlName[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PATHNAME,
-1,
};
size_t pathLen = 0;
if (sysctl(sysctlName, sizeof(sysctlName) / sizeof(sysctlName[0]), nullptr, &pathLen, nullptr, 0) < 0) {
return std::nullopt;
}

std::vector<char> path(pathLen);
if (sysctl(sysctlName, sizeof(sysctlName) / sizeof(sysctlName[0]), path.data(), &pathLen, nullptr, 0) < 0) {
return std::nullopt;
}

return Path(path.begin(), path.end());
#else
return std::nullopt;
#endif
Expand Down
66 changes: 61 additions & 5 deletions src/libutil/file-system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@

#include <boost/iostreams/device/mapped_file.hpp>

#ifdef __FreeBSD__
# include <sys/param.h>
# include <sys/mount.h>
#endif

#ifdef _WIN32
# include <io.h>
#endif
Expand Down Expand Up @@ -364,6 +369,13 @@ void syncParent(const Path & path)
fd.fsync();
}

#ifdef __FreeBSD__
#define MOUNTEDPATHS_PARAM , std::set<Path> &mountedPaths
#define MOUNTEDPATHS_ARG , mountedPaths
#else
#define MOUNTEDPATHS_PARAM
#define MOUNTEDPATHS_ARG
#endif
Comment on lines +372 to +378
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity: is there a reason to do this ugly define stuff rather than making it std::option<std::set<Path>> or something similar?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would create a bunch of runtime failure modes. non-freebsd would have to assert it is not present, and freebsd would to assert it is present


void recursiveSync(const Path & path)
{
Expand Down Expand Up @@ -410,11 +422,19 @@ void recursiveSync(const Path & path)
}


static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed)
static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed MOUNTEDPATHS_PARAM)
{
#ifndef _WIN32
checkInterrupt();

#ifdef __FreeBSD__
// In case of emergency (unmount fails for some reason) not recurse into mountpoints.
// This prevents us from tearing up the nullfs-mounted nix store.
if (mountedPaths.find(path) != mountedPaths.end()) {
return;
}
#endif

std::string name(baseNameOf(path.native()));

struct stat st;
Expand Down Expand Up @@ -468,7 +488,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
checkInterrupt();
std::string childName = dirent->d_name;
if (childName == "." || childName == "..") continue;
_deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
_deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed MOUNTEDPATHS_ARG);
}
if (errno) throw SysError("reading directory %1%", path);
}
Expand All @@ -484,7 +504,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
#endif
}

static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed)
static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed MOUNTEDPATHS_PARAM)
{
Path dir = dirOf(path.string());
if (dir == "")
Expand All @@ -496,7 +516,7 @@ static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFree
throw SysError("opening directory '%1%'", path);
}

_deletePath(dirfd.get(), path, bytesFreed);
_deletePath(dirfd.get(), path, bytesFreed MOUNTEDPATHS_ARG);
}


Expand Down Expand Up @@ -529,8 +549,20 @@ void createDirs(const std::filesystem::path & path)
void deletePath(const std::filesystem::path & path, uint64_t & bytesFreed)
{
//Activity act(*logger, lvlDebug, "recursively deleting path '%1%'", path);
#ifdef __FreeBSD__
std::set<Path> mountedPaths;
struct statfs *mntbuf;
int count;
if ((count = getmntinfo(&mntbuf, MNT_WAIT)) < 0) {
throw SysError("getmntinfo");
}

for (int i = 0; i < count; i++) {
mountedPaths.emplace(mntbuf[i].f_mntonname);
}
#endif
bytesFreed = 0;
_deletePath(path, bytesFreed);
_deletePath(path, bytesFreed MOUNTEDPATHS_ARG);
}


Expand Down Expand Up @@ -572,6 +604,30 @@ void AutoDelete::reset(const std::filesystem::path & p, bool recursive) {

//////////////////////////////////////////////////////////////////////

#ifdef __FreeBSD__
AutoUnmount::AutoUnmount() : del{false} {}

AutoUnmount::AutoUnmount(Path &p) : path(p), del(true) {}

AutoUnmount::~AutoUnmount()
{
try {
if (del) {
if (unmount(path.c_str(), 0) < 0) {
throw SysError("Failed to unmount path %1%", path);
}
}
} catch (...) {
ignoreExceptionInDestructor();
}
}

void AutoUnmount::cancel()
{
del = false;
}
#endif

//////////////////////////////////////////////////////////////////////

std::string defaultTempDir() {
Expand Down
52 changes: 52 additions & 0 deletions src/libutil/freebsd/freebsd-jail.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifdef __FreeBSD__
# include "nix/util/freebsd-jail.hh"

# include <sys/resource.h>
# include <sys/param.h>
# include <sys/jail.h>
# include <sys/mount.h>

# include "nix/util/error.hh"
# include "nix/util/util.hh"

namespace nix {

AutoRemoveJail::AutoRemoveJail()
: del{false}
{
}

AutoRemoveJail::AutoRemoveJail(int jid)
: jid(jid)
, del(true)
{
}

AutoRemoveJail::~AutoRemoveJail()
{
try {
if (del) {
if (jail_remove(jid) < 0) {
throw SysError("Failed to remove jail %1%", jid);
}
}
} catch (...) {
ignoreExceptionInDestructor();
}
}

void AutoRemoveJail::cancel()
{
del = false;
}

void AutoRemoveJail::reset(int j)
{
del = true;
jid = j;
}

//////////////////////////////////////////////////////////////////////

}
#endif
20 changes: 20 additions & 0 deletions src/libutil/freebsd/include/nix/util/freebsd-jail.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
///@file

#include "nix/util/types.hh"

namespace nix {

class AutoRemoveJail
{
int jid;
bool del;
public:
AutoRemoveJail(int jid);
AutoRemoveJail();
~AutoRemoveJail();
void cancel();
void reset(int j);
};

}
7 changes: 7 additions & 0 deletions src/libutil/freebsd/include/nix/util/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Public headers directory

include_dirs += include_directories('../..')

headers += files(
'freebsd-jail.hh',
)
5 changes: 5 additions & 0 deletions src/libutil/freebsd/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sources += files(
'freebsd-jail.cc',
)

subdir('include/nix/util')
15 changes: 14 additions & 1 deletion src/libutil/include/nix/util/file-system.hh
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ typedef std::unique_ptr<DIR, DIRDeleter> AutoCloseDir;
/**
* Create a temporary directory.
*/
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
mode_t mode = 0755);

/**
Expand Down Expand Up @@ -420,4 +420,17 @@ private:
std::filesystem::directory_iterator it_;
};

#ifdef __FreeBSD__
class AutoUnmount
{
Path path;
bool del;
public:
AutoUnmount(Path&);
AutoUnmount();
~AutoUnmount();
void cancel();
};
#endif

}
2 changes: 1 addition & 1 deletion src/libutil/linux/include/nix/util/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ include_dirs += include_directories('../..')

headers += files(
'cgroup.hh',
'namespaces.hh',
'linux-namespaces.hh',
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "nix/util/linux-namespaces.hh"
#include "nix/util/current-process.hh"
#include "nix/util/util.hh"
#include "nix/util/finally.hh"
Expand Down
2 changes: 1 addition & 1 deletion src/libutil/linux/meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
sources += files(
'cgroup.cc',
'namespaces.cc',
'linux-namespaces.cc',
)

subdir('include/nix/util')
4 changes: 4 additions & 0 deletions src/libutil/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ if host_machine.system() == 'linux'
subdir('linux')
endif

if host_machine.system() == 'freebsd'
subdir('freebsd')
endif

if host_machine.system() == 'windows'
subdir('windows')
else
Expand Down
2 changes: 1 addition & 1 deletion src/nix/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#endif

#ifdef __linux__
# include "nix/util/namespaces.hh"
# include "nix/util/linux-namespaces.hh"
#endif

#ifndef _WIN32
Expand Down
Loading