summaryrefslogtreecommitdiff
path: root/gnu/system
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-09-07 09:50:26 +0200
committerLudovic Courtès <ludo@gnu.org>2018-09-07 11:40:05 +0200
commit1540075c790dfaeff52c93392f2fc63b9e23b77e (patch)
treedc9c011af6bd8a6cdde92f84e0eb5ed9da957c6e /gnu/system
parent0012e0dd5642fbbb8ee40a68f65afc184952fc98 (diff)
vm: Make UUID computation really deterministic.
Fixes <https://bugs.gnu.org/32652>. * gnu/system/vm.scm (operating-system-uuid)[service-name, file-system-digest]: New procedures. Map these over services and file systems and hash the result. * tests/guix-system.sh: Add test.
Diffstat (limited to 'gnu/system')
-rw-r--r--gnu/system/vm.scm33
1 files changed, 29 insertions, 4 deletions
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 3898872a466..91e117b9f3d 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -529,17 +529,42 @@ should set REGISTER-CLOSURES? to #f."
529(define* (operating-system-uuid os #:optional (type 'dce)) 529(define* (operating-system-uuid os #:optional (type 'dce))
530 "Compute UUID object with a deterministic \"UUID\" for OS, of the given 530 "Compute UUID object with a deterministic \"UUID\" for OS, of the given
531TYPE (one of 'iso9660 or 'dce). Return a UUID object." 531TYPE (one of 'iso9660 or 'dce). Return a UUID object."
532 ;; Note: For this to be deterministic, we must not hash things that contains
533 ;; (directly or indirectly) procedures, for example. That rules out
534 ;; anything that contains gexps, thunk or delayed record fields, etc.
535
536 (define service-name
537 (compose service-type-name service-kind))
538
539 (define (file-system-digest fs)
540 ;; Return a hashable digest that does not contain 'dependencies' since
541 ;; this field can contain procedures.
542 (let ((device (file-system-device fs)))
543 (list (file-system-mount-point fs)
544 (file-system-type fs)
545 (cond ((file-system-label? device)
546 (file-system-label->string device))
547 ((uuid? device)
548 (uuid->string device))
549 ((string? device)
550 device)
551 (else #f))
552 (file-system-options fs))))
553
532 (if (eq? type 'iso9660) 554 (if (eq? type 'iso9660)
533 (let ((pad (compose (cut string-pad <> 2 #\0) 555 (let ((pad (compose (cut string-pad <> 2 #\0)
534 number->string)) 556 number->string))
535 (h (hash (operating-system-services os) 3600))) 557 (h (hash (map service-name (operating-system-services os))
558 3600)))
536 (bytevector->uuid 559 (bytevector->uuid
537 (string->iso9660-uuid 560 (string->iso9660-uuid
538 (string-append "1970-01-01-" 561 (string-append "1970-01-01-"
539 (pad (hash (operating-system-host-name os) 24)) "-" 562 (pad (hash (operating-system-host-name os) 24)) "-"
540 (pad (quotient h 60)) "-" 563 (pad (quotient h 60)) "-"
541 (pad (modulo h 60)) "-" 564 (pad (modulo h 60)) "-"
542 (pad (hash (operating-system-file-systems os) 100)))) 565 (pad (hash (map file-system-digest
566 (operating-system-file-systems os))
567 100))))
543 'iso9660)) 568 'iso9660))
544 (bytevector->uuid 569 (bytevector->uuid
545 (uint-list->bytevector 570 (uint-list->bytevector
@@ -547,9 +572,9 @@ TYPE (one of 'iso9660 or 'dce). Return a UUID object."
547 (- (expt 2 32) 1)) 572 (- (expt 2 32) 1))
548 (hash (operating-system-host-name os) 573 (hash (operating-system-host-name os)
549 (- (expt 2 32) 1)) 574 (- (expt 2 32) 1))
550 (hash (operating-system-services os) 575 (hash (map service-name (operating-system-services os))
551 (- (expt 2 32) 1)) 576 (- (expt 2 32) 1))
552 (hash (operating-system-file-systems os) 577 (hash (map file-system-digest (operating-system-file-systems os))
553 (- (expt 2 32) 1))) 578 (- (expt 2 32) 1)))
554 (endianness little) 579 (endianness little)
555 4) 580 4)