From: Brice Waegeneire <brice@waegenei.re>
To: 42193@debbugs.gnu.org
Subject: [bug#42193] [WIP 6/6] WIP services: Add kernel-module-configuration service.
Date: Sat, 4 Jul 2020 20:54:31 +0200 [thread overview]
Message-ID: <20200704185431.13739-7-brice@waegenei.re> (raw)
In-Reply-To: <20200704185234.12571-1-brice@waegenei.re>
---
gnu/services/linux.scm | 166 +++++++++++++++++++++++++++++++++++-
gnu/tests/linux-modules.scm | 67 +++++++++------
2 files changed, 208 insertions(+), 25 deletions(-)
diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm
index 7ea30a1270..9773dd5072 100644
--- a/gnu/services/linux.scm
+++ b/gnu/services/linux.scm
@@ -45,7 +45,22 @@
kernel-module-loader-service-type
- modprobe-service-type))
+ modprobe-service-type
+
+ kernel-module
+ kernel-module?
+ kernel-module-name
+ kernel-module-package
+ kernel-module-aliases
+ kernel-module-install
+ kernel-module-remove
+ kernel-module-pre-dependencies
+ kernel-module-post-dependencies
+ kernel-module-blacklist?
+ kernel-module-load?
+ kernel-module-is-builtin?
+ kernel-module->kernel-arguments
+ kernel-module-configuration-service-type))
\f
;;;
@@ -151,6 +166,9 @@ representation."
(rnrs io ports)
,@%default-modules))
(start
+ ;; TODO Verify that we are loading a loadable kernel and not a builtin
+ ;; one looking in
+ ;; /run/booted-system/kernel/lib/modules/5.4.39/modules.builtin
#~(lambda _
(cond
((null? '#$kernel-modules) #t)
@@ -227,3 +245,149 @@ files."
modprobe-environment)))
(compose concatenate)
(extend append)))
+
+\f
+;;;
+;;; Kernel module configuration.
+;;;
+
+;; NOTE Maybe have sperate records betwwen <kernel-builtin-module> and
+;; <kernel-lodable-module>
+(define-record-type* <kernel-module>
+ kernel-module make-kernel-module
+ kernel-module?
+ (name kernel-module-name) ; string
+ ;; For out-of-tree modules
+ (package kernel-module-package
+ (default #f)) ; #f | <package>
+ ;; NOTE Maybe use an alist instead
+ (options kernel-module-options
+ (default '())) ; list of strings
+ (aliases kernel-module-aliases
+ (default '())) ; list of strings
+ (install kernel-module-install
+ (default #f)) ; #f | string
+ (remove kernel-module-remove
+ (default #f)) ; #f | string
+ (pre-dependencies kernel-module-pre-dependencies
+ (default '())) ; list of strings
+ (post-dependencies kernel-module-post-dependencies
+ (default '())) ; list of strings
+ (blacklist? kernel-module-blacklist?
+ (default #f)) ; boolean
+ ;; NOTE Only possible if it's not built-in
+ ;; TODO maybe trow an error when it's set to true on a built-in module
+ (load? kernel-module-load?
+ (default #f))) ; boolean
+
+;; FIXME use 'modules.builtin' instead
+(define (kernel-module-is-builtin? module)
+ (if (kernel-module-package module) #f
+ #t))
+
+(define (kernel-module->kernel-arguments module)
+ "Return a list of kernel arguments for MODULE."
+ (match-record module <kernel-module>
+ (name options blacklist?)
+ (filter (lambda (s) (not (string-null? s)))
+ (list (if blacklist? (string-append name ".blacklist=yes") "")
+ (if (null? options) ""
+ (map (lambda (option)
+ (string-append name "." option))
+ options))))))
+
+(define (kernel-module->config module)
+ "Return a config string for MODULE."
+ (match-record module <kernel-module>
+ (name options aliases install remove pre-dependencies
+ post-dependencies blacklist?)
+ (string-concatenate
+ (list (if (null? options) ""
+ (format #f "options ~a~{ ~a~}\n" name options))
+ (if blacklist? (format #f "blacklist ~a\n" name)
+ "")
+ (if (null? aliases) ""
+ (map (lambda (alias)
+ (format #f "alias ~a ~a\n" alias name))
+ aliases))
+ (if install (format #f "install ~a ~a\n" name install)
+ "")
+ (if remove (format #f "remove ~a ~a\n" name remove)
+ "")
+ (if (null? pre-dependencies) ""
+ (map (lambda (dependency)
+ (format #f "softdep ~a :pre ~a\n"
+ name dependency))
+ pre-dependencies))
+ (if (null? post-dependencies) ""
+ (map (lambda (dependency)
+ (format #f "softdep ~a :post ~a\n"
+ name dependency))
+ post-dependencies))))))
+
+(define (string-underscorize s)
+ "Replace '-' characters by '_' in string S."
+ (string-map (lambda (c) (if (char=? c #\-) #\_ c)) s))
+
+(define (kernel-modules->config-files modules)
+ "Return a list of pairs of file name and gexp, to be used by 'file-union',
+from MODULES."
+ (define (kernel-module->filename-gexp module)
+ (let ((config (kernel-module->config module))
+ (name (kernel-module-name module)))
+ (if (string-null? config) #f
+ (list (string-append name ".conf")
+ (plain-file (string-append name ".conf") config)))))
+ (filter-map
+ (lambda (module)
+ (let ((module (kernel-module
+ (inherit module)
+ ;; XXX The kernel replace '-' by '_' in module name, we do
+ ;; the same to make name collision visible, that would
+ ;; otherwise be hidden.
+ (name (string-underscorize (kernel-module-name module))))))
+ (if (kernel-module-is-builtin? module) #f
+ (kernel-module->filename-gexp module))))
+ modules))
+
+(define (kernel-modules->packages modules)
+ "Return a list of packages from MODULES."
+ (filter-map (lambda (module)
+ (kernel-module-package module))
+ modules))
+
+(define (kernel-modules-to-load modules)
+ "Return a list of loadable module names, from MODULES, to be loaded."
+ (filter-map (lambda (module)
+ (if (and (not (kernel-module-is-builtin? module))
+ (kernel-module-load? module))
+ (kernel-module-name module)
+ #f))
+ modules))
+
+(define kernel-module-configuration-service-type
+ (service-type
+ (name 'kernel-module-configuration)
+ (description
+ "Configure kernel modules, in similar manner as @file{modprobe.d}.")
+ (default-value '())
+ (extensions
+ (list (service-extension modprobe-service-type
+ kernel-modules->config-files)
+ (service-extension kernel-profile-service-type
+ kernel-modules->packages)
+ (service-extension kernel-module-loader-service-type
+ kernel-modules-to-load)))
+ (compose concatenate)
+ (extend append)))
+
+;; TODO Make a naked modprobe call use MODPROBE_OPTIONS environment or
+;; /proc/sys/kernel/modprobe
+
+;; TODO write a helper to load a module from guile using modprobe command from
+;; '/proc/sys/kernel/modprobe' or %modprobe-wrapper. See linux-module-builder
+;; maybe.
+
+;; NOTE Throw an error when kernel-module-name isn't unique? It may already
+;; do it by itself already because 2 loadable module will try to create
+;; separeta config file with the same name.
diff --git a/gnu/tests/linux-modules.scm b/gnu/tests/linux-modules.scm
index 22e9a0c65c..296066e68f 100644
--- a/gnu/tests/linux-modules.scm
+++ b/gnu/tests/linux-modules.scm
@@ -32,6 +32,7 @@
#:use-module (guix monads)
#:use-module (guix store)
#:use-module (guix utils)
+ #:use-module (srfi srfi-1)
#:export (%test-loadable-kernel-modules-0
%test-loadable-kernel-modules-1
%test-loadable-kernel-modules-2))
@@ -66,19 +67,18 @@ that MODULES are actually loaded."
(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 verify that MODULE-NAMES
-are loaded in memory."
+(define* (run-loadable-kernel-modules-test modules)
+ "Run a test of an OS having MODULES and verify that they 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)
- (simple-service 'kernel-module-packages
- kernel-profile-service-type
- module-packages)
- (operating-system-user-services
- (simple-operating-system)))))
+ (inherit (simple-operating-system))
+ (services (cons* (service kernel-module-loader-service-type)
+ (service kernel-module-configuration-service-type
+ modules)
+ (operating-system-user-services
+ (simple-operating-system)))))
#:imported-modules '((guix combinators))))
(define vm (virtual-machine os))
(define (test script)
@@ -97,15 +97,20 @@ are loaded in memory."
marionette))
(test-end)
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))
- (gexp->derivation "loadable-kernel-modules"
- (test (modules-loaded?-program os module-names))))
+ (let ((modules (filter-map (lambda (module)
+ (if (kernel-module-load? module)
+ (kernel-module-name module)
+ #f))
+ modules)))
+ (gexp->derivation "loadable-kernel-modules"
+ (test (modules-loaded?-program os modules)))))
(define %test-loadable-kernel-modules-0
(system-test
(name "loadable-kernel-modules-0")
(description "Tests loadable kernel modules facility of <operating-system>
with no extra modules.")
- (value (run-loadable-kernel-modules-test '() '()))))
+ (value (run-loadable-kernel-modules-test '()))))
(define %test-loadable-kernel-modules-1
(system-test
@@ -113,8 +118,11 @@ with no extra modules.")
(description "Tests loadable kernel modules facility of <operating-system>
with one extra module.")
(value (run-loadable-kernel-modules-test
- (list ddcci-driver-linux)
- '("ddcci")))))
+ (list (kernel-module
+ (name "ddcci")
+ (package ddcci-driver-linux)
+ (options '("delay=606"))
+ (load? #t)))))))
(define %test-loadable-kernel-modules-2
(system-test
@@ -122,12 +130,23 @@ with one extra module.")
(description "Tests loadable kernel modules facility of <operating-system>
with two extra modules.")
(value (run-loadable-kernel-modules-test
- (list acpi-call-linux-module
- (package
- (inherit ddcci-driver-linux)
- (arguments
- `(#:linux #f
- ,@(strip-keyword-arguments '(#:linux)
- (package-arguments
- ddcci-driver-linux))))))
- '("acpi_call" "ddcci")))))
+ (list (kernel-module
+ (name "ddcci")
+ ;; XXX Verify that kernel modules are built with the correct
+ ;; kernel
+ (package (package
+ (inherit ddcci-driver-linux)
+ (arguments
+ `(#:linux #f
+ ,@(strip-keyword-arguments '(#:linux)
+ (package-arguments
+ ddcci-driver-linux))))))
+ (load? #t))
+ (kernel-module
+ (name "acpi_call")
+ (package acpi-call-linux-module)
+ (load? #t))
+ ;; TODO Test that a module isn't loaded
+ (kernel-module
+ (name "radeon")
+ (blacklist? #t)))))))
--
2.26.2
prev parent reply other threads:[~2020-07-04 18:55 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20200704185234.12571-1-brice@waegenei.re>
2020-07-04 18:54 ` [bug#42193] [WIP 1/6] services: simulated-wifi: Use 'kernel-module-loader' Brice Waegeneire
2020-07-04 18:54 ` Brice Waegeneire
2020-07-06 11:08 ` Danny Milosavljevic
2020-07-06 12:31 ` Brice Waegeneire
2020-07-04 18:54 ` [bug#42193] [WIP 2/6] services: Add 'kernel-profile-service-type' Brice Waegeneire
2020-07-08 11:29 ` pelzflorian (Florian Pelz)
2020-07-08 16:22 ` Brice Waegeneire
2020-07-11 17:30 ` pelzflorian (Florian Pelz)
2020-07-04 18:54 ` [bug#42193] [WIP 3/6] services: Add 'modprobe-service-type' Brice Waegeneire
2020-07-04 18:54 ` [bug#42193] [WIP 4/6] services: kernel-module-loader: Return a single 'shepherd-service' Brice Waegeneire
2020-07-06 0:03 ` Danny Milosavljevic
2020-07-06 10:01 ` Brice Waegeneire
2020-07-17 18:49 ` Danny Milosavljevic
2021-01-06 18:20 ` Danny Milosavljevic
2020-07-04 18:54 ` [bug#42193] [WIP 5/6] WIP services: Add kernel-arguments-service-type Brice Waegeneire
2020-07-04 18:54 ` Brice Waegeneire [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200704185431.13739-7-brice@waegenei.re \
--to=brice@waegenei.re \
--cc=42193@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).