summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2016-04-25 22:19:33 +0200
committerLudovic Courtès <ludo@gnu.org>2016-04-25 23:27:09 +0200
commit0054e47036b13d46f0f026bbc04d19770c2ecbad (patch)
treeb76d6e274644cb3209ad4091691fd6e71d20e52d
parenta1f708787d08e567da6118bacc481219884296ca (diff)
guix gc: Add '--free-space'.
* guix/scripts/gc.scm (show-help, %options): Add '--free-space'. (guix-gc)[ensure-free-space]: New procedure. Handle '--free-space'.
-rw-r--r--doc/guix.texi9
-rw-r--r--guix/scripts/gc.scm33
2 files changed, 37 insertions, 5 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index ab07d1066e1..6d64772262a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -1974,6 +1974,15 @@ suffix, such as @code{MiB} for mebibytes and @code{GB} for gigabytes
1974 1974
1975When @var{min} is omitted, collect all the garbage. 1975When @var{min} is omitted, collect all the garbage.
1976 1976
1977@item --free-space=@var{free}
1978@itemx -F @var{free}
1979Collect garbage until @var{free} space is available under
1980@file{/gnu/store}, if possible; @var{free} denotes storage space, such
1981as @code{500MiB}, as described above.
1982
1983When @var{free} or more is already available in @file{/gnu/store}, do
1984nothing and exit immediately.
1985
1977@item --delete 1986@item --delete
1978@itemx -d 1987@itemx -d
1979Attempt to delete all the store files and directories specified as 1988Attempt to delete all the store files and directories specified as
diff --git a/guix/scripts/gc.scm b/guix/scripts/gc.scm
index fe1bb93f7f0..4ec9ff9dcab 100644
--- a/guix/scripts/gc.scm
+++ b/guix/scripts/gc.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2015 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012, 2013, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3;;; 3;;;
4;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
5;;; 5;;;
@@ -20,6 +20,7 @@
20 #:use-module (guix ui) 20 #:use-module (guix ui)
21 #:use-module (guix scripts) 21 #:use-module (guix scripts)
22 #:use-module (guix store) 22 #:use-module (guix store)
23 #:autoload (guix build syscalls) (statfs)
23 #:use-module (ice-9 match) 24 #:use-module (ice-9 match)
24 #:use-module (ice-9 regex) 25 #:use-module (ice-9 regex)
25 #:use-module (srfi srfi-1) 26 #:use-module (srfi srfi-1)
@@ -43,6 +44,8 @@ Invoke the garbage collector.\n"))
43 -C, --collect-garbage[=MIN] 44 -C, --collect-garbage[=MIN]
44 collect at least MIN bytes of garbage")) 45 collect at least MIN bytes of garbage"))
45 (display (_ " 46 (display (_ "
47 -F, --free-space=FREE attempt to reach FREE available space in the store"))
48 (display (_ "
46 -d, --delete attempt to delete PATHS")) 49 -d, --delete attempt to delete PATHS"))
47 (display (_ " 50 (display (_ "
48 --optimize optimize the store by deduplicating identical files")) 51 --optimize optimize the store by deduplicating identical files"))
@@ -96,6 +99,9 @@ Invoke the garbage collector.\n"))
96 (leave (_ "invalid amount of storage: ~a~%") 99 (leave (_ "invalid amount of storage: ~a~%")
97 arg)))) 100 arg))))
98 (#f result))))) 101 (#f result)))))
102 (option '(#\F "free-space") #t #f
103 (lambda (opt name arg result)
104 (alist-cons 'free-space (size->number arg) result)))
99 (option '(#\d "delete") #f #f 105 (option '(#\d "delete") #f #f
100 (lambda (opt name arg result) 106 (lambda (opt name arg result)
101 (alist-cons 'action 'delete 107 (alist-cons 'action 'delete
@@ -175,6 +181,18 @@ Invoke the garbage collector.\n"))
175 (cut match:substring <> 1))) 181 (cut match:substring <> 1)))
176 file)) 182 file))
177 183
184 (define (ensure-free-space store space)
185 ;; Attempt to have at least SPACE bytes available in STORE.
186 (let* ((fs (statfs (%store-prefix)))
187 (free (* (file-system-block-size fs)
188 (file-system-blocks-available fs))))
189 (if (> free space)
190 (info (_ "already ~h bytes available on ~a, nothing to do~%")
191 free (%store-prefix))
192 (let ((to-free (- space free)))
193 (info (_ "freeing ~h bytes~%") to-free)
194 (collect-garbage store to-free)))))
195
178 (with-error-handling 196 (with-error-handling
179 (let* ((opts (parse-options)) 197 (let* ((opts (parse-options))
180 (store (open-connection)) 198 (store (open-connection))
@@ -197,10 +215,15 @@ Invoke the garbage collector.\n"))
197 (case (assoc-ref opts 'action) 215 (case (assoc-ref opts 'action)
198 ((collect-garbage) 216 ((collect-garbage)
199 (assert-no-extra-arguments) 217 (assert-no-extra-arguments)
200 (let ((min-freed (assoc-ref opts 'min-freed))) 218 (let ((min-freed (assoc-ref opts 'min-freed))
201 (if min-freed 219 (free-space (assoc-ref opts 'free-space)))
202 (collect-garbage store min-freed) 220 (cond
203 (collect-garbage store)))) 221 (free-space
222 (ensure-free-space store free-space))
223 (min-freed
224 (collect-garbage store min-freed))
225 (else
226 (collect-garbage store)))))
204 ((delete) 227 ((delete)
205 (delete-paths store (map direct-store-path paths))) 228 (delete-paths store (map direct-store-path paths)))
206 ((list-references) 229 ((list-references)