gnu: Add kernel-module-loader-service.

* doc/guix.texi (Linux Services): Add a new subsection and document the
new service and its configuration.
* gnu/services/linux.scm (kernel-module-loader-service-type): New type.
(kernel-module-loader-shepherd-service): New procedure.
* gnu/tests/linux-modules.scm (module-loader-program): Procedure
removed.
(modules-loaded?-program): New procedure.
(run-loadable-kernel-modules-test): 'module-loader-program' procedure
replaced by the new one.
[os]: Use 'kernel-module-loader-service'.

Signed-off-by: Danny Milosavljevic <dannym@scratchpost.org>
This commit is contained in:
Brice Waegeneire 2020-04-05 07:28:03 +02:00 committed by Danny Milosavljevic
parent 8c88e24229
commit 044d1478c9
No known key found for this signature in database
GPG key ID: E71A35542C30BAA5
3 changed files with 125 additions and 14 deletions

View file

@ -76,6 +76,7 @@ Copyright @copyright{} 2020 Damien Cassou@*
Copyright @copyright{} 2020 Jakub Kądziołka@* Copyright @copyright{} 2020 Jakub Kądziołka@*
Copyright @copyright{} 2020 Jack Hill@* Copyright @copyright{} 2020 Jack Hill@*
Copyright @copyright{} 2020 Naga Malleswari@* Copyright @copyright{} 2020 Naga Malleswari@*
Copyright @copyright{} 2020 Brice Waegeneire@*
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or under the terms of the GNU Free Documentation License, Version 1.3 or
@ -25383,6 +25384,42 @@ notifications.
@end table @end table
@end deftp @end deftp
@cindex modprobe
@cindex kernel module loader
@subsubsection Kernel Module Loader Service
The kernel module loader service allows one to load loadable kernel
modules at boot. This is especially useful for modules that don't
autoload and need to be manually loaded, as it's the case with
@code{ddcci}.
@deffn {Scheme Variable} kernel-module-loader-service-type
The service type for loading loadable kernel modules at boot with
@command{modprobe}. Its value must be a list of strings representing
module names. For example loading the drivers provided by
@code{ddcci-driver-linux}, in debugging mode by passing some module
parameters, can be done as follow:
@lisp
(use-modules (gnu) (gnu services))
(use-package-modules linux)
(use-service-modules linux)
(define ddcci-config
(plain-file "ddcci.conf"
"options ddcci dyndbg delay=120"))
(operating-system
...
(services (cons* (service kernel-module-loader-service-type
'("ddcci" "ddcci_backlight"))
(simple-service 'ddcci-config etc-service-type
(list `("modprobe.d/ddcci.conf"
,ddcci-config)))
%base-services))
(kernel-loadable-modules (list ddcci-driver-linux)))
@end lisp
@end deffn
@node Miscellaneous Services @node Miscellaneous Services
@subsection Miscellaneous Services @subsection Miscellaneous Services

View file

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -25,6 +26,8 @@ (define-module (gnu services linux)
#:use-module (gnu packages linux) #:use-module (gnu packages linux)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-26) #:use-module (srfi srfi-26)
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-35)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:export (earlyoom-configuration #:export (earlyoom-configuration
earlyoom-configuration? earlyoom-configuration?
@ -37,7 +40,9 @@ (define-module (gnu services linux)
earlyoom-configuration-ignore-positive-oom-score-adj? earlyoom-configuration-ignore-positive-oom-score-adj?
earlyoom-configuration-show-debug-messages? earlyoom-configuration-show-debug-messages?
earlyoom-configuration-send-notification-command earlyoom-configuration-send-notification-command
earlyoom-service-type)) earlyoom-service-type
kernel-module-loader-service-type))
;;; ;;;
@ -123,3 +128,53 @@ (define earlyoom-service-type
(list (service-extension shepherd-root-service-type (list (service-extension shepherd-root-service-type
(compose list earlyoom-shepherd-service)))) (compose list earlyoom-shepherd-service))))
(description "Run @command{earlyoom}, the Early OOM daemon."))) (description "Run @command{earlyoom}, the Early OOM daemon.")))
;;;
;;; Kernel module loader.
;;;
(define kernel-module-loader-shepherd-service
(match-lambda
((and (? list? kernel-modules) ((? string?) ...))
(list
(shepherd-service
(documentation "Load kernel modules.")
(provision '(kernel-module-loader))
(requirement '(file-systems))
(respawn? #f)
(one-shot? #t)
(modules `((srfi srfi-1)
(srfi srfi-34)
(srfi srfi-35)
(rnrs io ports)
,@%default-modules))
(start
#~(lambda _
(cond
((null? '#$kernel-modules) #t)
((file-exists? "/proc/sys/kernel/modprobe")
(let ((modprobe (call-with-input-file
"/proc/sys/kernel/modprobe" get-line)))
(guard (c ((message-condition? c)
(format (current-error-port) "~a~%"
(condition-message c))
#f))
(every (lambda (module)
(invoke/quiet modprobe "--" module))
'#$kernel-modules))))
(else
(format (current-error-port) "error: ~a~%"
"Kernel is missing loadable module support.")
#f)))))))))
(define kernel-module-loader-service-type
(service-type
(name 'kernel-module-loader)
(description "Load kernel modules.")
(extensions
(list (service-extension shepherd-root-service-type
kernel-module-loader-shepherd-service)))
(compose concatenate)
(extend append)
(default-value '())))

View file

@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org> ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org> ;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -19,6 +20,8 @@
(define-module (gnu tests linux-modules) (define-module (gnu tests linux-modules)
#:use-module (gnu packages linux) #:use-module (gnu packages linux)
#:use-module (gnu services)
#:use-module (gnu services linux)
#:use-module (gnu system) #:use-module (gnu system)
#:use-module (gnu system vm) #:use-module (gnu system vm)
#:use-module (gnu tests) #:use-module (gnu tests)
@ -37,25 +40,40 @@ (define-module (gnu tests linux-modules)
;;; ;;;
;;; Code: ;;; Code:
(define* (module-loader-program os modules) (define* (modules-loaded?-program os modules)
"Return an executable store item that, upon being evaluated, will dry-run "Return an executable store item that, upon being evaluated, will verify
load MODULES." that MODULES are actually loaded."
(program-file (program-file
"load-kernel-modules.scm" "verify-kernel-modules-loaded.scm"
(with-imported-modules (source-module-closure '((guix build utils))) #~(begin
#~(begin (use-modules (ice-9 rdelim)
(use-modules (guix build utils)) (ice-9 popen)
(for-each (lambda (module) (srfi srfi-1)
(invoke (string-append #$kmod "/bin/modprobe") "-n" "--" (srfi srfi-13))
module)) (let* ((port (open-input-pipe (string-append #$kmod "/bin/lsmod")))
'#$modules))))) (lines (string-split (read-string port) #\newline))
(separators (char-set #\space #\tab))
(modules (map (lambda (line)
(string-take line
(or (string-index line separators)
0)))
lines))
(status (close-pipe port)))
(and (= status 0)
(and-map (lambda (module)
(member module modules string=?))
'#$modules))))))
(define* (run-loadable-kernel-modules-test module-packages module-names) (define* (run-loadable-kernel-modules-test module-packages module-names)
"Run a test of an OS having MODULE-PACKAGES, and modprobe MODULE-NAMES." "Run a test of an OS having MODULE-PACKAGES, and verify that MODULE-NAMES
are loaded in memory."
(define os (define os
(marionette-operating-system (marionette-operating-system
(operating-system (operating-system
(inherit (simple-operating-system)) (inherit (simple-operating-system))
(services (cons (service kernel-module-loader-service-type module-names)
(operating-system-user-services
(simple-operating-system))))
(kernel-loadable-modules module-packages)) (kernel-loadable-modules module-packages))
#:imported-modules '((guix combinators)))) #:imported-modules '((guix combinators))))
(define vm (virtual-machine os)) (define vm (virtual-machine os))
@ -75,7 +93,8 @@ (define marionette
marionette)) marionette))
(test-end) (test-end)
(exit (= (test-runner-fail-count (test-runner-current)) 0))))) (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
(gexp->derivation "loadable-kernel-modules" (test (module-loader-program os module-names)))) (gexp->derivation "loadable-kernel-modules"
(test (modules-loaded?-program os module-names))))
(define %test-loadable-kernel-modules-0 (define %test-loadable-kernel-modules-0
(system-test (system-test