daemon: GC remove-unused-links phase uses 'statx' when available.

* config-daemon.ac: Check for 'statx'.
* nix/libstore/gc.cc (LocalStore::removeUnusedLinks) [HAVE_STATX]: Use
'statx' instead of 'lstat'.
This commit is contained in:
Ludovic Courtès 2019-11-26 23:35:24 +01:00
parent 434138e2f2
commit 7738a72186
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 13 additions and 1 deletions

@ -91,8 +91,9 @@ if test "x$guix_build_daemon" = "xyes"; then
dnl sched_setaffinity: to improve RPC locality. dnl sched_setaffinity: to improve RPC locality.
dnl statvfs: to detect disk-full conditions. dnl statvfs: to detect disk-full conditions.
dnl strsignal: for error reporting. dnl strsignal: for error reporting.
dnl statx: fine-grain 'stat' call, new in glibc 2.28.
AC_CHECK_FUNCS([lutimes lchown posix_fallocate sched_setaffinity \ AC_CHECK_FUNCS([lutimes lchown posix_fallocate sched_setaffinity \
statvfs nanosleep strsignal]) statvfs nanosleep strsignal statx])
dnl Check whether the store optimiser can optimise symlinks. dnl Check whether the store optimiser can optimise symlinks.
AC_MSG_CHECKING([whether it is possible to create a link to a symlink]) AC_MSG_CHECKING([whether it is possible to create a link to a symlink])

@ -570,8 +570,17 @@ void LocalStore::removeUnusedLinks(const GCState & state)
if (name == "." || name == "..") continue; if (name == "." || name == "..") continue;
Path path = linksDir + "/" + name; Path path = linksDir + "/" + name;
#ifdef HAVE_STATX
# define st_size stx_size
# define st_nlink stx_nlink
struct statx st;
if (statx(AT_FDCWD, path.c_str(),
AT_SYMLINK_NOFOLLOW | AT_STATX_DONT_SYNC,
STATX_SIZE | STATX_NLINK, &st) == -1)
#else
struct stat st; struct stat st;
if (lstat(path.c_str(), &st) == -1) if (lstat(path.c_str(), &st) == -1)
#endif
throw SysError(format("statting `%1%'") % path); throw SysError(format("statting `%1%'") % path);
if (st.st_nlink != 1) { if (st.st_nlink != 1) {
@ -586,6 +595,8 @@ void LocalStore::removeUnusedLinks(const GCState & state)
throw SysError(format("deleting `%1%'") % path); throw SysError(format("deleting `%1%'") % path);
state.results.bytesFreed += st.st_size; state.results.bytesFreed += st.st_size;
#undef st_size
#undef st_nlink
} }
struct stat st; struct stat st;