system: Introduce a disjoint UUID type.
Conceptually a UUID is just a bytevector. However, there's software out there such as GRUB that relies on the string representation of different UUID types (e.g., the string representation of DCE UUIDs differs from that of ISO-9660 UUIDs, even if they are actually bytevectors of the same length). This new <uuid> record type allows us to preserve information about the type of UUID so we can eventually convert it to a string using the right representation. * gnu/system/uuid.scm (<uuid>): New record type. (bytevector->uuid): New procedure. (uuid): Return calls to 'make-uuid'. (uuid->string): Rewrite using 'match-lambda*' to accept a single 'uuid?' argument. * gnu/bootloader/grub.scm (grub-root-search): Check for 'uuid?' instead of 'bytevector?'. * gnu/system.scm (bootable-kernel-arguments): Check whether ROOT-DEVICE is 'uuid?'. (read-boot-parameters): Use 'bytevector->uuid' when the store device is a bytevector. (read-boot-parameters-file): Check for 'uuid?' instead of 'bytevector?'. (device->sexp): New procedure. (operating-system-boot-parameters-file): Use it for 'root-device' and 'store'. (operating-system-bootcfg): Remove conditional in definition of 'root-device'. * gnu/system/file-systems.scm (file-system->spec): Check for 'uuid?' on DEVICE and take its bytevector. * gnu/system/mapped-devices.scm (open-luks-device): Likewise. * gnu/system/vm.scm (iso9660-image): Call 'uuid-bytevector' for the #:volume-uuid argument.master
parent
d1ff5f9db3
commit
9b336338cd
|
@ -30,7 +30,7 @@
|
||||||
#:use-module (gnu artwork)
|
#:use-module (gnu artwork)
|
||||||
#:use-module (gnu system)
|
#:use-module (gnu system)
|
||||||
#:use-module (gnu bootloader)
|
#:use-module (gnu bootloader)
|
||||||
#:use-module (gnu system file-systems)
|
#:use-module (gnu system uuid)
|
||||||
#:autoload (gnu packages bootloaders) (grub)
|
#:autoload (gnu packages bootloaders) (grub)
|
||||||
#:autoload (gnu packages compression) (gzip)
|
#:autoload (gnu packages compression) (gzip)
|
||||||
#:autoload (gnu packages gtk) (guile-cairo guile-rsvg)
|
#:autoload (gnu packages gtk) (guile-cairo guile-rsvg)
|
||||||
|
@ -300,7 +300,7 @@ code."
|
||||||
(match device
|
(match device
|
||||||
;; Preferably refer to DEVICE by its UUID or label. This is more
|
;; Preferably refer to DEVICE by its UUID or label. This is more
|
||||||
;; efficient and less ambiguous, see <http://bugs.gnu.org/22281>.
|
;; efficient and less ambiguous, see <http://bugs.gnu.org/22281>.
|
||||||
((? bytevector? uuid)
|
((? uuid? uuid)
|
||||||
(format #f "search --fs-uuid --set ~a"
|
(format #f "search --fs-uuid --set ~a"
|
||||||
(uuid->string device)))
|
(uuid->string device)))
|
||||||
((? string? label)
|
((? string? label)
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#:use-module (gnu system locale)
|
#:use-module (gnu system locale)
|
||||||
#:use-module (gnu system pam)
|
#:use-module (gnu system pam)
|
||||||
#:use-module (gnu system linux-initrd)
|
#:use-module (gnu system linux-initrd)
|
||||||
|
#:use-module (gnu system uuid)
|
||||||
#:use-module (gnu system file-systems)
|
#:use-module (gnu system file-systems)
|
||||||
#:use-module (gnu system mapped-devices)
|
#:use-module (gnu system mapped-devices)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
|
@ -128,7 +129,14 @@
|
||||||
(define (bootable-kernel-arguments kernel-arguments system.drv root-device)
|
(define (bootable-kernel-arguments kernel-arguments system.drv root-device)
|
||||||
"Prepend extra arguments to KERNEL-ARGUMENTS that allow SYSTEM.DRV to be
|
"Prepend extra arguments to KERNEL-ARGUMENTS that allow SYSTEM.DRV to be
|
||||||
booted from ROOT-DEVICE"
|
booted from ROOT-DEVICE"
|
||||||
(cons* (string-append "--root=" root-device)
|
(cons* (string-append "--root="
|
||||||
|
(if (uuid? root-device)
|
||||||
|
|
||||||
|
;; Note: Always use the DCE format because that's
|
||||||
|
;; what (gnu build linux-boot) expects for the
|
||||||
|
;; '--root' kernel command-line option.
|
||||||
|
(uuid->string (uuid-bytevector root-device) 'dce)
|
||||||
|
root-device))
|
||||||
#~(string-append "--system=" #$system.drv)
|
#~(string-append "--system=" #$system.drv)
|
||||||
#~(string-append "--load=" #$system.drv "/boot")
|
#~(string-append "--load=" #$system.drv "/boot")
|
||||||
kernel-arguments))
|
kernel-arguments))
|
||||||
|
@ -261,6 +269,8 @@ directly by the user."
|
||||||
|
|
||||||
(store-device
|
(store-device
|
||||||
(match (assq 'store rest)
|
(match (assq 'store rest)
|
||||||
|
(('store ('device (? bytevector? bv)) _ ...)
|
||||||
|
(bytevector->uuid bv))
|
||||||
(('store ('device device) _ ...)
|
(('store ('device device) _ ...)
|
||||||
device)
|
device)
|
||||||
(_ ;the old format
|
(_ ;the old format
|
||||||
|
@ -289,16 +299,12 @@ The object has its kernel-arguments extended in order to make it bootable."
|
||||||
(let* ((file (string-append system "/parameters"))
|
(let* ((file (string-append system "/parameters"))
|
||||||
(params (call-with-input-file file read-boot-parameters))
|
(params (call-with-input-file file read-boot-parameters))
|
||||||
(root (boot-parameters-root-device params))
|
(root (boot-parameters-root-device params))
|
||||||
(root-device (if (bytevector? root)
|
|
||||||
(uuid->string root)
|
|
||||||
root))
|
|
||||||
(kernel-arguments (boot-parameters-kernel-arguments params)))
|
(kernel-arguments (boot-parameters-kernel-arguments params)))
|
||||||
(if params
|
(if params
|
||||||
(boot-parameters
|
(boot-parameters
|
||||||
(inherit params)
|
(inherit params)
|
||||||
(kernel-arguments (bootable-kernel-arguments kernel-arguments
|
(kernel-arguments (bootable-kernel-arguments kernel-arguments
|
||||||
system
|
system root)))
|
||||||
root-device)))
|
|
||||||
#f)))
|
#f)))
|
||||||
|
|
||||||
(define (boot-parameters->menu-entry conf)
|
(define (boot-parameters->menu-entry conf)
|
||||||
|
@ -875,9 +881,7 @@ listed in OS. The C library expects to find it under
|
||||||
(mlet* %store-monad
|
(mlet* %store-monad
|
||||||
((system (operating-system-derivation os))
|
((system (operating-system-derivation os))
|
||||||
(root-fs -> (operating-system-root-file-system os))
|
(root-fs -> (operating-system-root-file-system os))
|
||||||
(root-device -> (if (eq? 'uuid (file-system-title root-fs))
|
(root-device -> (file-system-device root-fs))
|
||||||
(uuid->string (file-system-device root-fs))
|
|
||||||
(file-system-device root-fs)))
|
|
||||||
(params (operating-system-boot-parameters os system root-device))
|
(params (operating-system-boot-parameters os system root-device))
|
||||||
(entry -> (boot-parameters->menu-entry params))
|
(entry -> (boot-parameters->menu-entry params))
|
||||||
(bootloader-conf -> (operating-system-bootloader os)))
|
(bootloader-conf -> (operating-system-bootloader os)))
|
||||||
|
@ -917,6 +921,15 @@ kernel arguments for that derivation to <boot-parameters>."
|
||||||
(store-device (fs->boot-device store))
|
(store-device (fs->boot-device store))
|
||||||
(store-mount-point (file-system-mount-point store))))))
|
(store-mount-point (file-system-mount-point store))))))
|
||||||
|
|
||||||
|
(define (device->sexp device)
|
||||||
|
"Serialize DEVICE as an sexp (really, as an object with a read syntax.)"
|
||||||
|
(match device
|
||||||
|
((? uuid? uuid)
|
||||||
|
;; TODO: Preserve the type of UUID.
|
||||||
|
(uuid-bytevector uuid))
|
||||||
|
(_
|
||||||
|
device)))
|
||||||
|
|
||||||
(define* (operating-system-boot-parameters-file os #:optional (system.drv #f))
|
(define* (operating-system-boot-parameters-file os #:optional (system.drv #f))
|
||||||
"Return a file that describes the boot parameters of OS. The primary use of
|
"Return a file that describes the boot parameters of OS. The primary use of
|
||||||
this file is the reconstruction of GRUB menu entries for old configurations.
|
this file is the reconstruction of GRUB menu entries for old configurations.
|
||||||
|
@ -934,14 +947,17 @@ being stored into the \"parameters\" file)."
|
||||||
#~(boot-parameters
|
#~(boot-parameters
|
||||||
(version 0)
|
(version 0)
|
||||||
(label #$(boot-parameters-label params))
|
(label #$(boot-parameters-label params))
|
||||||
(root-device #$(boot-parameters-root-device params))
|
(root-device
|
||||||
|
#$(device->sexp
|
||||||
|
(boot-parameters-root-device params)))
|
||||||
(kernel #$(boot-parameters-kernel params))
|
(kernel #$(boot-parameters-kernel params))
|
||||||
(kernel-arguments
|
(kernel-arguments
|
||||||
#$(boot-parameters-kernel-arguments params))
|
#$(boot-parameters-kernel-arguments params))
|
||||||
(initrd #$(boot-parameters-initrd params))
|
(initrd #$(boot-parameters-initrd params))
|
||||||
(bootloader-name #$(boot-parameters-bootloader-name params))
|
(bootloader-name #$(boot-parameters-bootloader-name params))
|
||||||
(store
|
(store
|
||||||
(device #$(boot-parameters-store-device params))
|
(device
|
||||||
|
#$(device->sexp (boot-parameters-store-device params)))
|
||||||
(mount-point #$(boot-parameters-store-mount-point params))))
|
(mount-point #$(boot-parameters-store-mount-point params))))
|
||||||
#:set-load-path? #f)))
|
#:set-load-path? #f)))
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
#:use-module ((gnu system uuid)
|
#:use-module (gnu system uuid)
|
||||||
#:select (uuid string->uuid uuid->string))
|
|
||||||
#:re-export (uuid ;backward compatibility
|
#:re-export (uuid ;backward compatibility
|
||||||
string->uuid
|
string->uuid
|
||||||
uuid->string)
|
uuid->string)
|
||||||
|
@ -157,7 +156,10 @@ store--e.g., if FS is the root file system."
|
||||||
initrd code."
|
initrd code."
|
||||||
(match fs
|
(match fs
|
||||||
(($ <file-system> device title mount-point type flags options _ _ check?)
|
(($ <file-system> device title mount-point type flags options _ _ check?)
|
||||||
(list device title mount-point type flags options check?))))
|
(list (if (uuid? device)
|
||||||
|
(uuid-bytevector device)
|
||||||
|
device)
|
||||||
|
title mount-point type flags options check?))))
|
||||||
|
|
||||||
(define (spec->file-system sexp)
|
(define (spec->file-system sexp)
|
||||||
"Deserialize SEXP, a list, to the corresponding <file-system> object."
|
"Deserialize SEXP, a list, to the corresponding <file-system> object."
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
|
;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
|
||||||
;;; Copyright © 2017 Mark H Weaver <mhw@netris.org>
|
;;; Copyright © 2017 Mark H Weaver <mhw@netris.org>
|
||||||
;;;
|
;;;
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
#:use-module (guix modules)
|
#:use-module (guix modules)
|
||||||
#:use-module (gnu services)
|
#:use-module (gnu services)
|
||||||
#:use-module (gnu services shepherd)
|
#:use-module (gnu services shepherd)
|
||||||
|
#:use-module (gnu system uuid)
|
||||||
#:autoload (gnu packages cryptsetup) (cryptsetup-static)
|
#:autoload (gnu packages cryptsetup) (cryptsetup-static)
|
||||||
#:autoload (gnu packages linux) (mdadm-static)
|
#:autoload (gnu packages linux) (mdadm-static)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
|
@ -99,7 +100,9 @@
|
||||||
'cryptsetup'."
|
'cryptsetup'."
|
||||||
(with-imported-modules (source-module-closure
|
(with-imported-modules (source-module-closure
|
||||||
'((gnu build file-systems)))
|
'((gnu build file-systems)))
|
||||||
#~(let ((source #$source))
|
#~(let ((source #$(if (uuid? source)
|
||||||
|
(uuid-bytevector source)
|
||||||
|
source)))
|
||||||
;; XXX: 'use-modules' should be at the top level.
|
;; XXX: 'use-modules' should be at the top level.
|
||||||
(use-modules (rnrs bytevectors) ;bytevector?
|
(use-modules (rnrs bytevectors) ;bytevector?
|
||||||
((gnu build file-systems)
|
((gnu build file-systems)
|
||||||
|
|
|
@ -19,12 +19,19 @@
|
||||||
|
|
||||||
(define-module (gnu system uuid)
|
(define-module (gnu system uuid)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
|
#:use-module (srfi srfi-9)
|
||||||
#:use-module (rnrs bytevectors)
|
#:use-module (rnrs bytevectors)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 vlist)
|
#:use-module (ice-9 vlist)
|
||||||
#:use-module (ice-9 regex)
|
#:use-module (ice-9 regex)
|
||||||
#:use-module (ice-9 format)
|
#:use-module (ice-9 format)
|
||||||
#:export (uuid
|
#:export (uuid
|
||||||
|
uuid?
|
||||||
|
uuid-type
|
||||||
|
uuid-bytevector
|
||||||
|
|
||||||
|
bytevector->uuid
|
||||||
|
|
||||||
uuid->string
|
uuid->string
|
||||||
dce-uuid->string
|
dce-uuid->string
|
||||||
string->uuid
|
string->uuid
|
||||||
|
@ -206,15 +213,27 @@ corresponding bytevector; otherwise return #f."
|
||||||
(#f #f)
|
(#f #f)
|
||||||
((_ . (? procedure? parse)) (parse str))))
|
((_ . (? procedure? parse)) (parse str))))
|
||||||
|
|
||||||
(define* (uuid->string bv #:key (type 'dce))
|
;; High-level UUID representation that carries its type with it.
|
||||||
"Convert BV, a bytevector, to the UUID string representation for TYPE."
|
;;
|
||||||
(match (vhash-assq type %uuid-printers)
|
;; This is necessary to serialize bytevectors with the right printer in some
|
||||||
(#f #f)
|
;; circumstances. For instance, GRUB "search --fs-uuid" command compares the
|
||||||
((_ . (? procedure? unparse)) (unparse bv))))
|
;; string representation of UUIDs, not the raw bytes; thus, when emitting a
|
||||||
|
;; GRUB 'search' command, we need to procedure the right string representation
|
||||||
|
;; (see <https://debbugs.gnu.org/cgi/bugreport.cgi?msg=52;att=0;bug=27735>).
|
||||||
|
(define-record-type <uuid>
|
||||||
|
(make-uuid type bv)
|
||||||
|
uuid?
|
||||||
|
(type uuid-type) ;'dce | 'iso9660 | ...
|
||||||
|
(bv uuid-bytevector))
|
||||||
|
|
||||||
|
(define* (bytevector->uuid bv #:optional (type 'dce))
|
||||||
|
"Return a UUID object make of BV and TYPE."
|
||||||
|
(make-uuid type bv))
|
||||||
|
|
||||||
(define-syntax uuid
|
(define-syntax uuid
|
||||||
(lambda (s)
|
(lambda (s)
|
||||||
"Return the bytevector corresponding to the given UUID representation."
|
"Return the UUID object corresponding to the given UUID representation."
|
||||||
|
;; TODO: Extend to types other than DCE.
|
||||||
(syntax-case s ()
|
(syntax-case s ()
|
||||||
((_ str)
|
((_ str)
|
||||||
(string? (syntax->datum #'str))
|
(string? (syntax->datum #'str))
|
||||||
|
@ -222,6 +241,19 @@ corresponding bytevector; otherwise return #f."
|
||||||
(let ((bv (string->uuid (syntax->datum #'str))))
|
(let ((bv (string->uuid (syntax->datum #'str))))
|
||||||
(unless bv
|
(unless bv
|
||||||
(syntax-violation 'uuid "invalid UUID" s))
|
(syntax-violation 'uuid "invalid UUID" s))
|
||||||
(datum->syntax #'str bv)))
|
#`(make-uuid 'dce #,(datum->syntax #'str bv))))
|
||||||
((_ str)
|
((_ str)
|
||||||
#'(string->uuid str)))))
|
#'(make-uuid 'dce (string->uuid str))))))
|
||||||
|
|
||||||
|
(define uuid->string
|
||||||
|
;; Convert the given bytevector or UUID object, to the corresponding UUID
|
||||||
|
;; string representation.
|
||||||
|
(match-lambda*
|
||||||
|
(((? bytevector? bv))
|
||||||
|
(uuid->string bv 'dce))
|
||||||
|
(((? bytevector? bv) type)
|
||||||
|
(match (vhash-assq type %uuid-printers)
|
||||||
|
(#f #f)
|
||||||
|
((_ . (? procedure? unparse)) (unparse bv))))
|
||||||
|
(((? uuid? uuid))
|
||||||
|
(uuid->string (uuid-bytevector uuid) (uuid-type uuid)))))
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#:use-module (gnu system file-systems)
|
#:use-module (gnu system file-systems)
|
||||||
#:use-module (gnu system)
|
#:use-module (gnu system)
|
||||||
#:use-module (gnu services)
|
#:use-module (gnu services)
|
||||||
|
#:use-module (gnu system uuid)
|
||||||
|
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-26)
|
#:use-module (srfi srfi-26)
|
||||||
|
@ -231,7 +232,8 @@ INPUTS is a list of inputs (as for packages)."
|
||||||
#:register-closures? #$register-closures?
|
#:register-closures? #$register-closures?
|
||||||
#:closures graphs
|
#:closures graphs
|
||||||
#:volume-id #$file-system-label
|
#:volume-id #$file-system-label
|
||||||
#:volume-uuid #$file-system-uuid)
|
#:volume-uuid #$(and=> file-system-uuid
|
||||||
|
uuid-bytevector))
|
||||||
(reboot))))
|
(reboot))))
|
||||||
#:system system
|
#:system system
|
||||||
#:make-disk-image? #f
|
#:make-disk-image? #f
|
||||||
|
|
Reference in New Issue