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 Jack Hill@*
Copyright @copyright{} 2020 Naga Malleswari@*
Copyright @copyright{} 2020 Brice Waegeneire@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@ -25383,6 +25384,42 @@ notifications.
@end table
@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
@subsection Miscellaneous Services

View file

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;;
;;; This file is part of GNU Guix.
;;;
@ -25,6 +26,8 @@ (define-module (gnu services linux)
#:use-module (gnu packages linux)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-35)
#:use-module (ice-9 match)
#:export (earlyoom-configuration
earlyoom-configuration?
@ -37,7 +40,9 @@ (define-module (gnu services linux)
earlyoom-configuration-ignore-positive-oom-score-adj?
earlyoom-configuration-show-debug-messages?
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
(compose list earlyoom-shepherd-service))))
(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
;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;;
;;; This file is part of GNU Guix.
;;;
@ -19,6 +20,8 @@
(define-module (gnu tests linux-modules)
#:use-module (gnu packages linux)
#:use-module (gnu services)
#:use-module (gnu services linux)
#:use-module (gnu system)
#:use-module (gnu system vm)
#:use-module (gnu tests)
@ -37,25 +40,40 @@ (define-module (gnu tests linux-modules)
;;;
;;; Code:
(define* (module-loader-program os modules)
"Return an executable store item that, upon being evaluated, will dry-run
load MODULES."
(define* (modules-loaded?-program os modules)
"Return an executable store item that, upon being evaluated, will verify
that MODULES are actually loaded."
(program-file
"load-kernel-modules.scm"
(with-imported-modules (source-module-closure '((guix build utils)))
#~(begin
(use-modules (guix build utils))
(for-each (lambda (module)
(invoke (string-append #$kmod "/bin/modprobe") "-n" "--"
module))
'#$modules)))))
"verify-kernel-modules-loaded.scm"
#~(begin
(use-modules (ice-9 rdelim)
(ice-9 popen)
(srfi srfi-1)
(srfi srfi-13))
(let* ((port (open-input-pipe (string-append #$kmod "/bin/lsmod")))
(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)
"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
(marionette-operating-system
(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))
#:imported-modules '((guix combinators))))
(define vm (virtual-machine os))
@ -75,7 +93,8 @@ (define marionette
marionette))
(test-end)
(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
(system-test