services/qemu-binfmt: Use the F flag and the static output of QEMU.

Fixes <https://issues.guix.gnu.org/36117>.

Before this change, the 'binfmt_misc' entries registered for QEMU would not be
usable in container contexts outside of guix-daemon (without manually bind
mounting file names).

For example:

$ docker run --rm arm32v7/debian true
standard_init_linux.go:207: exec user process caused "no such file or directory"

After this change, any container can make use of the QEMU binfmt_misc
registrations, as their corresponding QEMU static binaries are fully
pre-loaded by the kernel.

* gnu/services/virtualization.scm (<qemu-platform>): Define using
'define-record-type*'.
[flags]: New field, which defaults to "F" (fix binary).
(%i386, %i486, %alpha, %arm, %armeb, %sparc, %sparc32plus, %ppc, %ppc64)
(%ppc64le, %m68k, %mips, %mipsel, %mipsn32, %mipsn32el, %mips64, %mips64el)
(%riscv32, %riscv64, %sh4, %sh4eb, %s390x, %aarch64, %hppa): Adjust.
(qemu-binfmt-guix-chroot): Remove variable.
(qemu-binfmt-service-type): Remove the qemu-binfmt-guix-chroot extension.
* gnu/services/qemu-binfmt (qemu-platform->binfmt):  Use the static output of
QEMU.
* doc/contributing.texi (Submitting Patches): Update doc.
* doc/guix.texi (Virtualization Services): Update doc.
This commit is contained in:
Maxim Cournoyer 2021-02-22 08:55:39 -05:00
parent d184fd4216
commit 77c2f4e206
No known key found for this signature in database
GPG key ID: 1260E46482E63562
3 changed files with 129 additions and 111 deletions

View file

