Skip to content

Commit

Permalink
WIP local store on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Ericson2314 committed May 2, 2024
1 parent 8402674 commit c641f8a
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 20 deletions.
File renamed without changes.
22 changes: 12 additions & 10 deletions src/libstore/unix/local-store.cc → src/libstore/local-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,34 @@
#include <new>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <utime.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include <grp.h>

#ifndef _WIN32
# include <grp.h>
#endif

#if __linux__
#include <sched.h>
#include <sys/statvfs.h>
#include <sys/mount.h>
#include <sys/ioctl.h>
# include <sched.h>
# include <sys/statvfs.h>
# include <sys/mount.h>
# include <sys/ioctl.h>
#endif

#ifdef __CYGWIN__
#include <windows.h>
# include <windows.h>
#endif

#include <sqlite3.h>


namespace nix {

using namespace nix::unix;

std::string LocalStoreConfig::doc()
{
return
Expand Down Expand Up @@ -224,6 +224,7 @@ LocalStore::LocalStore(const Params & params)
}
}

#ifndef _WIN32
/* Optionally, create directories and set permissions for a
multi-user install. */
if (isRootUser() && settings.buildUsersGroup != "") {
Expand All @@ -245,6 +246,7 @@ LocalStore::LocalStore(const Params & params)
}
}
}
#endif

/* Ensure that the store and its parents are not symlinks. */
if (!settings.allowSymlinkedStore) {
Expand Down Expand Up @@ -1309,7 +1311,7 @@ StorePath LocalStore::addToStoreFromDump(
narHash = narSink.finish();
}

canonicalisePathMetaData(realPath, {}); // FIXME: merge into restorePath
canonicalisePathMetaData(realPath); // FIXME: merge into restorePath

optimisePath(realPath, repair);

Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/libstore/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ else
endif
endif

$(d)/unix/local-store.cc: $(d)/unix/schema.sql.gen.hh $(d)/unix/ca-specific-schema.sql.gen.hh
$(d)/local-store.cc: $(d)/schema.sql.gen.hh $(d)/ca-specific-schema.sql.gen.hh

$(d)/unix/build.cc:

clean-files += $(d)/unix/schema.sql.gen.hh $(d)/unix/ca-specific-schema.sql.gen.hh
clean-files += $(d)/schema.sql.gen.hh $(d)/ca-specific-schema.sql.gen.hh

$(eval $(call install-file-in, $(buildprefix)$(d)/nix-store.pc, $(libdir)/pkgconfig, 0644))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct

}

#ifndef _WIN32 // TODO implement
if (st.st_mtime != mtimeStore) {
struct timeval times[2];
times[0].tv_sec = st.st_atime;
Expand All @@ -46,6 +47,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
#endif
throw SysError("changing modification time of '%1%'", path);
}
#endif
}


Expand All @@ -57,7 +59,9 @@ void canonicaliseTimestampAndPermissions(const Path & path)

static void canonicalisePathMetaData_(
const Path & path,
#ifndef _WIN32
std::optional<std::pair<uid_t, uid_t>> uidRange,
#endif
InodesSeen & inodesSeen)
{
checkInterrupt();
Expand Down Expand Up @@ -99,6 +103,7 @@ static void canonicalisePathMetaData_(
}
#endif

#ifndef _WIN32
/* Fail if the file is not owned by the build user. This prevents
us from messing up the ownership/permissions of files
hard-linked into the output (e.g. "ln /etc/shadow $out/foo").
Expand All @@ -112,11 +117,13 @@ static void canonicalisePathMetaData_(
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
return;
}
#endif

inodesSeen.insert(Inode(st.st_dev, st.st_ino));

canonicaliseTimestampAndPermissions(path, st);

#ifndef _WIN32
/* Change ownership to the current uid. If it's a symlink, use
lchown if available, otherwise don't bother. Wrong ownership
of a symlink doesn't matter, since the owning user can't change
Expand All @@ -134,22 +141,36 @@ static void canonicalisePathMetaData_(
throw SysError("changing owner of '%1%' to %2%",
path, geteuid());
}
#endif

if (S_ISDIR(st.st_mode)) {
DirEntries entries = readDirectory(path);
for (auto & i : entries)
canonicalisePathMetaData_(path + "/" + i.name, uidRange, inodesSeen);
canonicalisePathMetaData_(
path + "/" + i.name,
#ifndef _WIN32
uidRange,
#endif
inodesSeen);
}
}


void canonicalisePathMetaData(
const Path & path,
#ifndef _WIN32
std::optional<std::pair<uid_t, uid_t>> uidRange,
#endif
InodesSeen & inodesSeen)
{
canonicalisePathMetaData_(path, uidRange, inodesSeen);
canonicalisePathMetaData_(
path,
#ifndef _WIN32
uidRange,
#endif
inodesSeen);

#ifndef _WIN32
/* On platforms that don't have lchown(), the top-level path can't
be a symlink, since we can't change its ownership. */
auto st = lstat(path);
Expand All @@ -158,14 +179,23 @@ void canonicalisePathMetaData(
assert(S_ISLNK(st.st_mode));
throw Error("wrong ownership of top-level store path '%1%'", path);
}
#endif
}


void canonicalisePathMetaData(const Path & path,
std::optional<std::pair<uid_t, uid_t>> uidRange)
void canonicalisePathMetaData(const Path & path
#ifndef _WIN32
, std::optional<std::pair<uid_t, uid_t>> uidRange
#endif
)
{
InodesSeen inodesSeen;
canonicalisePathMetaData(path, uidRange, inodesSeen);
canonicalisePathMetaData_(
path,
#ifndef _WIN32
uidRange,
#endif
inodesSeen);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,25 @@ typedef std::set<Inode> InodesSeen;
* without execute permission; setuid bits etc. are cleared)
*
* - the owner and group are set to the Nix user and group, if we're
* running as root.
* running as root. (Unix only.)
*
* If uidRange is not empty, this function will throw an error if it
* encounters files owned by a user outside of the closed interval
* [uidRange->first, uidRange->second].
*/
void canonicalisePathMetaData(
const Path & path,
#ifndef _WIN32
std::optional<std::pair<uid_t, uid_t>> uidRange,
#endif
InodesSeen & inodesSeen);

void canonicalisePathMetaData(
const Path & path,
std::optional<std::pair<uid_t, uid_t>> uidRange);
const Path & path
#ifndef _WIN32
, std::optional<std::pair<uid_t, uid_t>> uidRange = std::nullopt
#endif
);

void canonicaliseTimestampAndPermissions(const Path & path);

Expand Down
File renamed without changes.

0 comments on commit c641f8a

Please sign in to comment.