database: Reset timestamps to one second after the Epoch.

Previously, store items registered in the database by this code (for
instance, store items retrieved by 'guix offload' and passed to
'restore-file-set') would have an mtime of 0 instead of 1.

This would cause problems for things like .go files: Guile would
consider them to be older than the corresponding .scm file, and
consequently it would ignore them and possibly use another (incorrect)
.go file.

Reported by Ricardo Wurmus.

* guix/store/database.scm (reset-timestamps): Pass 1, not 0, to
'utime'.
* tests/store-database.scm ("register-path"): Check the mtime of FILE
and REF.
master
Ludovic Courtès 2018-07-20 14:49:34 +02:00
parent 4f89a8eec6
commit e475211869
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 10 additions and 5 deletions

View File

@ -190,12 +190,14 @@ Every store item in REFERENCES must already be registered."
(define (reset-timestamps file) (define (reset-timestamps file)
"Reset the modification time on FILE and on all the files it contains, if "Reset the modification time on FILE and on all the files it contains, if
it's a directory. While at it, canonicalize file permissions." it's a directory. While at it, canonicalize file permissions."
;; Note: We're resetting to one second after the Epoch like 'guix-daemon'
;; has always done.
(let loop ((file file) (let loop ((file file)
(type (stat:type (lstat file)))) (type (stat:type (lstat file))))
(case type (case type
((directory) ((directory)
(chmod file #o555) (chmod file #o555)
(utime file 0 0 0 0) (utime file 1 1 0 0)
(let ((parent file)) (let ((parent file))
(for-each (match-lambda (for-each (match-lambda
(("." . _) #f) (("." . _) #f)
@ -209,10 +211,10 @@ it's a directory. While at it, canonicalize file permissions."
(type type)))))) (type type))))))
(scandir* parent)))) (scandir* parent))))
((symlink) ((symlink)
(utime file 0 0 0 0 AT_SYMLINK_NOFOLLOW)) (utime file 1 1 0 0 AT_SYMLINK_NOFOLLOW))
(else (else
(chmod file (if (executable-file? file) #o555 #o444)) (chmod file (if (executable-file? file) #o555 #o444))
(utime file 0 0 0 0))))) (utime file 1 1 0 0)))))
(define* (register-path path (define* (register-path path
#:key (references '()) deriver prefix #:key (references '()) deriver prefix

View File

@ -32,7 +32,8 @@
(test-begin "store-database") (test-begin "store-database")
(test-assert "register-path" (test-equal "register-path"
'(1 1)
(let ((file (string-append (%store-prefix) "/" (make-string 32 #\f) (let ((file (string-append (%store-prefix) "/" (make-string 32 #\f)
"-fake"))) "-fake")))
(when (valid-path? %store file) (when (valid-path? %store file)
@ -50,7 +51,9 @@
(and (valid-path? %store file) (and (valid-path? %store file)
(equal? (references %store file) (list ref)) (equal? (references %store file) (list ref))
(null? (valid-derivers %store file)) (null? (valid-derivers %store file))
(null? (referrers %store file)))))) (null? (referrers %store file))
(list (stat:mtime (lstat file))
(stat:mtime (lstat ref)))))))
(test-equal "new database" (test-equal "new database"
(list 1 2) (list 1 2)