@ -1016,7 +1016,6 @@ your @code{operating-system} configuration:
(service qemu-binfmt-service-type (service qemu-binfmt-service-type
(qemu-binfmt-configuration (qemu-binfmt-configuration
(platforms (lookup-qemu-platforms "arm" "aarch64")) (platforms (lookup-qemu-platforms "arm" "aarch64"))
(guix-support? #t)))
@end lisp @end lisp
Then reconfigure your system. Then reconfigure your system.

View file

@ -28723,13 +28723,6 @@ This is the configuration for the @code{qemu-binfmt} service.
The list of emulated QEMU platforms. Each item must be a @dfn{platform The list of emulated QEMU platforms. Each item must be a @dfn{platform
object} as returned by @code{lookup-qemu-platforms} (see below). object} as returned by @code{lookup-qemu-platforms} (see below).
@item @code{guix-support?} (default: @code{#t})
When it is true, QEMU and all its dependencies are added to the build
environment of @command{guix-daemon} (@pxref{Invoking guix-daemon,
@option{--chroot-directory} option}). This allows the @code{binfmt_misc}
handlers to be used within the build environment, which in turn means
that you can transparently build programs for another architecture.
For example, let's suppose you're on an x86_64 machine and you have this For example, let's suppose you're on an x86_64 machine and you have this
service: service:
@ -28737,7 +28730,6 @@ service:
(service qemu-binfmt-service-type (service qemu-binfmt-service-type
(qemu-binfmt-configuration (qemu-binfmt-configuration
(platforms (lookup-qemu-platforms "arm")) (platforms (lookup-qemu-platforms "arm"))
(guix-support? #t)))
@end lisp @end lisp
You can run: You can run:
@ -28752,10 +28744,6 @@ build}, transparently using QEMU to emulate the ARMv7 CPU@. Pretty handy
if you'd like to test a package build for an architecture you don't have if you'd like to test a package build for an architecture you don't have
access to! access to!
When @code{guix-support?} is set to @code{#f}, programs for other
architectures can still be executed transparently, but invoking commands
like @command{guix build -s armhf-linux @dots{}} will fail.
@item @code{qemu} (default: @code{qemu}) @item @code{qemu} (default: @code{qemu})
The QEMU package to use. The QEMU package to use.
@end table @end table

View file

@ -554,13 +554,14 @@ (define (generate-libvirt-documentation)
;;; ;;;
;; Platforms that QEMU can emulate. ;; Platforms that QEMU can emulate.
(define-record-type <qemu-platform> (define-record-type* <qemu-platform>
(qemu-platform name family magic mask) qemu-platform make-qemu-platform
qemu-platform? qemu-platform?
(name qemu-platform-name) ;string (name qemu-platform-name) ;string
(family qemu-platform-family) ;string (family qemu-platform-family) ;string
(magic qemu-platform-magic) ;bytevector (magic qemu-platform-magic) ;bytevector
(mask qemu-platform-mask)) ;bytevector (mask qemu-platform-mask) ;bytevector
(flags qemu-platform-flags (default "F"))) ;string
(define-syntax bv (define-syntax bv
(lambda (s) (lambda (s)
@ -577,125 +578,173 @@ (define-syntax bv
;;; 'scripts/qemu-binfmt-conf.sh' in QEMU. ;;; 'scripts/qemu-binfmt-conf.sh' in QEMU.
(define %i386 (define %i386
(qemu-platform "i386" "i386" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00") (name "i386")
(bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "i386")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %i486 (define %i486
(qemu-platform "i486" "i386" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00") (name "i486")
(bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "i386")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %alpha (define %alpha
(qemu-platform "alpha" "alpha" (qemu-platform
(bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90") (name "alpha")
(bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "alpha")
(magic (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90"))
(mask (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %arm (define %arm
(qemu-platform "arm" "arm" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00") (name "arm")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "arm")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %armeb (define %armeb
(qemu-platform "armeb" "arm" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28") (name "armeb")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "arm")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %sparc (define %sparc
(qemu-platform "sparc" "sparc" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02") (name "sparc")
(bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "sparc")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %sparc32plus (define %sparc32plus
(qemu-platform "sparc32plus" "sparc" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12") (name "sparc32plus")
(bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "sparc")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %ppc (define %ppc
(qemu-platform "ppc" "ppc" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14") (name "ppc")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "ppc")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %ppc64 (define %ppc64
(qemu-platform "ppc64" "ppc" (qemu-platform
(bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15") (name "ppc64")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "ppc")
(magic (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %ppc64le (define %ppc64le
(qemu-platform "ppc64le" "ppcle" (qemu-platform
(bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00") (name "ppc64le")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00"))) (family "ppcle")
(magic (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00"))))
(define %m68k (define %m68k
(qemu-platform "m68k" "m68k" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04") (name "m68k")
(bv "\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "m68k")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
;; XXX: We could use the other endianness on a MIPS host. ;; XXX: We could use the other endianness on a MIPS host.
(define %mips (define %mips
(qemu-platform "mips" "mips" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08") (name "mips")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "mips")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %mipsel (define %mipsel
(qemu-platform "mipsel" "mips" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00") (name "mipsel")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "mips")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %mipsn32 (define %mipsn32
(qemu-platform "mipsn32" "mips" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08") (name "mipsn32")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "mips")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %mipsn32el (define %mipsn32el
(qemu-platform "mipsn32el" "mips" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00") (name "mipsn32el")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "mips")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %mips64 (define %mips64
(qemu-platform "mips64" "mips" (qemu-platform
(bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08") (name "mips64")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "mips")
(magic (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %mips64el (define %mips64el
(qemu-platform "mips64el" "mips" (qemu-platform
(bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00") (name "mips64el")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "mips")
(magic (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %riscv32 (define %riscv32
(qemu-platform "riscv32" "riscv" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00") (name "riscv32")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "riscv")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %riscv64 (define %riscv64
(qemu-platform "riscv64" "riscv" (qemu-platform
(bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00") (name "riscv64")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "riscv")
(magic (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %sh4 (define %sh4
(qemu-platform "sh4" "sh4" (qemu-platform
(bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00") (name "sh4")
(bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "sh4")
(magic (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %sh4eb (define %sh4eb
(qemu-platform "sh4eb" "sh4" (qemu-platform
(bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a") (name "sh4eb")
(bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "sh4")
(magic (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %s390x (define %s390x
(qemu-platform "s390x" "s390x" (qemu-platform
(bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16") (name "s390x")
(bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "s390x")
(magic (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %aarch64 (define %aarch64
(qemu-platform "aarch64" "arm" (qemu-platform
(bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00") (name "aarch64")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (family "arm")
(magic (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))))
(define %hppa (define %hppa
(qemu-platform "hppa" "hppa" (qemu-platform
(bv "\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f") (name "hppa")
(bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (family "hppa")
(magic (bv "\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f"))
(mask (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))))
(define %qemu-platforms (define %qemu-platforms
(list %i386 %i486 %alpha %arm %sparc32plus %ppc %ppc64 %ppc64le %m68k (list %i386 %i486 %alpha %arm %sparc32plus %ppc %ppc64 %ppc64le %m68k
@ -715,9 +764,7 @@ (define-record-type* <qemu-binfmt-configuration>
(qemu qemu-binfmt-configuration-qemu (qemu qemu-binfmt-configuration-qemu
(default qemu)) (default qemu))
(platforms qemu-binfmt-configuration-platforms (platforms qemu-binfmt-configuration-platforms
(default '())) ;safest default (default '()))) ;safest default
(guix-support? qemu-binfmt-configuration-guix-support?
(default #t)))
(define (qemu-platform->binfmt qemu platform) (define (qemu-platform->binfmt qemu platform)
"Return a gexp that evaluates to a binfmt string for PLATFORM, using the "Return a gexp that evaluates to a binfmt string for PLATFORM, using the
@ -733,14 +780,13 @@ (define (bytevector->binfmt-string bv)
(bytevector->u8-list bv)))) (bytevector->u8-list bv))))
(match platform (match platform
(($ <qemu-platform> name family magic mask) (($ <qemu-platform> name family magic mask flags)
;; See 'Documentation/binfmt_misc.txt' in the kernel. ;; See 'Documentation/binfmt_misc.txt' in the kernel.
#~(string-append ":qemu-" #$name ":M::" #~(string-append ":qemu-" #$name ":M::"
#$(bytevector->binfmt-string magic) #$(bytevector->binfmt-string magic)
":" #$(bytevector->binfmt-string mask) ":" #$(bytevector->binfmt-string mask)
":" #$(file-append qemu "/bin/qemu-" name) ":" #$qemu:static "/bin/qemu-" #$name
":" ;FLAGS go here ":" #$flags))))
))))
(define %binfmt-mount-point (define %binfmt-mount-point
(file-system-mount-point %binary-format-file-system)) (file-system-mount-point %binary-format-file-system))
@ -779,19 +825,6 @@ (define qemu-binfmt-shepherd-services
'#$(map qemu-platform-name platforms)) '#$(map qemu-platform-name platforms))
#f))))))) #f)))))))
(define qemu-binfmt-guix-chroot
(match-lambda
;; Add QEMU and its dependencies to the guix-daemon chroot so that our
;; binfmt_misc handlers work in the chroot (otherwise 'execve' would fail
;; with ENOENT.)
;;
;; The 'F' flag of binfmt_misc is meant to address this problem by loading
;; the interpreter upfront rather than lazily, but apparently that is
;; insufficient (perhaps it loads the 'qemu-ARCH' binary upfront but looks
;; up its dependencies lazily?).
(($ <qemu-binfmt-configuration> qemu platforms guix?)
(if guix? (list qemu) '()))))
(define qemu-binfmt-service-type (define qemu-binfmt-service-type
;; TODO: Make a separate binfmt_misc service out of this? ;; TODO: Make a separate binfmt_misc service out of this?
(service-type (name 'qemu-binfmt) (service-type (name 'qemu-binfmt)
@ -800,9 +833,7 @@ (define qemu-binfmt-service-type
(const (const
(list %binary-format-file-system))) (list %binary-format-file-system)))
(service-extension shepherd-root-service-type (service-extension shepherd-root-service-type
qemu-binfmt-shepherd-services) qemu-binfmt-shepherd-services)))
(service-extension guix-service-type
qemu-binfmt-guix-chroot)))
(default-value (qemu-binfmt-configuration)) (default-value (qemu-binfmt-configuration))
(description (description
"This service supports transparent emulation of binaries "This service supports transparent emulation of binaries