summary refs log tree commit diff
path: root/gnu/build
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/build')
-rw-r--r--gnu/build/accounts.scm9
-rw-r--r--gnu/build/file-systems.scm2
-rw-r--r--gnu/build/linux-boot.scm15
-rw-r--r--gnu/build/linux-container.scm48
-rw-r--r--gnu/build/vm.scm30
5 files changed, 80 insertions, 24 deletions
diff --git a/gnu/build/accounts.scm b/gnu/build/accounts.scm
index 6b44ab610b..c43ce85b60 100644
--- a/gnu/build/accounts.scm
+++ b/gnu/build/accounts.scm
@@ -483,9 +483,12 @@ new UIDs."
                                (real-name (if previous
                                               (password-entry-real-name previous)
                                               real-name))
-                               (shell (if previous
-                                          (password-entry-shell previous)
-                                          shell)))
+
+                               ;; Do not reuse the shell of PREVIOUS since (1)
+                               ;; that could lead to confusion, and (2) the
+                               ;; shell might have been GC'd.  See
+                               ;; <https://lists.gnu.org/archive/html/guix-devel/2019-04/msg00478.html>.
+                               (shell shell))
                               result)
                         allocation))))
           '()
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index c468144170..8bb10d574d 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -575,6 +575,8 @@ corresponds to the symbols listed in FLAGS."
        (logior MS_NODEV (loop rest)))
       (('no-exec rest ...)
        (logior MS_NOEXEC (loop rest)))
+      (('no-atime rest ...)
+       (logior MS_NOATIME (loop rest)))
       (()
        0))))
 
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 44b3506284..a35d18ad7c 100644
--- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -437,6 +437,7 @@ bailing out.~%root contents: ~s~%" (scandir "/"))
 (define* (boot-system #:key
                       (linux-modules '())
                       linux-module-directory
+                      keymap-file
                       qemu-guest-networking?
                       volatile-root?
                       pre-mount
@@ -444,7 +445,8 @@ bailing out.~%root contents: ~s~%" (scandir "/"))
                       (on-error 'debug))
   "This procedure is meant to be called from an initrd.  Boot a system by
 first loading LINUX-MODULES (a list of module names) from
-LINUX-MODULE-DIRECTORY, then setting up QEMU guest networking if
+LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE with 'loadkeys' (if
+KEYMAP-FILE is true), then setting up QEMU guest networking if
 QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file systems
 specified in MOUNTS, and finally booting into the new root if any.  The initrd
 supports kernel command-line options '--load', '--root', and '--repl'.
@@ -491,6 +493,15 @@ upon error."
                       #:lookup-module lookup-module)
                  (map lookup-module linux-modules))
 
+       (when keymap-file
+         (let ((status (system* "loadkeys" keymap-file)))
+           (unless (zero? status)
+             ;; Emit a warning rather than abort when we cannot load
+             ;; KEYMAP-FILE.
+             (format (current-error-port)
+                     "warning: 'loadkeys' exited with status ~a~%"
+                     status))))
+
        (when qemu-guest-networking?
          (unless (configure-qemu-networking)
            (display "network interface is DOWN\n")))
diff --git a/gnu/build/linux-container.scm b/gnu/build/linux-container.scm
index 65e1325577..3d7b52f098 100644
--- a/gnu/build/linux-container.scm
+++ b/gnu/build/linux-container.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
-;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -168,9 +168,12 @@ for the process."
     (umount "real-root" MNT_DETACH)
     (rmdir "real-root")))
 
-(define (initialize-user-namespace pid host-uids)
+(define* (initialize-user-namespace pid host-uids
+                                    #:key (guest-uid 0) (guest-gid 0))
   "Configure the user namespace for PID.  HOST-UIDS specifies the number of
-host user identifiers to map into the user namespace."
+host user identifiers to map into the user namespace.  GUEST-UID and GUEST-GID
+specify the first UID (respectively GID) that host UIDs (respectively GIDs)
+map to in the namespace."
   (define proc-dir
     (string-append "/proc/" (number->string pid)))
 
@@ -191,10 +194,10 @@ host user identifiers to map into the user namespace."
     ;; within the container.
     (call-with-output-file (scope "/uid_map")
       (lambda (port)
-        (format port "0 ~d ~d" uid host-uids)))
+        (format port "~d ~d ~d" guest-uid uid host-uids)))
     (call-with-output-file (scope "/gid_map")
       (lambda (port)
-        (format port "0 ~d ~d" gid host-uids)))))
+        (format port "~d ~d ~d" guest-gid gid host-uids)))))
 
 (define (namespaces->bit-mask namespaces)
   "Return the number suitable for the 'flags' argument of 'clone' that
@@ -210,13 +213,17 @@ corresponds to the symbols in NAMESPACES."
                ('net  CLONE_NEWNET))
               namespaces)))
 
