virtualization.scm 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2017 Ryan Moe <ryan.moe@gmail.com>
  3. ;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (gnu services virtualization)
  20. #:use-module (gnu services)
  21. #:use-module (gnu services configuration)
  22. #:use-module (gnu services base)
  23. #:use-module (gnu services dbus)
  24. #:use-module (gnu services shepherd)
  25. #:use-module (gnu system shadow)
  26. #:use-module (gnu system file-systems)
  27. #:use-module (gnu packages admin)
  28. #:use-module (gnu packages virtualization)
  29. #:use-module (guix records)
  30. #:use-module (guix gexp)
  31. #:use-module (guix packages)
  32. #:use-module (srfi srfi-9)
  33. #:use-module (srfi srfi-26)
  34. #:use-module (rnrs bytevectors)
  35. #:use-module (ice-9 match)
  36. #:export (libvirt-configuration
  37. libvirt-service-type
  38. virtlog-configuration
  39. virtlog-service-type
  40. %qemu-platforms
  41. lookup-qemu-platforms
  42. qemu-platform?
  43. qemu-platform-name
  44. qemu-binfmt-configuration
  45. qemu-binfmt-configuration?
  46. qemu-binfmt-service-type))
  47. (define (uglify-field-name field-name)
  48. (let ((str (symbol->string field-name)))
  49. (string-join
  50. (string-split (string-delete #\? str) #\-)
  51. "_")))
  52. (define (quote-val val)
  53. (string-append "\"" val "\""))
  54. (define (serialize-field field-name val)
  55. (format #t "~a = ~a\n" (uglify-field-name field-name) val))
  56. (define (serialize-string field-name val)
  57. (serialize-field field-name (quote-val val)))
  58. (define (serialize-boolean field-name val)
  59. (serialize-field field-name (if val 1 0)))
  60. (define (serialize-integer field-name val)
  61. (serialize-field field-name val))
  62. (define (build-opt-list val)
  63. (string-append
  64. "["
  65. (string-join (map quote-val val) ",")
  66. "]"))
  67. (define optional-list? list?)
  68. (define optional-string? string?)
  69. (define (serialize-list field-name val)
  70. (serialize-field field-name (build-opt-list val)))
  71. (define (serialize-optional-list field-name val)
  72. (if (null? val)
  73. (format #t "# ~a = []\n" (uglify-field-name field-name))
  74. (serialize-list field-name val)))
  75. (define (serialize-optional-string field-name val)
  76. (if (string-null? val)
  77. (format #t "# ~a = \"\"\n" (uglify-field-name field-name))
  78. (serialize-string field-name val)))
  79. (define-configuration libvirt-configuration
  80. (libvirt
  81. (package libvirt)
  82. "Libvirt package.")
  83. (listen-tls?
  84. (boolean #t)
  85. "Flag listening for secure TLS connections on the public TCP/IP port.
  86. must set @code{listen} for this to have any effect.
  87. It is necessary to setup a CA and issue server certificates before
  88. using this capability.")
  89. (listen-tcp?
  90. (boolean #f)
  91. "Listen for unencrypted TCP connections on the public TCP/IP port.
  92. must set @code{listen} for this to have any effect.
  93. Using the TCP socket requires SASL authentication by default. Only
  94. SASL mechanisms which support data encryption are allowed. This is
  95. DIGEST_MD5 and GSSAPI (Kerberos5)")
  96. (tls-port
  97. (string "16514")
  98. "Port for accepting secure TLS connections This can be a port number,
  99. or service name")
  100. (tcp-port
  101. (string "16509")
  102. "Port for accepting insecure TCP connections This can be a port number,
  103. or service name")
  104. (listen-addr
  105. (string "0.0.0.0")
  106. "IP address or hostname used for client connections.")
  107. (mdns-adv?
  108. (boolean #f)
  109. "Flag toggling mDNS advertisement of the libvirt service.
  110. Alternatively can disable for all services on a host by
  111. stopping the Avahi daemon.")
  112. (mdns-name
  113. (string (string-append "Virtualization Host " (gethostname)))
  114. "Default mDNS advertisement name. This must be unique on the
  115. immediate broadcast network.")
  116. (unix-sock-group
  117. (string "root")
  118. "UNIX domain socket group ownership. This can be used to
  119. allow a 'trusted' set of users access to management capabilities
  120. without becoming root.")
  121. (unix-sock-ro-perms
  122. (string "0777")
  123. "UNIX socket permissions for the R/O socket. This is used
  124. for monitoring VM status only.")
  125. (unix-sock-rw-perms
  126. (string "0770")
  127. "UNIX socket permissions for the R/W socket. Default allows
  128. only root. If PolicyKit is enabled on the socket, the default
  129. will change to allow everyone (eg, 0777)")
  130. (unix-sock-admin-perms
  131. (string "0777")
  132. "UNIX socket permissions for the admin socket. Default allows
  133. only owner (root), do not change it unless you are sure to whom
  134. you are exposing the access to.")
  135. (unix-sock-dir
  136. (string "/var/run/libvirt")
  137. "The directory in which sockets will be found/created.")
  138. (auth-unix-ro
  139. (string "polkit")
  140. "Authentication scheme for UNIX read-only sockets. By default
  141. socket permissions allow anyone to connect")
  142. (auth-unix-rw
  143. (string "polkit")
  144. "Authentication scheme for UNIX read-write sockets. By default
  145. socket permissions only allow root. If PolicyKit support was compiled
  146. into libvirt, the default will be to use 'polkit' auth.")
  147. (auth-tcp
  148. (string "sasl")
  149. "Authentication scheme for TCP sockets. If you don't enable SASL,
  150. then all TCP traffic is cleartext. Don't do this outside of a dev/test
  151. scenario.")
  152. (auth-tls
  153. (string "none")
  154. "Authentication scheme for TLS sockets. TLS sockets already have
  155. encryption provided by the TLS layer, and limited authentication is
  156. done by certificates.
  157. It is possible to make use of any SASL authentication mechanism as
  158. well, by using 'sasl' for this option")
  159. (access-drivers
  160. (optional-list '())
  161. "API access control scheme.
  162. By default an authenticated user is allowed access to all APIs. Access
  163. drivers can place restrictions on this.")
  164. (key-file
  165. (string "")
  166. "Server key file path. If set to an empty string, then no private key
  167. is loaded.")
  168. (cert-file
  169. (string "")
  170. "Server key file path. If set to an empty string, then no certificate
  171. is loaded.")
  172. (ca-file
  173. (string "")
  174. "Server key file path. If set to an empty string, then no CA certificate
  175. is loaded.")
  176. (crl-file
  177. (string "")
  178. "Certificate revocation list path. If set to an empty string, then no
  179. CRL is loaded.")
  180. (tls-no-sanity-cert
  181. (boolean #f)
  182. "Disable verification of our own server certificates.
  183. When libvirtd starts it performs some sanity checks against its own
  184. certificates.")
  185. (tls-no-verify-cert
  186. (boolean #f)
  187. "Disable verification of client certificates.
  188. Client certificate verification is the primary authentication mechanism.
  189. Any client which does not present a certificate signed by the CA
  190. will be rejected.")
  191. (tls-allowed-dn-list
  192. (optional-list '())
  193. "Whitelist of allowed x509 Distinguished Name.")
  194. (sasl-allowed-usernames
  195. (optional-list '())
  196. "Whitelist of allowed SASL usernames. The format for username
  197. depends on the SASL authentication mechanism.")
  198. (tls-priority
  199. (string "NORMAL")
  200. "Override the compile time default TLS priority string. The
  201. default is usually \"NORMAL\" unless overridden at build time.
  202. Only set this is it is desired for libvirt to deviate from
  203. the global default settings.")
  204. (max-clients
  205. (integer 5000)
  206. "Maximum number of concurrent client connections to allow
  207. over all sockets combined.")
  208. (max-queued-clients
  209. (integer 1000)
  210. "Maximum length of queue of connections waiting to be
  211. accepted by the daemon. Note, that some protocols supporting
  212. retransmission may obey this so that a later reattempt at
  213. connection succeeds.")
  214. (max-anonymous-clients
  215. (integer 20)
  216. "Maximum length of queue of accepted but not yet authenticated
  217. clients. Set this to zero to turn this feature off")
  218. (min-workers
  219. (integer 5)
  220. "Number of workers to start up initially.")
  221. (max-workers
  222. (integer 20)
  223. "Maximum number of worker threads.
  224. If the number of active clients exceeds @code{min-workers},
  225. then more threads are spawned, up to max_workers limit.
  226. Typically you'd want max_workers to equal maximum number
  227. of clients allowed.")
  228. (prio-workers
  229. (integer 5)
  230. "Number of priority workers. If all workers from above
  231. pool are stuck, some calls marked as high priority
  232. (notably domainDestroy) can be executed in this pool.")
  233. (max-requests
  234. (integer 20)
  235. "Total global limit on concurrent RPC calls.")
  236. (max-client-requests
  237. (integer 5)
  238. "Limit on concurrent requests from a single client
  239. connection. To avoid one client monopolizing the server
  240. this should be a small fraction of the global max_requests
  241. and max_workers parameter.")
  242. (admin-min-workers
  243. (integer 1)
  244. "Same as @code{min-workers} but for the admin interface.")
  245. (admin-max-workers
  246. (integer 5)
  247. "Same as @code{max-workers} but for the admin interface.")
  248. (admin-max-clients
  249. (integer 5)
  250. "Same as @code{max-clients} but for the admin interface.")
  251. (admin-max-queued-clients
  252. (integer 5)
  253. "Same as @code{max-queued-clients} but for the admin interface.")
  254. (admin-max-client-requests
  255. (integer 5)
  256. "Same as @code{max-client-requests} but for the admin interface.")
  257. (log-level
  258. (integer 3)
  259. "Logging level. 4 errors, 3 warnings, 2 information, 1 debug.")
  260. (log-filters
  261. (string "3:remote 4:event")
  262. "Logging filters.
  263. A filter allows to select a different logging level for a given category
  264. of logs
  265. The format for a filter is one of:
  266. @itemize
  267. @item x:name
  268. @item x:+name
  269. @end itemize
  270. where @code{name} is a string which is matched against the category
  271. given in the @code{VIR_LOG_INIT()} at the top of each libvirt source
  272. file, e.g., \"remote\", \"qemu\", or \"util.json\" (the name in the
  273. filter can be a substring of the full category name, in order
  274. to match multiple similar categories), the optional \"+\" prefix
  275. tells libvirt to log stack trace for each message matching
  276. name, and @code{x} is the minimal level where matching messages should
  277. be logged:
  278. @itemize
  279. @item 1: DEBUG
  280. @item 2: INFO
  281. @item 3: WARNING
  282. @item 4: ERROR
  283. @end itemize
  284. Multiple filters can be defined in a single filters statement, they just
  285. need to be separated by spaces.")
  286. (log-outputs
  287. (string "3:stderr")
  288. "Logging outputs.
  289. An output is one of the places to save logging information
  290. The format for an output can be:
  291. @table @code
  292. @item x:stderr
  293. output goes to stderr
  294. @item x:syslog:name
  295. use syslog for the output and use the given name as the ident
  296. @item x:file:file_path
  297. output to a file, with the given filepath
  298. @item x:journald
  299. output to journald logging system
  300. @end table
  301. In all case the x prefix is the minimal level, acting as a filter
  302. @itemize
  303. @item 1: DEBUG
  304. @item 2: INFO
  305. @item 3: WARNING
  306. @item 4: ERROR
  307. @end itemize
  308. Multiple outputs can be defined, they just need to be separated by spaces.")
  309. (audit-level
  310. (integer 1)
  311. "Allows usage of the auditing subsystem to be altered
  312. @itemize
  313. @item 0: disable all auditing
  314. @item 1: enable auditing, only if enabled on host
  315. @item 2: enable auditing, and exit if disabled on host.
  316. @end itemize
  317. ")
  318. (audit-logging
  319. (boolean #f)
  320. "Send audit messages via libvirt logging infrastructure.")
  321. (host-uuid
  322. (optional-string "")
  323. "Host UUID. UUID must not have all digits be the same.")
  324. (host-uuid-source
  325. (string "smbios")
  326. "Source to read host UUID.
  327. @itemize
  328. @item @code{smbios}: fetch the UUID from @code{dmidecode -s system-uuid}
  329. @item @code{machine-id}: fetch the UUID from @code{/etc/machine-id}
  330. @end itemize
  331. If @code{dmidecode} does not provide a valid UUID a temporary UUID
  332. will be generated.")
  333. (keepalive-interval
  334. (integer 5)
  335. "A keepalive message is sent to a client after
  336. @code{keepalive_interval} seconds of inactivity to check if
  337. the client is still responding. If set to -1, libvirtd will
  338. never send keepalive requests; however clients can still send
  339. them and the daemon will send responses.")
  340. (keepalive-count
  341. (integer 5)
  342. "Maximum number of keepalive messages that are allowed to be sent
  343. to the client without getting any response before the connection is
  344. considered broken.
  345. In other words, the connection is automatically
  346. closed approximately after
  347. @code{keepalive_interval * (keepalive_count + 1)} seconds since the last
  348. message received from the client. When @code{keepalive-count} is
  349. set to 0, connections will be automatically closed after
  350. @code{keepalive-interval} seconds of inactivity without sending any
  351. keepalive messages.")
  352. (admin-keepalive-interval
  353. (integer 5)
  354. "Same as above but for admin interface.")
  355. (admin-keepalive-count
  356. (integer 5)
  357. "Same as above but for admin interface.")
  358. (ovs-timeout
  359. (integer 5)
  360. "Timeout for Open vSwitch calls.
  361. The @code{ovs-vsctl} utility is used for the configuration and
  362. its timeout option is set by default to 5 seconds to avoid
  363. potential infinite waits blocking libvirt."))
  364. (define* (libvirt-conf-file config)
  365. "Return a libvirtd config file."
  366. (plain-file "libvirtd.conf"
  367. (with-output-to-string
  368. (lambda ()
  369. (serialize-configuration config libvirt-configuration-fields)))))
  370. (define %libvirt-accounts
  371. (list (user-group (name "libvirt") (system? #t))))
  372. (define (%libvirt-activation config)
  373. (let ((sock-dir (libvirt-configuration-unix-sock-dir config)))
  374. #~(begin
  375. (use-modules (guix build utils))
  376. (mkdir-p #$sock-dir))))
  377. (define (libvirt-shepherd-service config)
  378. (let* ((config-file (libvirt-conf-file config))
  379. (libvirt (libvirt-configuration-libvirt config)))
  380. (list (shepherd-service
  381. (documentation "Run the libvirt daemon.")
  382. (provision '(libvirtd))
  383. (start #~(make-forkexec-constructor
  384. (list (string-append #$libvirt "/sbin/libvirtd")
  385. "-f" #$config-file)))
  386. (stop #~(make-kill-destructor))))))
  387. (define libvirt-service-type
  388. (service-type (name 'libvirt)
  389. (extensions
  390. (list
  391. (service-extension polkit-service-type
  392. (compose list libvirt-configuration-libvirt))
  393. (service-extension profile-service-type
  394. (compose list
  395. libvirt-configuration-libvirt))
  396. (service-extension activation-service-type
  397. %libvirt-activation)
  398. (service-extension shepherd-root-service-type
  399. libvirt-shepherd-service)
  400. (service-extension account-service-type
  401. (const %libvirt-accounts))))
  402. (default-value (libvirt-configuration))))
  403. (define-record-type* <virtlog-configuration>
  404. virtlog-configuration make-virtlog-configuration
  405. virtlog-configuration?
  406. (libvirt virtlog-configuration-libvirt
  407. (default libvirt))
  408. (log-level virtlog-configuration-log-level
  409. (default 3))
  410. (log-filters virtlog-configuration-log-filters
  411. (default "3:remote 4:event"))
  412. (log-outputs virtlog-configuration-log-outputs
  413. (default "3:syslog:virtlogd"))
  414. (max-clients virtlog-configuration-max-clients
  415. (default 1024))
  416. (max-size virtlog-configuration-max-size
  417. (default 2097152)) ;; 2MB
  418. (max-backups virtlog-configuration-max-backups
  419. (default 3)))
  420. (define* (virtlogd-conf-file config)
  421. "Return a virtlogd config file."
  422. (plain-file "virtlogd.conf"
  423. (string-append
  424. "log_level = " (number->string (virtlog-configuration-log-level config)) "\n"
  425. "log_filters = \"" (virtlog-configuration-log-filters config) "\"\n"
  426. "log_outputs = \"" (virtlog-configuration-log-outputs config) "\"\n"
  427. "max_clients = " (number->string (virtlog-configuration-max-clients config)) "\n"
  428. "max_size = " (number->string (virtlog-configuration-max-size config)) "\n"
  429. "max_backups = " (number->string (virtlog-configuration-max-backups config)) "\n")))
  430. (define (virtlogd-shepherd-service config)
  431. (let* ((config-file (virtlogd-conf-file config))
  432. (libvirt (virtlog-configuration-libvirt config)))
  433. (list (shepherd-service
  434. (documentation "Run the virtlog daemon.")
  435. (provision '(virtlogd))
  436. (start #~(make-forkexec-constructor
  437. (list (string-append #$libvirt "/sbin/virtlogd")
  438. "-f" #$config-file)))
  439. (stop #~(make-kill-destructor))))))
  440. (define virtlog-service-type
  441. (service-type (name 'virtlogd)
  442. (extensions
  443. (list
  444. (service-extension shepherd-root-service-type
  445. virtlogd-shepherd-service)))
  446. (default-value (virtlog-configuration))))
  447. (define (generate-libvirt-documentation)
  448. (generate-documentation
  449. `((libvirt-configuration ,libvirt-configuration-fields))
  450. 'libvirt-configuration))
  451. ;;;
  452. ;;; Transparent QEMU emulation via binfmt_misc.
  453. ;;;
  454. ;; Platforms that QEMU can emulate.
  455. (define-record-type <qemu-platform>
  456. (qemu-platform name family magic mask)
  457. qemu-platform?
  458. (name qemu-platform-name) ;string
  459. (family qemu-platform-family) ;string
  460. (magic qemu-platform-magic) ;bytevector
  461. (mask qemu-platform-mask)) ;bytevector
  462. (define-syntax bv
  463. (lambda (s)
  464. "Expand the given string into a bytevector."
  465. (syntax-case s ()
  466. ((_ str)
  467. (string? (syntax->datum #'str))
  468. (let ((bv (u8-list->bytevector
  469. (map char->integer
  470. (string->list (syntax->datum #'str))))))
  471. bv)))))
  472. ;;; The platform descriptions below are taken from
  473. ;;; 'scripts/qemu-binfmt-conf.sh' in QEMU.
  474. (define %i386
  475. (qemu-platform "i386" "i386"
  476. (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00")
  477. (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  478. (define %i486
  479. (qemu-platform "i486" "i386"
  480. (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00")
  481. (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  482. (define %alpha
  483. (qemu-platform "alpha" "alpha"
  484. (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90")
  485. (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  486. (define %arm
  487. (qemu-platform "arm" "arm"
  488. (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00")
  489. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  490. (define %armeb
  491. (qemu-platform "armeb" "arm"
  492. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28")
  493. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  494. (define %sparc
  495. (qemu-platform "sparc" "sparc"
  496. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02")
  497. (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  498. (define %sparc32plus
  499. (qemu-platform "sparc32plus" "sparc"
  500. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12")
  501. (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  502. (define %ppc
  503. (qemu-platform "ppc" "ppc"
  504. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14")
  505. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  506. (define %ppc64
  507. (qemu-platform "ppc64" "ppc"
  508. (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15")
  509. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  510. (define %ppc64le
  511. (qemu-platform "ppc64le" "ppcle"
  512. (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00")
  513. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00")))
  514. (define %m68k
  515. (qemu-platform "m68k" "m68k"
  516. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04")
  517. (bv "\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  518. ;; XXX: We could use the other endianness on a MIPS host.
  519. (define %mips
  520. (qemu-platform "mips" "mips"
  521. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08")
  522. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  523. (define %mipsel
  524. (qemu-platform "mipsel" "mips"
  525. (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00")
  526. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  527. (define %mipsn32
  528. (qemu-platform "mipsn32" "mips"
  529. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08")
  530. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  531. (define %mipsn32el
  532. (qemu-platform "mipsn32el" "mips"
  533. (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00")
  534. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  535. (define %mips64
  536. (qemu-platform "mips64" "mips"
  537. (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08")
  538. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  539. (define %mips64el
  540. (qemu-platform "mips64el" "mips"
  541. (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00")
  542. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  543. (define %sh4
  544. (qemu-platform "sh4" "sh4"
  545. (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00")
  546. (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  547. (define %sh4eb
  548. (qemu-platform "sh4eb" "sh4"
  549. (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a")
  550. (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  551. (define %s390x
  552. (qemu-platform "s390x" "s390x"
  553. (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16")
  554. (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  555. (define %aarch64
  556. (qemu-platform "aarch64" "arm"
  557. (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00")
  558. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff")))
  559. (define %hppa
  560. (qemu-platform "hppa" "hppa"
  561. (bv "\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f")
  562. (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff")))
  563. (define %qemu-platforms
  564. (list %i386 %i486 %alpha %arm %sparc32plus %ppc %ppc64 %ppc64le %m68k
  565. %mips %mipsel %mipsn32 %mipsn32el %mips64 %mips64el
  566. %sh4 %sh4eb %s390x %aarch64 %hppa))
  567. (define (lookup-qemu-platforms . names)
  568. "Return the list of QEMU platforms that match NAMES--a list of names such as
  569. \"arm\", \"hppa\", etc."
  570. (filter (lambda (platform)
  571. (member (qemu-platform-name platform) names))
  572. %qemu-platforms))
  573. (define-record-type* <qemu-binfmt-configuration>
  574. qemu-binfmt-configuration make-qemu-binfmt-configuration
  575. qemu-binfmt-configuration?
  576. (qemu qemu-binfmt-configuration-qemu
  577. (default qemu))
  578. (platforms qemu-binfmt-configuration-platforms
  579. (default '())) ;safest default
  580. (guix-support? qemu-binfmt-configuration-guix-support?
  581. (default #f)))
  582. (define (qemu-platform->binfmt qemu platform)
  583. "Return a gexp that evaluates to a binfmt string for PLATFORM, using the
  584. given QEMU package."
  585. (define (bytevector->binfmt-string bv)
  586. ;; Return a binfmt-friendly string representing BV. Hex-encode every
  587. ;; character, in particular because the doc notes "that you must escape
  588. ;; any NUL bytes; parsing halts at the first one".
  589. (string-concatenate
  590. (map (lambda (n)
  591. (string-append "\\x"
  592. (string-pad (number->string n 16) 2 #\0)))
  593. (bytevector->u8-list bv))))
  594. (match platform
  595. (($ <qemu-platform> name family magic mask)
  596. ;; See 'Documentation/binfmt_misc.txt' in the kernel.
  597. #~(string-append ":qemu-" #$name ":M::"
  598. #$(bytevector->binfmt-string magic)
  599. ":" #$(bytevector->binfmt-string mask)
  600. ":" #$(file-append qemu "/bin/qemu-" name)
  601. ":" ;FLAGS go here
  602. ))))
  603. (define %binfmt-mount-point
  604. (file-system-mount-point %binary-format-file-system))
  605. (define %binfmt-register-file
  606. (string-append %binfmt-mount-point "/register"))
  607. (define qemu-binfmt-shepherd-services
  608. (match-lambda
  609. (($ <qemu-binfmt-configuration> qemu platforms)
  610. (list (shepherd-service
  611. (provision '(qemu-binfmt))
  612. (documentation "Install binfmt_misc handlers for QEMU.")
  613. (requirement '(file-system-/proc/sys/fs/binfmt_misc))
  614. (start #~(lambda ()
  615. ;; Register the handlers for all of PLATFORMS.
  616. (for-each (lambda (str)
  617. (call-with-output-file
  618. #$%binfmt-register-file
  619. (lambda (port)
  620. (display str port))))
  621. (list
  622. #$@(map (cut qemu-platform->binfmt qemu
  623. <>)
  624. platforms)))
  625. #t))
  626. (stop #~(lambda (_)
  627. ;; Unregister the handlers.
  628. (for-each (lambda (name)
  629. (let ((file (string-append
  630. #$%binfmt-mount-point
  631. "/qemu-" name)))
  632. (call-with-output-file file
  633. (lambda (port)
  634. (display "-1" port)))))
  635. '#$(map qemu-platform-name platforms))
  636. #f)))))))
  637. (define qemu-binfmt-guix-chroot
  638. (match-lambda
  639. ;; Add QEMU and its dependencies to the guix-daemon chroot so that our
  640. ;; binfmt_misc handlers work in the chroot (otherwise 'execve' would fail
  641. ;; with ENOENT.)
  642. ;;
  643. ;; The 'F' flag of binfmt_misc is meant to address this problem by loading
  644. ;; the interpreter upfront rather than lazily, but apparently that is
  645. ;; insufficient (perhaps it loads the 'qemu-ARCH' binary upfront but looks
  646. ;; up its dependencies lazily?).
  647. (($ <qemu-binfmt-configuration> qemu platforms guix?)
  648. (if guix? (list qemu) '()))))
  649. (define qemu-binfmt-service-type
  650. ;; TODO: Make a separate binfmt_misc service out of this?
  651. (service-type (name 'qemu-binfmt)
  652. (extensions
  653. (list (service-extension file-system-service-type
  654. (const
  655. (list %binary-format-file-system)))
  656. (service-extension shepherd-root-service-type
  657. qemu-binfmt-shepherd-services)
  658. (service-extension guix-service-type
  659. qemu-binfmt-guix-chroot)))
  660. (default-value (qemu-binfmt-configuration))
  661. (description
  662. "This service supports transparent emulation of binaries
  663. compiled for other architectures using QEMU and the @code{binfmt_misc}
  664. functionality of the kernel Linux.")))