From 7b307a21dd723507854ee18e458167d0fb9134fd Mon Sep 17 00:00:00 2001 From: Mathieu Othacehe Date: Mon, 4 Dec 2017 18:04:13 +0100 Subject: vm: Use qemu drive device parameter. * gnu/build/vm.scm (load-in-linux-vm): Use device parameter to define drive device. --- gnu/build/vm.scm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index 20ee12709b..ed84463677 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -127,8 +127,10 @@ the #:references-graphs parameter of 'derivation'." builder) (append (if make-disk-image? - `("-drive" ,(string-append "file=" output - ",if=virtio")) + `("-device" "virtio-blk,drive=myhd" + "-drive" ,(string-append "if=none,file=" output + ",format=" disk-image-format + ",id=myhd")) '()) ;; Only enable kvm if we see /dev/kvm exists. ;; This allows users without hardware virtualization to still -- cgit v1.2.3 From acf54bca225b63f5b06e335a55045421c47bbd09 Mon Sep 17 00:00:00 2001 From: Mathieu Othacehe Date: Tue, 5 Dec 2017 11:34:01 +0100 Subject: vm: Adapt qemu command to ARM. * gnu/build/vm.scm (load-in-linux-vm): New argument #:target-arm32. Use it to adapt command for qemu-system-arm. This implies to choose a machine ("virt"), use the correct console port "ttyAMA0", disable KVM use that is buggy on some ARM boards (Odroid XU4 for example) and use user mode network stack instead of NIC. Gather all those options in a new variable "arch-specific-flags". * gnu/system/vm.scm (expression->derivation-in-linux-vm): Pass to load-in-linux-vm "#:target-arm32?" argument. --- gnu/build/vm.scm | 34 +++++++++++++++++++++++++++------- gnu/system/vm.scm | 4 ++++ 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index ed84463677..8f8ca609f2 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -77,6 +77,7 @@ linux initrd make-disk-image? single-file-output? + target-arm32? (disk-image-size (* 100 (expt 2 20))) (disk-image-format "qcow2") (references-graphs '())) @@ -91,6 +92,31 @@ access it via /dev/hda. REFERENCES-GRAPHS can specify a list of reference-graph files as produced by the #:references-graphs parameter of 'derivation'." + + (define arch-specific-flags + `(;; On ARM, a machine has to be specified. Use "virt" machine to avoid + ;; hardware limits imposed by other machines. + ,@(if target-arm32? '("-M" "virt") '()) + + ;; Only enable kvm if we see /dev/kvm exists. This allows users without + ;; hardware virtualization to still use these commands. KVM support is + ;; still buggy on some ARM32 boards. Do not use it even if available. + ,@(if (and (file-exists? "/dev/kvm") + (not target-arm32?)) + '("-enable-kvm") + '()) + "-append" + ;; The serial port name differs between emulated architectures/machines. + ,@(if target-arm32? + `(,(string-append "console=ttyAMA0 --load=" builder)) + `(,(string-append "console=ttyS0 --load=" builder))) + ;; NIC is not supported on ARM "virt" machine, so use a user mode + ;; network stack instead. + ,@(if target-arm32? + '("-device" "virtio-net-pci,netdev=mynet" + "-netdev" "user,id=mynet") + '("-net" "nic,model=virtio")))) + (when make-disk-image? (format #t "creating ~a image of ~,2f MiB...~%" disk-image-format (/ disk-image-size (expt 2 20))) @@ -113,7 +139,6 @@ the #:references-graphs parameter of 'derivation'." (unless (zero? (apply system* qemu "-nographic" "-no-reboot" "-m" (number->string memory-size) - "-net" "nic,model=virtio" "-virtfs" (string-append "local,id=store_dev,path=" (%store-directory) @@ -132,12 +157,7 @@ the #:references-graphs parameter of 'derivation'." ",format=" disk-image-format ",id=myhd")) '()) - ;; Only enable kvm if we see /dev/kvm exists. - ;; This allows users without hardware virtualization to still - ;; use these commands. - (if (file-exists? "/dev/kvm") - '("-enable-kvm") - '())))) + arch-specific-flags))) (error "qemu failed" qemu)) ;; When MAKE-DISK-IMAGE? is true, the image is in OUTPUT already. diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm index d754ac76f0..b376337c8d 100644 --- a/gnu/system/vm.scm +++ b/gnu/system/vm.scm @@ -175,6 +175,10 @@ made available under the /xchg CIFS share." #:memory-size #$memory-size #:make-disk-image? #$make-disk-image? #:single-file-output? #$single-file-output? + ;; FIXME: ‘target-arm32?’ may not operate on + ;; the right system/target values. Rewrite + ;; using ‘let-system’ when available. + #:target-arm32? #$(target-arm32?) #:disk-image-format #$disk-image-format #:disk-image-size size #:references-graphs graphs))))) -- cgit v1.2.3 From e22482038611a53a9d2b25df20363664cd91be2e Mon Sep 17 00:00:00 2001 From: Mathieu Othacehe Date: Tue, 5 Dec 2017 12:59:15 +0100 Subject: bootloader: Factorize write-file-on-device. * gnu/bootloader/extlinux.scm (install-extlinux): Factorize bootloader writing in a new procedure write-file-on-device defined in (gnu build bootloader). * gnu/build/bootloader.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add new file. * gnu/system/vm.scm (qemu-img): Adapt to import and use (gnu build bootloader) module during derivation building. * gnu/scripts/system.scm (bootloader-installer-derivation): Ditto. --- gnu/bootloader/extlinux.scm | 10 +++------- gnu/build/bootloader.scm | 37 +++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + gnu/system/vm.scm | 6 ++++-- guix/scripts/system.scm | 6 ++++-- 5 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 gnu/build/bootloader.scm (limited to 'gnu/build') diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scm index 9b6e2c7f2a..f7820a37a4 100644 --- a/gnu/bootloader/extlinux.scm +++ b/gnu/bootloader/extlinux.scm @@ -20,6 +20,7 @@ (define-module (gnu bootloader extlinux) #:use-module (gnu bootloader) #:use-module (gnu system) + #:use-module (gnu build bootloader) #:use-module (gnu packages bootloaders) #:use-module (guix gexp) #:use-module (guix monads) @@ -95,13 +96,8 @@ TIMEOUT ~a~%" (find-files syslinux-dir "\\.c32$")) (unless (and (zero? (system* extlinux "--install" install-dir)) - (call-with-input-file (string-append syslinux-dir "/" #$mbr) - (lambda (input) - (let ((bv (get-bytevector-n input 440))) - (call-with-output-file device - (lambda (output) - (put-bytevector output bv)) - #:binary #t))))) + (write-file-on-device + (string-append syslinux-dir "/" #$mbr) 440 device 0)) (error "failed to install SYSLINUX"))))) (define install-extlinux-mbr diff --git a/gnu/build/bootloader.scm b/gnu/build/bootloader.scm new file mode 100644 index 0000000000..d00674dd40 --- /dev/null +++ b/gnu/build/bootloader.scm @@ -0,0 +1,37 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2017 Mathieu Othacehe +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu build bootloader) + #:use-module (ice-9 binary-ports) + #:export (write-file-on-device)) + + +;;; +;;; Writing utils. +;;; + +(define (write-file-on-device file size device offset) + "Write SIZE bytes from FILE to DEVICE starting at OFFSET." + (call-with-input-file file + (lambda (input) + (let ((bv (get-bytevector-n input size))) + (call-with-output-file device + (lambda (output) + (seek output offset SEEK_SET) + (put-bytevector output bv)) + #:binary #t))))) diff --git a/gnu/local.mk b/gnu/local.mk index f6b29a7155..c87af5a17b 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -489,6 +489,7 @@ GNU_SYSTEM_MODULES = \ %D%/system/vm.scm \ \ %D%/build/activation.scm \ + %D%/build/bootloader.scm \ %D%/build/cross-toolchain.scm \ %D%/build/file-systems.scm \ %D%/build/install.scm \ diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm index b376337c8d..6102d465b8 100644 --- a/gnu/system/vm.scm +++ b/gnu/system/vm.scm @@ -277,10 +277,12 @@ register INPUTS in the store database of the image so that Guix can be used in the image." (expression->derivation-in-linux-vm name - (with-imported-modules (source-module-closure '((gnu build vm) + (with-imported-modules (source-module-closure '((gnu build bootloader) + (gnu build vm) (guix build utils))) #~(begin - (use-modules (gnu build vm) + (use-modules (gnu build bootloader) + (gnu build vm) (guix build utils) (srfi srfi-26) (ice-9 binary-ports)) diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index d0eacc573c..cbf7e6cd03 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -674,9 +674,11 @@ any, are available. Raise an error if they're not." and TARGET arguments." (with-monad %store-monad (gexp->file "bootloader-installer" - (with-imported-modules '((guix build utils)) + (with-imported-modules '((gnu build bootloader) + (guix build utils)) #~(begin - (use-modules (guix build utils) + (use-modules (gnu build bootloader) + (guix build utils) (ice-9 binary-ports)) (#$installer #$bootloader #$device #$target)))))) -- cgit v1.2.3 From 97817e7f18bd3bd95152e46239ad96928678e944 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Sat, 16 Dec 2017 00:16:40 +0100 Subject: linux-boot: Add make-static-device-nodes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/build/linux-boot.scm (make-static-device-nodes): New variable. (): New variable. (read-static-device-nodes): New variable. (report-system-error): New variable. (catch-system-error): New variable. (create-device-node): New variable. (mkdir-p*): New variable. Co-Authored-By: Ludovic Courtès --- gnu/build/linux-boot.scm | 107 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'gnu/build') diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm index 2547f1e0af..4dd740174e 100644 --- a/gnu/build/linux-boot.scm +++ b/gnu/build/linux-boot.scm @@ -22,8 +22,11 @@ #:use-module (system repl error-handling) #:autoload (system repl repl) (start-repl) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) #:use-module (srfi srfi-26) #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (ice-9 regex) #:use-module (ice-9 ftw) #:use-module (guix build utils) #:use-module ((guix build syscalls) @@ -35,6 +38,7 @@ linux-command-line find-long-option make-essential-device-nodes + make-static-device-nodes configure-qemu-networking bind-mount @@ -105,6 +109,109 @@ with the given MAJOR number, starting with MINOR." 'block-special #o644 (device-number major (+ minor i))) (loop (+ i 1))))) +;; Representation of a /dev node. +(define-record-type + (device-node name type major minor module) + device-node? + (name device-node-name) + (type device-node-type) + (major device-node-major) + (minor device-node-minor) + (module device-node-module)) + +(define (read-static-device-nodes port) + "Read from PORT a list of written in the format used by +/lib/modules/*/*.devname files." + (let loop ((line (read-line port))) + (if (eof-object? line) + '() + (match (string-split line #\space) + (((? (cut string-prefix? "#" <>)) _ ...) + (loop (read-line port))) + ((module-name device-name device-spec) + (let* ((device-parts + (string-match "([bc])([0-9][0-9]*):([0-9][0-9]*)" + device-spec)) + (type-string (match:substring device-parts 1)) + (type (match type-string + ("c" 'char-special) + ("b" 'block-special))) + (major-string (match:substring device-parts 2)) + (major (string->number major-string 10)) + (minor-string (match:substring device-parts 3)) + (minor (string->number minor-string 10))) + (cons (device-node device-name type major minor module-name) + (loop (read-line port))))) + (_ + (begin + (format (current-error-port) + "read-static-device-nodes: ignored devname line '~a'~%" line) + (loop (read-line port)))))))) + +(define* (mkdir-p* dir #:optional (mode #o755)) + "This is a variant of 'mkdir-p' that works around + by passing MODE explicitly in each 'mkdir' call." + (define absolute? + (string-prefix? "/" dir)) + + (define not-slash + (char-set-complement (char-set #\/))) + + (let loop ((components (string-tokenize dir not-slash)) + (root (if absolute? + "" + "."))) + (match components + ((head tail ...) + (let ((path (string-append root "/" head))) + (catch 'system-error + (lambda () + (mkdir path mode) + (loop tail path)) + (lambda args + (if (= EEXIST (system-error-errno args)) + (loop tail path) + (apply throw args)))))) + (() #t)))) + +(define (report-system-error name . args) + "Report a system error for the file NAME." + (let ((errno (system-error-errno args))) + (format (current-error-port) "could not create '~a': ~a~%" name + (strerror errno)))) + +;; Catch a system-error, log it and don't die from it. +(define-syntax-rule (catch-system-error name exp) + (catch 'system-error + (lambda () + exp) + (lambda args + (apply report-system-error name args)))) + +;; Create a device node like the passed here on the filesystem. +(define create-device-node + (match-lambda + (($ xname type major minor module) + (let ((name (string-append "/dev/" xname))) + (mkdir-p* (dirname name)) + (catch-system-error name + (mknod name type #o600 (device-number major minor))))))) + +(define* (make-static-device-nodes linux-release-module-directory) + "Create static device nodes required by the given Linux release. +This is required in order to solve a chicken-or-egg problem: +The Linux kernel has a feature to autoload modules when a device is first +accessed. +And udev has a feature to set the permissions of static nodes correctly +when it is starting up and also to automatically create nodes when hardware +is hotplugged. That leaves universal device files which are not linked to +one specific hardware device. These we have to create." + (let ((devname-name (string-append linux-release-module-directory "/" + "modules.devname"))) + (for-each create-device-node + (call-with-input-file devname-name + read-static-device-nodes)))) + (define* (make-essential-device-nodes #:key (root "/")) "Make essential device nodes under ROOT/dev." ;; The hand-made devtmpfs/udev! -- cgit v1.2.3 From 2ca712bdbae5551a270c17522da20e8cb84a29cf Mon Sep 17 00:00:00 2001 From: Leo Famulari Date: Sat, 2 Dec 2017 20:17:45 -0500 Subject: vm: Pass the host's /dev/urandom to the guest at /dev/hwrng. * gnu/build/vm.scm (load-in-linux-vm): Use QEMU's virtio-rng-pci. * gnu/system/vm.scm (common-qemu-options): Likewise. --- gnu/build/vm.scm | 4 +++- gnu/system/vm.scm | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index 8f8ca609f2..404f324045 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès ;;; Copyright © 2016 Christopher Allan Webber -;;; Copyright © 2016 Leo Famulari +;;; Copyright © 2016, 2017 Leo Famulari ;;; Copyright © 2017 Mathieu Othacehe ;;; Copyright © 2017 Marius Bakke ;;; @@ -139,6 +139,8 @@ the #:references-graphs parameter of 'derivation'." (unless (zero? (apply system* qemu "-nographic" "-no-reboot" "-m" (number->string memory-size) + "-object" "rng-random,filename=/dev/urandom,id=guixsd-vm-rng" + "-device" "virtio-rng-pci,rng=guixsd-vm-rng" "-virtfs" (string-append "local,id=store_dev,path=" (%store-directory) diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm index c1305d3f9e..53629daa90 100644 --- a/gnu/system/vm.scm +++ b/gnu/system/vm.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès ;;; Copyright © 2016 Christopher Allan Webber -;;; Copyright © 2016 Leo Famulari +;;; Copyright © 2016, 2017 Leo Famulari ;;; Copyright © 2017 Mathieu Othacehe ;;; Copyright © 2017 Marius Bakke ;;; @@ -666,6 +666,8 @@ with '-virtfs' options for the host file systems listed in SHARED-FS." "-no-reboot" "-net nic,model=virtio" + "-object" "rng-random,filename=/dev/urandom,id=guixsd-vm-rng" + "-device" "virtio-rng-pci,rng=guixsd-vm-rng" #$@(map virtfs-option shared-fs) "-vga std" -- cgit v1.2.3