-(define (run-container root mounts namespaces host-uids thunk)
+(define* (run-container root mounts namespaces host-uids thunk
+                        #:key (guest-uid 0) (guest-gid 0))
   "Run THUNK in a new container process and return its PID.  ROOT specifies
 the root directory for the container.  MOUNTS is a list of <file-system>
 objects that specify file systems to mount inside the container.  NAMESPACES
 is a list of symbols that correspond to the possible Linux namespaces: mnt,
-ipc, uts, user, and net.  HOST-UIDS specifies the number of
-host user identifiers to map into the user namespace."
+ipc, uts, user, and net.
+
+HOST-UIDS specifies the number of host user identifiers to map into the user
+namespace.  GUEST-UID and GUEST-GID specify the first UID (respectively GID)
+that host UIDs (respectively GIDs) map to in the namespace."
   ;; The parent process must initialize the user namespace for the child
   ;; before it can boot.  To negotiate this, a pipe is used such that the
   ;; child process blocks until the parent writes to it.
@@ -254,7 +261,9 @@ host user identifiers to map into the user namespace."
          (pid
           (close-port child)
           (when (memq 'user namespaces)
-            (initialize-user-namespace pid host-uids))
+            (initialize-user-namespace pid host-uids
+                                       #:guest-uid guest-uid
+                                       #:guest-gid guest-gid))
           ;; TODO: Initialize cgroups.
           (write 'ready parent)
           (newline parent)
@@ -271,23 +280,30 @@ host user identifiers to map into the user namespace."
                #f)))))))))
 
 (define* (call-with-container mounts thunk #:key (namespaces %namespaces)
-                              (host-uids 1))
+                              (host-uids 1) (guest-uid 0) (guest-gid 0))
   "Run THUNK in a new container process and return its exit status.
 MOUNTS is a list of <file-system> objects that specify file systems to mount
 inside the container.  NAMESPACES is a list of symbols corresponding to
 the identifiers for Linux namespaces: mnt, ipc, uts, pid, user, and net.  By
-default, all namespaces are used.  HOST-UIDS is the number of host user
-identifiers to map into the container's user namespace, if there is one.  By
-default, only a single uid/gid, that of the current user, is mapped into the
-container.  The host user that creates the container is the root user (uid/gid
-0) within the container.  Only root can map more than a single uid/gid.
+default, all namespaces are used.
+
+HOST-UIDS is the number of host user identifiers to map into the container's
+user namespace, if there is one.  By default, only a single uid/gid, that of
+the current user, is mapped into the container.  The host user that creates
+the container is the root user (uid/gid 0) within the container.  Only root
+can map more than a single uid/gid.
+
+GUEST-UID and GUEST-GID specify the first UID (respectively GID) that host
+UIDs (respectively GIDs) map to in the namespace.
 
 Note that if THUNK needs to load any additional Guile modules, the relevant
 module files must be present in one of the mappings in MOUNTS and the Guile
 load path must be adjusted as needed."
   (call-with-temporary-directory
    (lambda (root)
-     (let ((pid (run-container root mounts namespaces host-uids thunk)))
+     (let ((pid (run-container root mounts namespaces host-uids thunk
+                               #:guest-uid guest-uid
+                               #:guest-gid guest-gid)))
        ;; Catch SIGINT and kill the container process.
        (sigaction SIGINT
          (lambda (signum)
diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm
index 6d6a0c4cb4..ac99d6b1a3 100644
--- a/gnu/build/vm.scm
+++ b/gnu/build/vm.scm
@@ -37,6 +37,7 @@
   #:use-module (ice-9 popen)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-9)
+  #:use-module (srfi srfi-19)
   #:use-module (srfi srfi-26)
   #:export (qemu-command
             load-in-linux-vm
@@ -144,6 +145,7 @@ the #:references-graphs parameter of 'derivation'."
     (_ #f))
 
   (apply invoke qemu "-nographic" "-no-reboot"
+         "-smp" (number->string (parallel-job-count))
          "-m" (number->string memory-size)
          "-object" "rng-random,filename=/dev/urandom,id=guixsd-vm-rng"
          "-device" "virtio-rng-pci,rng=guixsd-vm-rng"
@@ -458,6 +460,29 @@ GRUB configuration and OS-DRV as the stuff in it."
               closures)
     (register-bootcfg-root "/tmp/root" config-file))
 
+  ;; 'grub-mkrescue' calls out to mtools programs to create 'efi.img', a FAT
+  ;; file system image, and mtools honors SOURCE_DATE_EPOCH for the mtime of
+  ;; those files.  The epoch for FAT is Jan. 1st 1980, not 1970, so choose
+  ;; that.
+  (setenv "SOURCE_DATE_EPOCH"
+          (number->string
+           (time-second
+            (date->time-utc (make-date 0 0 0 0 1 1 1980 0)))))
+
+  ;; Our patched 'grub-mkrescue' honors this environment variable and passes
+  ;; it to 'mformat', which makes it the serial number of 'efi.img'.  This
+  ;; allows for deterministic builds.
+  (setenv "GRUB_FAT_SERIAL_NUMBER"
+          (number->string (if volume-uuid
+
+                              ;; On 32-bit systems the 2nd argument must be
+                              ;; lower than 2^32.
+                              (string-hash (iso9660-uuid->string volume-uuid)
+                                           (- (expt 2 32) 1))
+
+                              #x77777777)
+                          16))
+
   (let ((pipe
          (apply open-pipe* OPEN_WRITE
                 grub-mkrescue "-o" target
@@ -472,9 +497,8 @@ GRUB configuration and OS-DRV as the stuff in it."
                 "-path-list" "-"
                 "--"
 
-                ;; XXX: Add padding to avoid I/O errors on i686:
-                ;; <https://bugs.gnu.org/33639>.
-                "-padding" "10m"
+                ;; Set all timestamps to 1.
+                "-volume_date" "all_file_dates" "=1"
 
                 "-volid" (string-upcase volume-id)
                 (if volume-uuid