summaryrefslogtreecommitdiff
path: root/gnu/build
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim.cournoyer@gmail.com>2024-05-12 20:51:50 -0400
committerMaxim Cournoyer <maxim.cournoyer@gmail.com>2024-05-29 22:01:23 -0400
commitafacfa33ec4b52cb9ffb9b0a7a0c1e68cf264673 (patch)
tree9d811f1d85d4ae892604ca421d653ea53fb654a0 /gnu/build
parentb72b6063cebbcfd64d43f5b05ba8470eb11c3f65 (diff)
gnu: linux-libre: Enable Zstd compression of kernel modules.
This brings the on disk size of the kernel from 164 MiB to 144 MiB, or about 12%. * gnu/packages/linux.scm (default-extra-linux-options) [version>=5.13]: Enable CONFIG_MODULE_COMPRESS_ZSTD, else CONFIG_MODULE_COMPRESS_GZIP. (make-linux-libre*) [phases] {set-environment}: Set ZSTD_CLEVEL environment variable to 19. [native-inputs]: Add zstd. * gnu/build/linux-modules.scm (module-regex): Add .zst to regexp. Update doc. (modinfo-section-contents): Extend support to Zstd compressed module. (dot-ko): Register the 'zstd compression type. (ensure-dot-ko, file-name->module-name, load-linux-module*) (module-name->file-name/guess, write-module-name-database) (write-module-alias-database, write-module-device-database): Update doc. (module-name-lookup): Also consider zstd-compressed modules. * gnu/installer.scm (installer-program): Add guile-zstd extension to gexp. * gnu/system/linux-initrd.scm (flat-linux-module-directory): Likewise. Decompress zstd-compressed modules for use in initrd. * guix/profiles.scm (linux-module-database): Add guile-zstd extension to gexp. Change-Id: Ide899dc5c58ea5033583b1a91a92c025fc8d901a
Diffstat (limited to 'gnu/build')
-rw-r--r--gnu/build/linux-modules.scm62
1 files changed, 36 insertions, 26 deletions
diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scm
index 68c32ff8738..32baf6c5259 100644
--- a/gnu/build/linux-modules.scm
+++ b/gnu/build/linux-modules.scm
@@ -3,6 +3,7 @@
3;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> 3;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
4;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org> 4;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org>
5;;; Copyright © 2023 Tobias Geerinckx-Rice <me@tobias.gr> 5;;; Copyright © 2023 Tobias Geerinckx-Rice <me@tobias.gr>
6;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
6;;; 7;;;
7;;; This file is part of GNU Guix. 8;;; This file is part of GNU Guix.
8;;; 9;;;
@@ -26,6 +27,7 @@
26 #:use-module ((guix build utils) #:select (find-files invoke)) 27 #:use-module ((guix build utils) #:select (find-files invoke))
27 #:use-module (guix build union) 28 #:use-module (guix build union)
28 #:autoload (zlib) (call-with-gzip-input-port) 29 #:autoload (zlib) (call-with-gzip-input-port)
30 #:autoload (zstd) (call-with-zstd-input-port)
29 #:use-module (rnrs io ports) 31 #:use-module (rnrs io ports)
30 #:use-module (rnrs bytevectors) 32 #:use-module (rnrs bytevectors)
31 #:use-module (srfi srfi-1) 33 #:use-module (srfi srfi-1)
@@ -108,24 +110,29 @@ string list."
108 (cons (string->symbol (string-take str =)) 110 (cons (string->symbol (string-take str =))
109 (string-drop str (+ 1 =))))) 111 (string-drop str (+ 1 =)))))
110 112
111;; Matches kernel modules, without compression, with GZIP compression or with 113;; Matches kernel modules, without compression, with GZIP, XZ or ZSTD
112;; XZ compression. 114;; compression.
113(define module-regex "\\.ko(\\.gz|\\.xz)?$") 115(define module-regex "\\.ko(\\.gz|\\.xz|\\.zst)?$")
114 116
115(define (modinfo-section-contents file) 117(define (modinfo-section-contents file)
116 "Return the contents of the '.modinfo' section of FILE as a list of 118 "Return the contents of the '.modinfo' section of FILE as a list of
117key/value pairs.." 119key/value pairs.."
120 (define (decompress-file decompressor file)
121 (let ((port (open-file file "r0")))
122 (dynamic-wind
123 (lambda ()
124 #t)
125 (lambda ()
126 (decompressor port get-bytevector-all))
127 (lambda ()
128 (close-port port)))))
129
118 (define (get-bytevector file) 130 (define (get-bytevector file)
119 (cond 131 (cond
120 ((string-suffix? ".ko.gz" file) 132 ((string-suffix? ".ko.gz" file)
121 (let ((port (open-file file "r0"))) 133 (decompress-file call-with-gzip-input-port file))
122 (dynamic-wind 134 ((string-suffix? ".ko.zst" file)
123 (lambda () 135 (decompress-file call-with-zstd-input-port file))
124 #t)
125 (lambda ()
126 (call-with-gzip-input-port port get-bytevector-all))
127 (lambda ()
128 (close-port port)))))
129 (else 136 (else
130 (call-with-input-file file get-bytevector-all)))) 137 (call-with-input-file file get-bytevector-all))))
131 138
@@ -213,11 +220,12 @@ modules that can be postloaded, of the soft dependencies of module FILE."
213 (let ((suffix (match compression 220 (let ((suffix (match compression
214 ('xz ".ko.xz") 221 ('xz ".ko.xz")
215 ('gzip ".ko.gz") 222 ('gzip ".ko.gz")
223 ('zstd ".ko.zst")
216 (else ".ko")))) 224 (else ".ko"))))
217 (string-append name suffix))) 225 (string-append name suffix)))
218 226
219(define (ensure-dot-ko name compression) 227(define (ensure-dot-ko name compression)
220 "Return NAME with a '.ko[.gz|.xz]' suffix appended, unless it already has 228 "Return NAME with a '.ko[.gz|.xz|.zst]' suffix appended, unless it already has
221it." 229it."
222 (if (string-contains name ".ko") 230 (if (string-contains name ".ko")
223 name 231 name
@@ -235,7 +243,7 @@ underscores."
235 243
236(define (file-name->module-name file) 244(define (file-name->module-name file)
237 "Return the module name corresponding to FILE, stripping the trailing 245 "Return the module name corresponding to FILE, stripping the trailing
238'.ko[.gz|.xz]' and normalizing it." 246'.ko[.gz|.xz|.zst]' and normalizing it."
239 (normalize-module-name (strip-extension (basename file)))) 247 (normalize-module-name (strip-extension (basename file))))
240 248
241(define (find-module-file directory module) 249(define (find-module-file directory module)
@@ -333,11 +341,11 @@ not a file name."
333 (recursive? #t) 341 (recursive? #t)
334 (lookup-module dot-ko) 342 (lookup-module dot-ko)
335 (black-list (module-black-list))) 343 (black-list (module-black-list)))
336 "Load Linux module from FILE, the name of a '.ko[.gz|.xz]' file; return true 344 "Load Linux module from FILE, the name of a '.ko[.gz|.xz|.zst]' file; return
337on success, false otherwise. When RECURSIVE? is true, load its dependencies 345true on success, false otherwise. When RECURSIVE? is true, load its
338first (à la 'modprobe'.) The actual files containing modules depended on are 346dependencies first (à la 'modprobe'.) The actual files containing modules
339obtained by calling LOOKUP-MODULE with the module name. Modules whose name 347depended on are obtained by calling LOOKUP-MODULE with the module name.
340appears in BLACK-LIST are not loaded." 348Modules whose name appears in BLACK-LIST are not loaded."
341 (define (black-listed? module) 349 (define (black-listed? module)
342 (let ((result (member module black-list))) 350 (let ((result (member module black-list)))
343 (when result 351 (when result
@@ -695,7 +703,7 @@ are required to access DEVICE."
695 "Guess the file name corresponding to NAME, a module name. That doesn't 703 "Guess the file name corresponding to NAME, a module name. That doesn't
696always work because sometimes underscores in NAME map to hyphens (e.g., 704always work because sometimes underscores in NAME map to hyphens (e.g.,
697\"input-leds.ko\"), sometimes not (e.g., \"mac_hid.ko\"). If the module is 705\"input-leds.ko\"), sometimes not (e.g., \"mac_hid.ko\"). If the module is
698compressed then COMPRESSED can be set to 'xz or 'gzip, depending on the 706compressed then COMPRESSED can be set to 'zstd, 'xz or 'gzip, depending on the
699compression type." 707compression type."
700 (string-append directory "/" (ensure-dot-ko name compression))) 708 (string-append directory "/" (ensure-dot-ko name compression)))
701 709
@@ -707,6 +715,8 @@ compression type."
707 (let ((names (list 715 (let ((names (list
708 (module-name->file-name/guess directory name) 716 (module-name->file-name/guess directory name)
709 (module-name->file-name/guess directory name 717 (module-name->file-name/guess directory name
718 #:compression 'zstd)
719 (module-name->file-name/guess directory name
710 #:compression 'xz) 720 #:compression 'xz)
711 (module-name->file-name/guess directory name 721 (module-name->file-name/guess directory name
712 #:compression 'gzip)))) 722 #:compression 'gzip))))
@@ -729,8 +739,8 @@ compression type."
729 739
730(define (write-module-name-database directory) 740(define (write-module-name-database directory)
731 "Write a database that maps \"module names\" as they appear in the relevant 741 "Write a database that maps \"module names\" as they appear in the relevant
732ELF section of '.ko[.gz|.xz]' files, to actual file names. This format is 742ELF section of '.ko[.gz|.xz|.zst]' files, to actual file names. This format
733Guix-specific. It aims to deal with inconsistent naming, in particular 743is Guix-specific. It aims to deal with inconsistent naming, in particular
734hyphens vs. underscores." 744hyphens vs. underscores."
735 (define mapping 745 (define mapping
736 (map (lambda (file) 746 (map (lambda (file)
@@ -749,8 +759,8 @@ hyphens vs. underscores."
749 (pretty-print mapping port)))) 759 (pretty-print mapping port))))
750 760
751(define (write-module-alias-database directory) 761(define (write-module-alias-database directory)
752 "Traverse the '.ko[.gz|.xz]' files in DIRECTORY and create the corresponding 762 "Traverse the '.ko[.gz|.xz|.zst]' files in DIRECTORY and create the
753'modules.alias' file." 763corresponding 'modules.alias' file."
754 (define aliases 764 (define aliases
755 (map (lambda (file) 765 (map (lambda (file)
756 (cons (file-name->module-name file) (module-aliases file))) 766 (cons (file-name->module-name file) (module-aliases file)))
@@ -796,9 +806,9 @@ are found, return a tuple (DEVNAME TYPE MAJOR MINOR), otherwise return #f."
796 (char-set-complement (char-set #\-))) 806 (char-set-complement (char-set #\-)))
797 807
798(define (write-module-device-database directory) 808(define (write-module-device-database directory)
799 "Traverse the '.ko[.gz|.xz]' files in DIRECTORY and create the corresponding 809 "Traverse the '.ko[.gz|.xz|.zst]' files in DIRECTORY and create the
800'modules.devname' file. This file contains information about modules that can 810corresponding 'modules.devname' file. This file contains information about
801be loaded on-demand, such as file system modules." 811modules that can be loaded on-demand, such as file system modules."
802 (define aliases 812 (define aliases
803 (filter-map (lambda (file) 813 (filter-map (lambda (file)
804 (match (aliases->device-tuple (module-aliases file)) 814 (match (aliases->device-tuple (module-aliases file))