download: Add X.org mirrors.
[jackhill/guix/guix.git] / guix / store.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
34fcbe3a 2;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
77d3cf08 3;;;
233e7676 4;;; This file is part of GNU Guix.
77d3cf08 5;;;
233e7676 6;;; GNU Guix is free software; you can redistribute it and/or modify it
77d3cf08
LC
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
233e7676 11;;; GNU Guix is distributed in the hope that it will be useful, but
77d3cf08
LC
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
233e7676 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
77d3cf08
LC
18
19(define-module (guix store)
82058eff 20 #:use-module (guix utils)
d8eea3d2 21 #:use-module (guix config)
77d3cf08
LC
22 #:use-module (rnrs bytevectors)
23 #:use-module (rnrs io ports)
24 #:use-module (srfi srfi-1)
25 #:use-module (srfi srfi-9)
26 #:use-module (srfi srfi-26)
e87088c9
LC
27 #:use-module (srfi srfi-34)
28 #:use-module (srfi srfi-35)
26bbbb95 29 #:use-module (srfi srfi-39)
77d3cf08
LC
30 #:use-module (ice-9 match)
31 #:use-module (ice-9 rdelim)
b37eb5ed 32 #:use-module (ice-9 ftw)
e3d74106 33 #:use-module (ice-9 regex)
9fd72fb1
LC
34 #:export (%daemon-socket-file
35
36 nix-server?
77d3cf08
LC
37 nix-server-major-version
38 nix-server-minor-version
39 nix-server-socket
40
e87088c9
LC
41 &nix-error nix-error?
42 &nix-protocol-error nix-protocol-error?
43 nix-protocol-error-message
44 nix-protocol-error-status
45
26bbbb95
LC
46 hash-algo
47
77d3cf08 48 open-connection
3abaf0c4 49 close-connection
77d3cf08 50 set-build-options
31ef99a8 51 valid-path?
82058eff 52 query-path-hash
77d3cf08
LC
53 add-text-to-store
54 add-to-store
26bbbb95 55 build-derivations
3259877d 56 add-temp-root
34811f02 57 add-indirect-root
26bbbb95 58
0f3d2504
LC
59 substitutable?
60 substitutable-path
61 substitutable-deriver
62 substitutable-references
63 substitutable-download-size
64 substitutable-nar-size
65 has-substitutes?
66 substitutable-paths
67 substitutable-path-info
68
3259877d
LC
69 live-paths
70 dead-paths
71 collect-garbage
72 delete-paths
73
dcee50c1
LC
74 current-build-output-port
75
26bbbb95
LC
76 %store-prefix
77 store-path?
e3d74106
LC
78 derivation-path?
79 store-path-package-name))
77d3cf08 80
63193ebf 81(define %protocol-version #x10c)
77d3cf08
LC
82
83(define %worker-magic-1 #x6e697863)
84(define %worker-magic-2 #x6478696f)
85
86(define (protocol-major magic)
87 (logand magic #xff00))
88(define (protocol-minor magic)
89 (logand magic #x00ff))
90
91(define-syntax define-enumerate-type
92 (syntax-rules ()
93 ((_ name->int (name id) ...)
94 (define-syntax name->int
95 (syntax-rules (name ...)
96 ((_ name) id) ...)))))
97
98(define-enumerate-type operation-id
99 ;; operation numbers from worker-protocol.hh
100 (quit 0)
101 (valid-path? 1)
102 (has-substitutes? 3)
103 (query-path-hash 4)
104 (query-references 5)
105 (query-referrers 6)
106 (add-to-store 7)
107 (add-text-to-store 8)
108 (build-derivations 9)
109 (ensure-path 10)
110 (add-temp-root 11)
111 (add-indirect-root 12)
112 (sync-with-gc 13)
113 (find-roots 14)
114 (export-path 16)
115 (query-deriver 18)
116 (set-options 19)
117 (collect-garbage 20)
63193ebf 118 ;;(query-substitutable-path-info 21) ; obsolete as of #x10c
77d3cf08 119 (query-derivation-outputs 22)
63193ebf 120 (query-all-valid-paths 23)
77d3cf08
LC
121 (query-failed-paths 24)
122 (clear-failed-paths 25)
123 (query-path-info 26)
124 (import-paths 27)
63193ebf
LC
125 (query-derivation-output-names 28)
126 (query-path-from-hash-part 29)
127 (query-substitutable-path-infos 30)
128 (query-valid-paths 31)
129 (query-substitutable-paths 32))
77d3cf08
LC
130
131(define-enumerate-type hash-algo
132 ;; hash.hh
133 (md5 1)
134 (sha1 2)
135 (sha256 3))
136
3259877d
LC
137(define-enumerate-type gc-action
138 ;; store-api.hh
139 (return-live 0)
140 (return-dead 1)
141 (delete-dead 2)
142 (delete-specific 3))
143
77d3cf08 144(define %default-socket-path
d8eea3d2
LC
145 (string-append (or (getenv "NIX_STATE_DIR") %state-directory)
146 "/daemon-socket/socket"))
77d3cf08 147
9fd72fb1
LC
148(define %daemon-socket-file
149 ;; File name of the socket the daemon listens too.
150 (make-parameter (or (getenv "GUIX_DAEMON_SOCKET")
151 %default-socket-path)))
152
153
77d3cf08
LC
154\f
155;; serialize.cc
156
157(define (write-int n p)
158 (let ((b (make-bytevector 8 0)))
159 (bytevector-u32-set! b 0 n (endianness little))
160 (put-bytevector p b)))
161
162(define (read-int p)
163 (let ((b (get-bytevector-n p 8)))
164 (bytevector-u32-ref b 0 (endianness little))))
165
166(define (write-long-long n p)
167 (let ((b (make-bytevector 8 0)))
168 (bytevector-u64-set! b 0 n (endianness little))
169 (put-bytevector p b)))
170
3259877d
LC
171(define (read-long-long p)
172 (let ((b (get-bytevector-n p 8)))
173 (bytevector-u64-ref b 0 (endianness little))))
174
77d3cf08
LC
175(define write-padding
176 (let ((zero (make-bytevector 8 0)))
177 (lambda (n p)
178 (let ((m (modulo n 8)))
179 (or (zero? m)
180 (put-bytevector p zero 0 (- 8 m)))))))
181
182(define (write-string s p)
82c38fe6
LC
183 (let* ((s (string->utf8 s))
184 (l (bytevector-length s))
185 (m (modulo l 8))
186 (b (make-bytevector (+ 8 l (if (zero? m) 0 (- 8 m))))))
238e43b9 187 (bytevector-u32-set! b 0 l (endianness little))
82c38fe6
LC
188 (bytevector-copy! s 0 b 8 l)
189 (put-bytevector p b)))
77d3cf08
LC
190
191(define (read-string p)
192 (let* ((len (read-int p))
193 (m (modulo len 8))
194 (bv (get-bytevector-n p len))
195 (str (utf8->string bv)))
196 (or (zero? m)
197 (get-bytevector-n p (- 8 m)))
198 str))
199
bbdb3ffa
LC
200(define (read-latin1-string p)
201 (let* ((len (read-int p))
202 (m (modulo len 8))
203 (str (get-string-n p len)))
204 (or (zero? m)
205 (get-bytevector-n p (- 8 m)))
206 str))
207
77d3cf08
LC
208(define (write-string-list l p)
209 (write-int (length l) p)
210 (for-each (cut write-string <> p) l))
211
3259877d
LC
212(define (read-string-list p)
213 (let ((len (read-int p)))
214 (unfold (cut >= <> len)
215 (lambda (i)
216 (read-string p))
217 1+
218 0)))
219
220(define (write-store-path f p)
221 (write-string f p)) ; TODO: assert path
222
77d3cf08
LC
223(define (read-store-path p)
224 (read-string p)) ; TODO: assert path
225
3259877d
LC
226(define write-store-path-list write-string-list)
227(define read-store-path-list read-string-list)
228
77d3cf08
LC
229(define (write-contents file p)
230 "Write the contents of FILE to output port P."
231 (define (dump in size)
232 (define buf-size 65536)
233 (define buf (make-bytevector buf-size))
234
235 (let loop ((left size))
236 (if (<= left 0)
237 0
238 (let ((read (get-bytevector-n! in buf 0 buf-size)))
239 (if (eof-object? read)
240 left
241 (begin
242 (put-bytevector p buf 0 read)
243 (loop (- left read))))))))
244
245 (let ((size (stat:size (lstat file))))
246 (write-string "contents" p)
247 (write-long-long size p)
248 (call-with-input-file file
249 (lambda (p)
250 (dump p size)))
251 (write-padding size p)))
252
253(define (write-file f p)
254 (define %archive-version-1 "nix-archive-1")
255
b37eb5ed
LC
256 (write-string %archive-version-1 p)
257
258 (let dump ((f f))
259 (let ((s (lstat f)))
260 (write-string "(" p)
261 (case (stat:type s)
262 ((regular)
263 (write-string "type" p)
264 (write-string "regular" p)
265 (if (not (zero? (logand (stat:mode s) #o100)))
266 (begin
267 (write-string "executable" p)
268 (write-string "" p)))
269 (write-contents f p))
270 ((directory)
271 (write-string "type" p)
272 (write-string "directory" p)
273 (let ((entries (remove (cut member <> '("." ".."))
274 (scandir f))))
275 (for-each (lambda (e)
276 (let ((f (string-append f "/" e)))
277 (write-string "entry" p)
278 (write-string "(" p)
279 (write-string "name" p)
280 (write-string e p)
281 (write-string "node" p)
282 (dump f)
283 (write-string ")" p)))
284 entries)))
285 (else
286 (error "ENOSYS")))
287 (write-string ")" p))))
77d3cf08 288
0f3d2504
LC
289;; Information about a substitutable store path.
290(define-record-type <substitutable>
291 (substitutable path deriver refs dl-size nar-size)
292 substitutable?
293 (path substitutable-path)
294 (deriver substitutable-deriver)
295 (refs substitutable-references)
296 (dl-size substitutable-download-size)
297 (nar-size substitutable-nar-size))
298
299(define (read-substitutable-path-list p)
300 (let loop ((len (read-int p))
301 (result '()))
302 (if (zero? len)
303 (reverse result)
304 (let ((path (read-store-path p))
305 (deriver (read-store-path p))
306 (refs (read-store-path-list p))
307 (dl-size (read-long-long p))
308 (nar-size (read-long-long p)))
309 (loop (- len 1)
310 (cons (substitutable path deriver refs dl-size nar-size)
311 result))))))
312
77d3cf08 313(define-syntax write-arg
3259877d
LC
314 (syntax-rules (integer boolean file string string-list
315 store-path store-path-list base16)
77d3cf08
LC
316 ((_ integer arg p)
317 (write-int arg p))
318 ((_ boolean arg p)
319 (write-int (if arg 1 0) p))
320 ((_ file arg p)
321 (write-file arg p))
322 ((_ string arg p)
323 (write-string arg p))
324 ((_ string-list arg p)
82058eff 325 (write-string-list arg p))
3259877d
LC
326 ((_ store-path arg p)
327 (write-store-path arg p))
328 ((_ store-path-list arg p)
329 (write-store-path-list arg p))
82058eff
LC
330 ((_ base16 arg p)
331 (write-string (bytevector->base16-string arg) p))))
77d3cf08
LC
332
333(define-syntax read-arg
0f3d2504
LC
334 (syntax-rules (integer boolean string store-path store-path-list
335 substitutable-path-list base16)
77d3cf08
LC
336 ((_ integer p)
337 (read-int p))
338 ((_ boolean p)
339 (not (zero? (read-int p))))
340 ((_ string p)
341 (read-string p))
342 ((_ store-path p)
82058eff 343 (read-store-path p))
3259877d
LC
344 ((_ store-path-list p)
345 (read-store-path-list p))
0f3d2504
LC
346 ((_ substitutable-path-list p)
347 (read-substitutable-path-list p))
348 ((_ base16 p)
82058eff 349 (base16-string->bytevector (read-string p)))))
77d3cf08
LC
350
351\f
352;; remote-store.cc
353
354(define-record-type <nix-server>
2c3f47ee 355 (%make-nix-server socket major minor
bdcf35a6 356 ats-cache atts-cache)
77d3cf08
LC
357 nix-server?
358 (socket nix-server-socket)
359 (major nix-server-major-version)
2c3f47ee
LC
360 (minor nix-server-minor-version)
361
362 ;; Caches. We keep them per-connection, because store paths build
363 ;; during the session are temporary GC roots kept for the duration of
364 ;; the session.
bdcf35a6
LC
365 (ats-cache nix-server-add-to-store-cache)
366 (atts-cache nix-server-add-text-to-store-cache))
77d3cf08 367
e87088c9
LC
368(define-condition-type &nix-error &error
369 nix-error?)
370
371(define-condition-type &nix-protocol-error &nix-error
372 nix-protocol-error?
373 (message nix-protocol-error-message)
374 (status nix-protocol-error-status))
375
9fd72fb1 376(define* (open-connection #:optional (file (%daemon-socket-file))
e36a7172 377 #:key (reserve-space? #t))
e531ac2a
LC
378 "Connect to the daemon over the Unix-domain socket at FILE. When
379RESERVE-SPACE? is true, instruct it to reserve a little bit of extra
380space on the file system so that the garbage collector can still
381operate, should the disk become full. Return a server object."
77d3cf08
LC
382 (let ((s (with-fluids ((%default-port-encoding #f))
383 ;; This trick allows use of the `scm_c_read' optimization.
384 (socket PF_UNIX SOCK_STREAM 0)))
385 (a (make-socket-address PF_UNIX file)))
df1fab58
LC
386
387 ;; Enlarge the receive buffer.
388 (setsockopt s SOL_SOCKET SO_RCVBUF (* 12 1024))
389
77d3cf08
LC
390 (connect s a)
391 (write-int %worker-magic-1 s)
392 (let ((r (read-int s)))
393 (and (eqv? r %worker-magic-2)
394 (let ((v (read-int s)))
395 (and (eqv? (protocol-major %protocol-version)
396 (protocol-major v))
397 (begin
398 (write-int %protocol-version s)
e36a7172
LC
399 (if (>= (protocol-minor v) 11)
400 (write-int (if reserve-space? 1 0) s))
77d3cf08
LC
401 (let ((s (%make-nix-server s
402 (protocol-major v)
2c3f47ee 403 (protocol-minor v)
fce2394e
LC
404 (make-hash-table 100)
405 (make-hash-table 100))))
34fcbe3a
LC
406 (let loop ((done? (process-stderr s)))
407 (or done? (process-stderr s)))
77d3cf08
LC
408 s))))))))
409
3abaf0c4
LC
410(define (close-connection server)
411 "Close the connection to SERVER."
412 (close (nix-server-socket server)))
413
dcee50c1
LC
414(define current-build-output-port
415 ;; The port where build output is sent.
416 (make-parameter (current-error-port)))
417
77d3cf08 418(define (process-stderr server)
dcee50c1
LC
419 "Read standard output and standard error from SERVER, writing it to
420CURRENT-BUILD-OUTPUT-PORT. Return #t when SERVER is done sending data, and
421#f otherwise; in the latter case, the caller should call `process-stderr'
bbdb3ffa
LC
422again until #t is returned or an error is raised.
423
424Since the build process's output cannot be assumed to be UTF-8, we
425conservatively consider it to be Latin-1, thereby avoiding possible
426encoding conversion errors."
77d3cf08
LC
427 (define p
428 (nix-server-socket server))
429
430 ;; magic cookies from worker-protocol.hh
431 (define %stderr-next #x6f6c6d67)
432 (define %stderr-read #x64617461) ; data needed from source
433 (define %stderr-write #x64617416) ; data for sink
434 (define %stderr-last #x616c7473)
435 (define %stderr-error #x63787470)
436
437 (let ((k (read-int p)))
438 (cond ((= k %stderr-write)
bbdb3ffa 439 (read-latin1-string p)
dcee50c1 440 #f)
77d3cf08
LC
441 ((= k %stderr-read)
442 (let ((len (read-int p)))
bbdb3ffa 443 (read-latin1-string p) ; FIXME: what to do?
dcee50c1 444 #f))
77d3cf08 445 ((= k %stderr-next)
bbdb3ffa 446 (let ((s (read-latin1-string p)))
dcee50c1
LC
447 (display s (current-build-output-port))
448 #f))
77d3cf08 449 ((= k %stderr-error)
bbdb3ffa 450 (let ((error (read-latin1-string p))
77d3cf08
LC
451 (status (if (>= (nix-server-minor-version server) 8)
452 (read-int p)
453 1)))
e87088c9
LC
454 (raise (condition (&nix-protocol-error
455 (message error)
456 (status status))))))
77d3cf08 457 ((= k %stderr-last)
dcee50c1 458 ;; The daemon is done (see `stopWork' in `nix-worker.cc'.)
77d3cf08
LC
459 #t)
460 (else
e87088c9
LC
461 (raise (condition (&nix-protocol-error
462 (message "invalid error code")
463 (status k))))))))
77d3cf08
LC
464
465(define* (set-build-options server
466 #:key keep-failed? keep-going? try-fallback?
467 (verbosity 0)
468 (max-build-jobs (current-processor-count))
469 (max-silent-time 3600)
470 (use-build-hook? #t)
471 (build-verbosity 0)
472 (log-type 0)
e036c31b
LC
473 (print-build-trace #t)
474 (build-cores 1)
63193ebf
LC
475 (use-substitutes? #t)
476 (binary-caches '())) ; client "untrusted" cache URLs
77d3cf08
LC
477 ;; Must be called after `open-connection'.
478
479 (define socket
480 (nix-server-socket server))
481
482 (let-syntax ((send (syntax-rules ()
e036c31b
LC
483 ((_ (type option) ...)
484 (begin
485 (write-arg type option socket)
486 ...)))))
487 (write-int (operation-id set-options) socket)
488 (send (boolean keep-failed?) (boolean keep-going?)
489 (boolean try-fallback?) (integer verbosity)
490 (integer max-build-jobs) (integer max-silent-time))
77d3cf08 491 (if (>= (nix-server-minor-version server) 2)
e036c31b 492 (send (boolean use-build-hook?)))
77d3cf08 493 (if (>= (nix-server-minor-version server) 4)
e036c31b
LC
494 (send (integer build-verbosity) (integer log-type)
495 (boolean print-build-trace)))
496 (if (>= (nix-server-minor-version server) 6)
497 (send (integer build-cores)))
498 (if (>= (nix-server-minor-version server) 10)
499 (send (boolean use-substitutes?)))
63193ebf
LC
500 (if (>= (nix-server-minor-version server) 12)
501 (send (string-list (fold-right (lambda (pair result)
502 (match pair
503 ((h . t)
504 (cons* h t result))))
505 '()
506 binary-caches))))
dcee50c1
LC
507 (let loop ((done? (process-stderr server)))
508 (or done? (process-stderr server)))))
77d3cf08 509
fd060fd3 510(define-syntax operation
77d3cf08 511 (syntax-rules ()
fd060fd3 512 "Define a client-side RPC stub for the given operation."
3259877d 513 ((_ (name (type arg) ...) docstring return ...)
fd060fd3 514 (lambda (server arg ...)
77d3cf08
LC
515 docstring
516 (let ((s (nix-server-socket server)))
517 (write-int (operation-id name) s)
518 (write-arg type arg s)
519 ...
dcee50c1
LC
520 ;; Loop until the server is done sending error output.
521 (let loop ((done? (process-stderr server)))
522 (or done? (loop (process-stderr server))))
3259877d 523 (values (read-arg return s) ...))))))
77d3cf08 524
fd060fd3
LC
525(define-syntax-rule (define-operation (name args ...)
526 docstring return ...)
527 (define name
528 (operation (name args ...) docstring return ...)))
529
31ef99a8
LC
530(define-operation (valid-path? (string path))
531 "Return #t when PATH is a valid store path."
532 boolean)
533
63193ebf 534(define-operation (query-path-hash (store-path path))
82058eff
LC
535 "Return the SHA256 hash of PATH as a bytevector."
536 base16)
537
fd060fd3
LC
538(define add-text-to-store
539 ;; A memoizing version of `add-to-store', to avoid repeated RPCs with
540 ;; the very same arguments during a given session.
541 (let ((add-text-to-store
542 (operation (add-text-to-store (string name) (string text)
543 (string-list references))
544 #f
545 store-path)))
bdcf35a6
LC
546 (lambda (server name text references)
547 "Add TEXT under file NAME in the store, and return its store path.
548REFERENCES is the list of store paths referred to by the resulting store
549path."
fce2394e 550 (let ((args `(,text ,name ,references))
bdcf35a6
LC
551 (cache (nix-server-add-text-to-store-cache server)))
552 (or (hash-ref cache args)
fd060fd3 553 (let ((path (add-text-to-store server name text references)))
bdcf35a6
LC
554 (hash-set! cache args path)
555 path))))))
556
fd060fd3 557(define add-to-store
a7b6ffee
LC
558 ;; A memoizing version of `add-to-store'. This is important because
559 ;; `add-to-store' leads to huge data transfers to the server, and
560 ;; because it's often called many times with the very same argument.
fd060fd3
LC
561 (let ((add-to-store (operation (add-to-store (string basename)
562 (boolean fixed?) ; obsolete, must be #t
563 (boolean recursive?)
564 (string hash-algo)
565 (file file-name))
566 #f
567 store-path)))
a9ebd9ef
LC
568 (lambda (server basename recursive? hash-algo file-name)
569 "Add the contents of FILE-NAME under BASENAME to the store. When
570RECURSIVE? is true and FILE-NAME designates a directory, the contents of
571FILE-NAME are added recursively; if FILE-NAME designates a flat file and
572RECURSIVE? is true, its contents are added, and its permission bits are
573kept. HASH-ALGO must be a string such as \"sha256\"."
2c3f47ee 574 (let* ((st (stat file-name #f))
fce2394e 575 (args `(,st ,basename ,recursive? ,hash-algo))
2c3f47ee 576 (cache (nix-server-add-to-store-cache server)))
a7b6ffee 577 (or (and st (hash-ref cache args))
a9ebd9ef 578 (let ((path (add-to-store server basename #t recursive?
a7b6ffee
LC
579 hash-algo file-name)))
580 (hash-set! cache args path)
581 path))))))
582
77d3cf08 583(define-operation (build-derivations (string-list derivations))
dcee50c1
LC
584 "Build DERIVATIONS, and return when the worker is done building them.
585Return #t on success."
77d3cf08 586 boolean)
26bbbb95 587
d3648e01
LC
588(define-operation (add-temp-root (store-path path))
589 "Make PATH a temporary root for the duration of the current session.
590Return #t."
591 boolean)
592
34811f02
LC
593(define-operation (add-indirect-root (string file-name))
594 "Make FILE-NAME an indirect root for the garbage collector; FILE-NAME
595can be anywhere on the file system, but it must be an absolute file
596name--it is the caller's responsibility to ensure that it is an absolute
597file name. Return #t on success."
598 boolean)
599
0f3d2504
LC
600(define-operation (has-substitutes? (store-path path))
601 "Return #t if binary substitutes are available for PATH, and #f otherwise."
602 boolean)
603
604(define substitutable-paths
605 (operation (query-substitutable-paths (store-path-list paths))
606 "Return the subset of PATHS that is substitutable."
607 store-path-list))
608
609(define substitutable-path-info
610 (operation (query-substitutable-paths (store-path-list paths))
611 "Return information about the subset of PATHS that is
612substitutable. For each substitutable path, a `substitutable?' object is
613returned."
614 substitutable-path-list))
615
3259877d
LC
616(define (run-gc server action to-delete min-freed)
617 "Perform the garbage-collector operation ACTION, one of the
618`gc-action' values. When ACTION is `delete-specific', the TO-DELETE is
619the list of store paths to delete. IGNORE-LIVENESS? should always be
620#f. MIN-FREED is the minimum amount of disk space to be freed, in
621bytes, before the GC can stop. Return the list of store paths delete,
622and the number of bytes freed."
623 (let ((s (nix-server-socket server)))
624 (write-int (operation-id collect-garbage) s)
625 (write-int action s)
626 (write-store-path-list to-delete s)
627 (write-arg boolean #f s) ; ignore-liveness?
628 (write-long-long min-freed s)
629 (write-int 0 s) ; obsolete
630 (when (>= (nix-server-minor-version server) 5)
631 ;; Obsolete `use-atime' and `max-atime' parameters.
632 (write-int 0 s)
633 (write-int 0 s))
634
635 ;; Loop until the server is done sending error output.
636 (let loop ((done? (process-stderr server)))
637 (or done? (loop (process-stderr server))))
638
639 (let ((paths (read-store-path-list s))
640 (freed (read-long-long s))
641 (obsolete (read-long-long s)))
642 (values paths freed))))
643
644(define-syntax-rule (%long-long-max)
645 ;; Maximum unsigned 64-bit integer.
646 (- (expt 2 64) 1))
647
648(define (live-paths server)
649 "Return the list of live store paths---i.e., store paths still
650referenced, and thus not subject to being garbage-collected."
651 (run-gc server (gc-action return-live) '() (%long-long-max)))
652
653(define (dead-paths server)
654 "Return the list of dead store paths---i.e., store paths no longer
655referenced, and thus subject to being garbage-collected."
656 (run-gc server (gc-action return-dead) '() (%long-long-max)))
657
658(define* (collect-garbage server #:optional (min-freed (%long-long-max)))
659 "Collect garbage from the store at SERVER. If MIN-FREED is non-zero,
660then collect at least MIN-FREED bytes. Return the paths that were
661collected, and the number of bytes freed."
662 (run-gc server (gc-action delete-dead) '() min-freed))
663
664(define* (delete-paths server paths #:optional (min-freed (%long-long-max)))
665 "Delete PATHS from the store at SERVER, if they are no longer
666referenced. If MIN-FREED is non-zero, then stop after at least
667MIN-FREED bytes have been collected. Return the paths that were
668collected, and the number of bytes freed."
669 (run-gc server (gc-action delete-specific) paths min-freed))
670
26bbbb95
LC
671\f
672;;;
673;;; Store paths.
674;;;
675
676(define %store-prefix
677 ;; Absolute path to the Nix store.
cd3ded43 678 (make-parameter (or (and=> (getenv "NIX_STORE_DIR") canonicalize-path)
d8eea3d2 679 %store-directory)))
26bbbb95 680
f39bd08a
LC
681(define (store-path? path)
682 "Return #t if PATH is a store path."
683 ;; This is a lightweight check, compared to using a regexp, but this has to
684 ;; be fast as it's called often in `derivation', for instance.
685 ;; `isStorePath' in Nix does something similar.
686 (string-prefix? (%store-prefix) path))
26bbbb95
LC
687
688(define (derivation-path? path)
689 "Return #t if PATH is a derivation path."
690 (and (store-path? path) (string-suffix? ".drv" path)))
e3d74106
LC
691
692(define (store-path-package-name path)
693 "Return the package name part of PATH, a file name in the store."
694 (define store-path-rx
695 (make-regexp (string-append "^.*" (regexp-quote (%store-prefix))
696 "/[^-]+-(.+)$")))
697
698 (and=> (regexp-exec store-path-rx path)
699 (cut match:substring <> 1)))