summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-11-04 20:55:48 +0100
committerLudovic Courtès <ludo@gnu.org>2014-11-04 21:13:28 +0100
commit000c59b6719250ee94a597418765c2f7f0ad3969 (patch)
tree473f7840522e966cc473d1dd397fb8c574df137f
parent8de16914751966ba45789d619cac5246cbf53cac (diff)
downloadguix-000c59b6719250ee94a597418765c2f7f0ad3969.tar.gz
store: Invalidate caches once GC has run.
* guix/store.scm (run-gc): Add calls to 'hash-clear!'.
* tests/store.scm ("add-text-to-store vs. delete-paths",
  "add-to-store vs. delete-paths"): New tests.
-rw-r--r--guix/store.scm7
-rw-r--r--tests/store.scm25
2 files changed, 32 insertions, 0 deletions
diff --git a/guix/store.scm b/guix/store.scm
index 452a2f1268..bc4c641583 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -728,6 +728,13 @@ and the number of bytes freed."
     (let ((paths    (read-store-path-list s))
           (freed    (read-long-long s))
           (obsolete (read-long-long s)))
+      (unless (null? paths)
+        ;; To be on the safe side, completely invalidate both caches.
+        ;; Otherwise we could end up returning store paths that are no longer
+        ;; valid.
+        (hash-clear! (nix-server-add-to-store-cache server))
+        (hash-clear! (nix-server-add-text-to-store-cache server)))
+
      (values paths freed))))
 
 (define-syntax-rule (%long-long-max)
diff --git a/tests/store.scm b/tests/store.scm
index 88a8877d80..cb5370d5cc 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -158,6 +158,31 @@
            (> freed 0)
            (not (file-exists? p))))))
 
+(test-assert "add-text-to-store vs. delete-paths"
+  ;; Before, 'add-text-to-store' would return PATH2 without noticing that it
+  ;; is no longer valid.
+  (with-store store
+    (let* ((text    (random-text))
+           (path    (add-text-to-store store "delete-me" text))
+           (deleted (delete-paths store (list path)))
+           (path2   (add-text-to-store store "delete-me" text)))
+      (and (string=? path path2)
+           (equal? deleted (list path))
+           (valid-path? store path)
+           (file-exists? path)))))
+
+(test-assert "add-to-store vs. delete-paths"
+  ;; Same as above.
+  (with-store store
+    (let* ((file    (search-path %load-path "guix.scm"))
+           (path    (add-to-store store "delete-me" #t "sha256" file))
+           (deleted (delete-paths store (list path)))
+           (path2   (add-to-store store "delete-me" #t "sha256" file)))
+      (and (string=? path path2)
+           (equal? deleted (list path))
+           (valid-path? store path)
+           (file-exists? path)))))
+
 (test-assert "references"
   (let* ((t1 (add-text-to-store %store "random1"
                                 (random-text)))