From 2e3e5d21988fc2cafb2a9eaf4b00976ea425629d Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Tue, 3 Sep 2019 21:36:29 +0200 Subject: daemon: Invoke 'guix gc --list-busy' instead of 'list-runtime-roots'. * nix/scripts/list-runtime-roots.in: Remove. * guix/store/roots.scm (%proc-directory): New variable. (proc-file-roots, proc-exe-roots, proc-cwd-roots) (proc-fd-roots, proc-maps-roots, proc-environ-roots) (referenced-files, canonicalize-store-item, busy-store-items): New procedures, taken from 'list-runtime-roots.in'. * nix/libstore/globals.hh (Settings)[guixProgram]: New field. * nix/libstore/globals.cc (Settings::processEnvironment): Initialize 'guixProgram'. * nix/libstore/gc.cc (addAdditionalRoots): Drop code related to 'NIX_ROOT_FINDER'. Run "guix gc --list-busy". * nix/local.mk (nodist_pkglibexec_SCRIPTS): Remove 'scripts/list-runtime-roots'. * config-daemon.ac: Don't output nix/scripts/list-runtime-roots. * build-aux/pre-inst-env.in: Don't set 'NIX_ROOT_FINDER'. Set 'GUIX'. * doc/guix.texi (Invoking guix gc): Document '--list-busy'. * guix/scripts/gc.scm (show-help, %options): Add "--list-busy". (guix-gc)[list-busy]: New procedure. Handle the 'list-busy' action. --- nix/libstore/gc.cc | 11 ++- nix/libstore/globals.cc | 1 + nix/libstore/globals.hh | 3 + nix/local.mk | 1 - nix/scripts/list-runtime-roots.in | 147 -------------------------------------- 5 files changed, 8 insertions(+), 155 deletions(-) delete mode 100644 nix/scripts/list-runtime-roots.in (limited to 'nix') diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc index 46171e116c..c466996668 100644 --- a/nix/libstore/gc.cc +++ b/nix/libstore/gc.cc @@ -339,14 +339,11 @@ Roots LocalStore::findRoots() static void addAdditionalRoots(StoreAPI & store, PathSet & roots) { - Path rootFinder = getEnv("NIX_ROOT_FINDER", - settings.nixLibexecDir + "/list-runtime-roots"); + debug(format("executing `%1% gc --list-busy' to find additional roots") + % settings.guixProgram); - if (rootFinder.empty()) return; - - debug(format("executing `%1%' to find additional roots") % rootFinder); - - string result = runProgram(rootFinder); + const Strings args = { "gc", "--list-busy" }; + string result = runProgram(settings.guixProgram, false, args); StringSet paths = tokenizeString(result, "\n"); diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc index 6df20e7a52..8f7c976fcb 100644 --- a/nix/libstore/globals.cc +++ b/nix/libstore/globals.cc @@ -73,6 +73,7 @@ void Settings::processEnvironment() nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR)); nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR)); nixDaemonSocketFile = canonPath(nixStateDir + DEFAULT_SOCKET_PATH); + guixProgram = canonPath(getEnv("GUIX", nixBinDir + "/guix")); } diff --git a/nix/libstore/globals.hh b/nix/libstore/globals.hh index b073f724b6..0d9315a41a 100644 --- a/nix/libstore/globals.hh +++ b/nix/libstore/globals.hh @@ -66,6 +66,9 @@ struct Settings { /* File name of the socket the daemon listens to. */ Path nixDaemonSocketFile; + /* Absolute file name of the 'guix' program. */ + Path guixProgram; + /* Whether to keep temporary directories of failed builds. */ bool keepFailed; diff --git a/nix/local.mk b/nix/local.mk index 6d7e60e9fb..fd7379b5ff 100644 --- a/nix/local.mk +++ b/nix/local.mk @@ -155,7 +155,6 @@ noinst_HEADERS = \ (write (get-string-all in) out)))))" nodist_pkglibexec_SCRIPTS = \ - %D%/scripts/list-runtime-roots \ %D%/scripts/substitute \ %D%/scripts/download diff --git a/nix/scripts/list-runtime-roots.in b/nix/scripts/list-runtime-roots.in deleted file mode 100644 index 5f2660fb5e..0000000000 --- a/nix/scripts/list-runtime-roots.in +++ /dev/null @@ -1,147 +0,0 @@ -#!@GUILE@ -ds -!# -;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2017 Ludovic Courtès -;;; -;;; This file is part of GNU Guix. -;;; -;;; GNU Guix is free software; you can redistribute it and/or modify it -;;; under the terms of the GNU General Public License as published by -;;; the Free Software Foundation; either version 3 of the License, or (at -;;; your option) any later version. -;;; -;;; GNU Guix is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with GNU Guix. If not, see . - -;;; -;;; List files being used at run time; these files are garbage collector -;;; roots. This is equivalent to `find-runtime-roots.pl' in Nix. -;;; - -(use-modules (ice-9 ftw) - (ice-9 regex) - (ice-9 rdelim) - (ice-9 match) - (srfi srfi-1) - (srfi srfi-26) - (rnrs io ports)) - -(define %proc-directory - ;; Mount point of Linuxish /proc file system. - "/proc") - -(define %store-directory - (or (getenv "NIX_STORE_DIR") - "@storedir@")) - -(define (proc-file-roots dir file) - "Return a one-element list containing the file pointed to by DIR/FILE, -or the empty list." - (or (and=> (false-if-exception (readlink (string-append dir "/" file))) - list) - '())) - -(define proc-exe-roots (cut proc-file-roots <> "exe")) -(define proc-cwd-roots (cut proc-file-roots <> "cwd")) - -(define (proc-fd-roots dir) - "Return the list of store files referenced by DIR, which is a -/proc/XYZ directory." - (let ((dir (string-append dir "/fd"))) - (filter-map (lambda (file) - (let ((target (false-if-exception - (readlink (string-append dir "/" file))))) - (and target - (string-prefix? "/" target) - target))) - (or (scandir dir string->number) '())))) - -(define (proc-maps-roots dir) - "Return the list of store files referenced by DIR, which is a -/proc/XYZ directory." - (define %file-mapping-line - (make-regexp "^.*[[:blank:]]+/([^ ]+)$")) - - (call-with-input-file (string-append dir "/maps") - (lambda (maps) - (let loop ((line (read-line maps)) - (roots '())) - (cond ((eof-object? line) - roots) - ((regexp-exec %file-mapping-line line) - => - (lambda (match) - (let ((file (string-append "/" - (match:substring match 1)))) - (loop (read-line maps) - (cons file roots))))) - (else - (loop (read-line maps) roots))))))) - -(define (proc-environ-roots dir) - "Return the list of store files referenced by DIR/environ, where DIR is a -/proc/XYZ directory." - (define split-on-nul - (cute string-tokenize <> - (char-set-complement (char-set #\nul)))) - - (define (rhs-file-names str) - (let ((equal (string-index str #\=))) - (if equal - (let* ((str (substring str (+ 1 equal))) - (rx (string-append (regexp-quote %store-directory) - "/[0-9a-z]{32}-[a-zA-Z0-9\\._+-]+"))) - (map match:substring (list-matches rx str))) - '()))) - - (define environ - (string-append dir "/environ")) - - (append-map rhs-file-names - (split-on-nul - (call-with-input-file environ - get-string-all)))) - -(define (referenced-files) - "Return the list of referenced store items." - (append-map (lambda (pid) - (let ((proc (string-append %proc-directory "/" pid))) - (catch 'system-error - (lambda () - (append (proc-exe-roots proc) - (proc-cwd-roots proc) - (proc-fd-roots proc) - (proc-maps-roots proc) - (proc-environ-roots proc))) - (lambda args - (let ((err (system-error-errno args))) - (if (or (= ENOENT err) ;TOCTTOU race - (= ESRCH err) ;ditto - (= EACCES err)) ;not running as root - '() - (apply throw args))))))) - (scandir %proc-directory string->number - (lambda (a b) - (< (string->number a) (string->number b)))))) - -(define canonicalize-store-item - (let* ((store (string-append %store-directory "/")) - (prefix (string-length store))) - (lambda (file) - "Return #f if FILE is not a store item; otherwise, return the store file -name without any sub-directory components." - (and (string-prefix? store file) - (string-append store - (let ((base (string-drop file prefix))) - (match (string-index base #\/) - (#f base) - (slash (string-take base slash))))))))) - -(for-each (cut simple-format #t "~a~%" <>) - (delete-duplicates - (filter-map canonicalize-store-item (referenced-files)))) -- cgit v1.2.3