diff options
author | Ludovic Courtès <ludo@gnu.org> | 2018-12-14 11:10:25 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2018-12-14 12:07:24 +0100 |
commit | adb158b7396cbdcda347fa298978408e531a03fd (patch) | |
tree | fd6877e72a20840cd3962f80a89618bd08fcf04b /tests/store-deduplication.scm | |
parent | ea49fbdea3bbb9b55951b7bff9d9cf768fd23161 (diff) | |
download | patches-adb158b7396cbdcda347fa298978408e531a03fd.tar patches-adb158b7396cbdcda347fa298978408e531a03fd.tar.gz |
deduplication: Gracefully handle ENOSPC raised by 'link' calls.
Reported by Andreas Enge <andreas@enge.fr>
in <https://bugs.gnu.org/33676>.
* guix/store/deduplication.scm (replace-with-link): Catch ENOSPC around
'get-temp-link'. Do nothing when 'get-temp-link' throws ENOSPC. Move
code to restore PARENT's permissions outside of 'catch'.
* tests/store-deduplication.scm ("deduplicate, ENOSPC"): New test.
Diffstat (limited to 'tests/store-deduplication.scm')
-rw-r--r-- | tests/store-deduplication.scm | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/tests/store-deduplication.scm b/tests/store-deduplication.scm index e438aa84c6..e2870a363d 100644 --- a/tests/store-deduplication.scm +++ b/tests/store-deduplication.scm @@ -48,7 +48,7 @@ (put-bytevector port data)))) identical) ;; Make the parent of IDENTICAL read-only. This should not prevent - ;; deduplication for inserting its hard link. + ;; deduplication from inserting its hard link. (chmod (dirname (second identical)) #o544) (call-with-output-file unique @@ -64,4 +64,46 @@ (stat:nlink (stat unique)) (map (compose stat:nlink stat) identical)))))) +(test-equal "deduplicate, ENOSPC" + (cons* #f ;inode comparison + (append (make-list 3 4) + (make-list 7 1))) ;'nlink' values + + ;; In this scenario the first 3 files are properly deduplicated and then we + ;; simulate a full '.links' directory where link(2) gets ENOSPC, thereby + ;; preventing deduplication of the subsequent files. + (call-with-temporary-directory + (lambda (store) + (let ((true-link link) + (links 0) + (data1 (string->utf8 "Hello, world!")) + (data2 (string->utf8 "Hi, world!")) + (identical (map (lambda (n) + (string-append store "/" (number->string n) + "/a/b/c")) + (iota 10))) + (populate (lambda (data) + (lambda (file) + (mkdir-p (dirname file)) + (call-with-output-file file + (lambda (port) + (put-bytevector port data))))))) + (for-each (populate data1) (take identical 5)) + (for-each (populate data2) (drop identical 5)) + (dynamic-wind + (lambda () + (set! link (lambda (old new) + (set! links (+ links 1)) + (if (<= links 3) + (true-link old new) + (throw 'system-error "link" "~A" '("Whaaat?!") + (list ENOSPC)))))) + (lambda () + (deduplicate store (nar-sha256 store) #:store store)) + (lambda () + (set! link true-link))) + + (cons (apply = (map (compose stat:ino stat) identical)) + (map (compose stat:nlink stat) identical)))))) + (test-end "store-deduplication") |