summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2012-12-05 16:29:28 +0100
committerLudovic Courtès <ludo@gnu.org>2012-12-05 16:29:28 +0100
commitf5c82e15e0e76b855bc4cc88ffb79331b7083f39 (patch)
treebe5fa23b0899617c411afca2413655bb1d073ab7
parent8b15ac6700f1345e9efa709dea6e4efcbdaf6d7a (diff)
daemon: Add `list-runtime-roots' script.
* nix/scripts/list-runtime-roots.in: New file. * config-daemon.ac: Add `AC_CONFIG_FILES' invocation for it. * daemon.am (nodist_pkglibexec_SCRIPTS): New variable. (AM_TESTS_ENVIRONMENT): Define `top_builddir'. * tests/guix-daemon.sh: Export `NIX_ROOT_FINDER'. * nix/sync-with-upstream: Substitute the path to the root finder in libstore/gc.cc.
-rw-r--r--.gitignore1
-rw-r--r--config-daemon.ac3
-rw-r--r--daemon.am4
-rw-r--r--nix/scripts/list-runtime-roots.in116
-rwxr-xr-xnix/sync-with-upstream4
-rw-r--r--tests/guix-daemon.sh4
6 files changed, 131 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index d39ad6ed960..3ef17152bac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,3 +61,4 @@ stamp-h[0-9]
61/libutil.a 61/libutil.a
62/guix-daemon 62/guix-daemon
63/test-tmp 63/test-tmp
64/nix/scripts/list-runtime-roots
diff --git a/config-daemon.ac b/config-daemon.ac
index a10be14632c..946f6e453d6 100644
--- a/config-daemon.ac
+++ b/config-daemon.ac
@@ -91,6 +91,9 @@ if test "x$guix_build_daemon" = "xyes"; then
91 91
92 dnl Check for <linux/fs.h> (for immutable file support). 92 dnl Check for <linux/fs.h> (for immutable file support).
93 AC_CHECK_HEADERS([linux/fs.h]) 93 AC_CHECK_HEADERS([linux/fs.h])
94
95 AC_CONFIG_FILES([nix/scripts/list-runtime-roots],
96 [chmod +x nix/scripts/list-runtime-roots])
94fi 97fi
95 98
96AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"]) 99AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"])
diff --git a/daemon.am b/daemon.am
index 48b0871a97b..f5d58ea2751 100644
--- a/daemon.am
+++ b/daemon.am
@@ -146,6 +146,9 @@ nix/libstore/schema.sql.hh: nix/libstore/schema.sql
146 (lambda (in) \ 146 (lambda (in) \
147 (write (get-string-all in) out)))))" 147 (write (get-string-all in) out)))))"
148 148
149nodist_pkglibexec_SCRIPTS = \
150 nix/scripts/list-runtime-roots
151
149EXTRA_DIST += \ 152EXTRA_DIST += \
150 nix/sync-with-upstream \ 153 nix/sync-with-upstream \
151 nix/libstore/schema.sql \ 154 nix/libstore/schema.sql \
@@ -156,6 +159,7 @@ EXTRA_DIST += \
156test_root = $(abs_top_builddir)/test-tmp 159test_root = $(abs_top_builddir)/test-tmp
157 160
158AM_TESTS_ENVIRONMENT += \ 161AM_TESTS_ENVIRONMENT += \
162 top_builddir="$(abs_top_builddir)" \
159 TEST_ROOT="$(test_root)" 163 TEST_ROOT="$(test_root)"
160 164
161TESTS += \ 165TESTS += \
diff --git a/nix/scripts/list-runtime-roots.in b/nix/scripts/list-runtime-roots.in
new file mode 100644
index 00000000000..5c21ae543d1
--- /dev/null
+++ b/nix/scripts/list-runtime-roots.in
@@ -0,0 +1,116 @@
1#!@GUILE@ -ds
2!#
3;;; Guix --- Nix package management from Guile. -*- coding: utf-8 -*-
4;;; Copyright (C) 2012 Ludovic Courtès <ludo@gnu.org>
5;;;
6;;; This file is part of Guix.
7;;;
8;;; Guix is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; Guix is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with Guix. If not, see <http://www.gnu.org/licenses/>.
20
21;;;
22;;; List files being used at run time; these files are garbage collector
23;;; roots. This is equivalent to `find-runtime-roots.pl' in Nix.
24;;;
25
26(use-modules (ice-9 ftw)
27 (ice-9 regex)
28 (ice-9 rdelim)
29 (ice-9 popen)
30 (srfi srfi-1)
31 (srfi srfi-26))
32
33(define %proc-directory
34 ;; Mount point of Linuxish /proc file system.
35 "/proc")
36
37(define (proc-file-roots dir file)
38 "Return a one-element list containing the file pointed to by DIR/FILE,
39or the empty list."
40 (or (and=> (false-if-exception (readlink (string-append dir "/" file)))
41 list)
42 '()))
43
44(define proc-exe-roots (cut proc-file-roots <> "exe"))
45(define proc-cwd-roots (cut proc-file-roots <> "cwd"))
46
47(define (proc-fd-roots dir)
48 "Return the list of store files referenced by DIR, which is a
49/proc/XYZ directory."
50 (let ((dir (string-append dir "/fd")))
51 (filter-map (lambda (file)
52 (let ((target (false-if-exception
53 (readlink (string-append dir "/" file)))))
54 (and target
55 (string-prefix? "/" target)
56 target)))
57 (scandir dir string->number))))
58
59(define (proc-maps-roots dir)
60 "Return the list of store files referenced by DIR, which is a
61/proc/XYZ directory."
62 (define %file-mapping-line
63 (make-regexp "^.*[[:blank:]]+/([^ ]+)$"))
64
65 (call-with-input-file (string-append dir "/maps")
66 (lambda (maps)
67 (let loop ((line (read-line maps))
68 (roots '()))
69 (cond ((eof-object? line)
70 roots)
71 ((regexp-exec %file-mapping-line line)
72 =>
73 (lambda (match)
74 (let ((file (string-append "/"
75 (match:substring match 1))))
76 (loop (read-line maps)
77 (cons file roots)))))
78 (else
79 (loop (read-line maps) roots)))))))
80
81(define (lsof-roots)
82 "Return the list of roots as found by calling `lsof'."
83 (catch 'system
84 (lambda ()
85 (let ((pipe (open-pipe* OPEN_READ "lsof" "-n" "-w" "-F" "n")))
86 (define %file-rx
87 (make-regexp "^n/(.*)$"))
88
89 (let loop ((line (read-line pipe))
90 (roots '()))
91 (cond ((eof-object? line)
92 (begin
93 (close-pipe pipe)
94 roots))
95 ((regexp-exec %file-rx line)
96 =>
97 (lambda (match)
98 (loop (read-line pipe)
99 (cons (string-append "/"
100 (match:substring match 1))
101 roots))))
102 (else
103 (loop (read-line pipe) roots))))))
104 (lambda _
105 '())))
106
107(let ((proc (format #f "~a/~a" %proc-directory (getpid))))
108 (for-each (cut simple-format #t "~a~%" <>)
109 (delete-duplicates
110 (let ((proc-roots (if (file-exists? proc)
111 (append (proc-exe-roots proc)
112 (proc-cwd-roots proc)
113 (proc-fd-roots proc)
114 (proc-maps-roots proc))
115 '())))
116 (append proc-roots (lsof-roots))))))
diff --git a/nix/sync-with-upstream b/nix/sync-with-upstream
index 324dcb27c9e..69bd1fbee7e 100755
--- a/nix/sync-with-upstream
+++ b/nix/sync-with-upstream
@@ -62,3 +62,7 @@ do
62done 62done
63 63
64cp -v "$top_srcdir/nix-upstream/"{COPYING,AUTHORS} "$top_srcdir/nix" 64cp -v "$top_srcdir/nix-upstream/"{COPYING,AUTHORS} "$top_srcdir/nix"
65
66# Substitutions.
67sed -i "$top_srcdir/nix/libstore/gc.cc" \
68 -e 's|/nix/find-runtime-roots\.pl|/guix/list-runtime-roots|g'
diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh
index d7926b2376f..b6b92a78d43 100644
--- a/tests/guix-daemon.sh
+++ b/tests/guix-daemon.sh
@@ -29,8 +29,10 @@ NIX_LOCALSTATE_DIR="$TEST_ROOT/var"
29NIX_LOG_DIR="$TEST_ROOT/var/log/nix" 29NIX_LOG_DIR="$TEST_ROOT/var/log/nix"
30NIX_STATE_DIR="$TEST_ROOT/var/nix" 30NIX_STATE_DIR="$TEST_ROOT/var/nix"
31NIX_DB_DIR="$TEST_ROOT/db" 31NIX_DB_DIR="$TEST_ROOT/db"
32NIX_ROOT_FINDER="$top_builddir/nix/scripts/list-runtime-roots"
32export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ 33export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \
33 NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR 34 NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR \
35 NIX_ROOT_FINDER
34 36
35guix-daemon --version 37guix-daemon --version
36guix-build --version 38guix-build --version