diff mbox series

[bug#71482,v2] gnu: zfs: Split the kernel module out of the base package.

Message ID bce99c396e12032bc9c5d241483c224d30e3c387.1727034635.git.kaelyn.alexi@protonmail.com
State New
Headers show
Series [bug#71482,v2] gnu: zfs: Split the kernel module out of the base package. | expand

Commit Message

Kaelyn Takata Sept. 22, 2024, 7:52 p.m. UTC
Split the ZFS user-space tools and kernel modules into separate packages, with
a new make-zfs-for-kernel procedure for easily creating ZFS kernel module
packages for a specific kernel package. The generated kernel module package
includes the kernel version for which it was built in the name of the package,
such as "zfs-for-linux-libre-6.6.32-version".

& gnu/packages/file-systems.scm (zfs): Change to be the user-space tools.
(make-zfs-for-kernel): New procedure which accepts a single 'kernel-package'
argument.

Change-Id: Ib2d0e2b0f031d2ab3105d6b46ecd73bde1aa8564
---
 gnu/packages/file-systems.scm | 126 ++++++++++++++++++++--------------
 1 file changed, 73 insertions(+), 53 deletions(-)


base-commit: b7c94d528875415ea7ec6225d88a6b3d55fa2e14

Comments

Z572 Oct. 5, 2024, 4:17 p.m. UTC | #1
Kaelyn Takata via Guix-patches via <guix-patches@gnu.org> writes:

> Split the ZFS user-space tools and kernel modules into separate packages, with
> a new make-zfs-for-kernel procedure for easily creating ZFS kernel module
> packages for a specific kernel package. The generated kernel module package
> includes the kernel version for which it was built in the name of the package,
> such as "zfs-for-linux-libre-6.6.32-version".
>
> & gnu/packages/file-systems.scm (zfs): Change to be the user-space tools.
> (make-zfs-for-kernel): New procedure which accepts a single 'kernel-package'
> argument.
>
> Change-Id: Ib2d0e2b0f031d2ab3105d6b46ecd73bde1aa8564
> ---
>  gnu/packages/file-systems.scm | 126 ++++++++++++++++++++--------------
>  1 file changed, 73 insertions(+), 53 deletions(-)
>
> diff --git a/gnu/packages/file-systems.scm b/gnu/packages/file-systems.scm
> index 059bdf67a9..ceaaf7f3ab 100644
> --- a/gnu/packages/file-systems.scm
> +++ b/gnu/packages/file-systems.scm
> @@ -9,7 +9,7 @@
>  ;;; Copyright © 2021 raid5atemyhomework <raid5atemyhomework@protonmail.com>
>  ;;; Copyright © 2021 Stefan Reichör <stefan@xsteve.at>
>  ;;; Copyright © 2021 Noisytoot <noisytoot@disroot.org>
> -;;; Copyright © 2021, 2023 Kaelyn Takata <kaelyn.alexi@protonmail.com>
> +;;; Copyright © 2021, 2023, 2024 Kaelyn Takata <kaelyn.alexi@protonmail.com>
>  ;;; Copyright © 2022 Brian Cully <bjc@spork.org>
>  ;;; Copyright © 2023 Aaron Covrig <aaron.covrig.us@ieee.org>
>  ;;; Copyright © 2024 Ahmad Draidi <a.r.draidi@redscript.org>
> @@ -1564,7 +1564,6 @@ (define-public zfs
>    (package
>      (name "zfs")
>      (version "2.2.6")
> -    (outputs '("out" "module" "src"))
>      (source
>        (origin
>          (method url-fetch)
> @@ -1573,33 +1572,19 @@ (define-public zfs
>                                "/zfs-" version ".tar.gz"))
>            (sha256
>             (base32 "19x2a8k25i3y6nr7nx5aaqrpnp55vjmrw86p06zpgpf578804bn9"))))
> -    (build-system linux-module-build-system)
> +    (build-system gnu-build-system)
>      (arguments
>       (list
> -      ;; The ZFS kernel module should not be downloaded since the license
> -      ;; terms don't allow for distributing it, only building it locally.
> -      #:substitutable? #f
> -      ;; Tests cannot run in an unprivileged build environment.
> -      #:tests? #f
> +      #:configure-flags #~(list "--with-config=user"
> +                                (string-append "--prefix=" #$output)
> +                                (string-append "--with-dracutdir=" #$output
> +                                               "/lib/dracut")
> +                                (string-append "--with-udevdir=" #$output
> +                                               "/lib/udev")
> +                                (string-append "--with-mounthelperdir=" #$output
> +                                               "/sbin"))
>        #:phases
>        #~(modify-phases %standard-phases
> -          (add-after 'configure 'really-configure
> -            (lambda* (#:key inputs #:allow-other-keys)
> -              (substitute* "configure"
> -                (("-/bin/sh") (string-append "-" (which "sh"))))
> -              (invoke "./configure"
> -                      "--with-config=all"
> -                      (string-append "--prefix=" #$output)
> -                      (string-append "--with-dracutdir=" #$output
> -                                     "/lib/dracut")
> -                      (string-append "--with-udevdir=" #$output
> -                                     "/lib/udev")
> -                      (string-append "--with-mounthelperdir=" #$output
> -                                     "/sbin")
> -                      (string-append "--with-linux="
> -                                     (search-input-directory
> -                                      inputs
> -                                      "lib/modules/build")))))
>            (add-after 'unpack 'patch-source
>              (lambda* (#:key inputs #:allow-other-keys)
>                ;; New feature "compatibility=" in 2.1.0.
> @@ -1631,14 +1616,6 @@ (define-public zfs
>                  ;; Just use 'modprobe' in message to user, since Guix
>                  ;; does not have a traditional /sbin/
>                  (("'/sbin/modprobe ") "'modprobe "))
> -              (substitute* "configure"
> -                (("/etc/default")
> -                 (string-append #$output "/etc/default"))
> -                (("/etc/bash_completion.d")
> -                 (string-append #$output "/etc/bash_completion.d")))
> -              (substitute* "Makefile.in"
> -                (("/usr/share/initramfs-tools")
> -                 (string-append #$output "/usr/share/initramfs-tools")))
>                (substitute* "contrib/initramfs/Makefile.am"
>                  (("/usr/share/initramfs-tools")
>                   (string-append #$output "/usr/share/initramfs-tools")))
> @@ -1668,31 +1645,22 @@ (define-public zfs
>                                  (dirname (which "sed")) ":"
>                                  (dirname (which "gawk")))))
>                (substitute* '("Makefile.am" "Makefile.in")
> -                (("\\$\\(prefix)/src") (string-append #$output:src "/src")))
> +                (("@initconfdir@") (string-append #$output "/etc/default"))
> +                (("/usr/share/initramfs-tools" dir) (string-append #$output dir)))
>                (substitute* (find-files "udev/rules.d/" ".rules.in$")
>                  (("/sbin/modprobe")
>                   (search-input-file inputs "/bin/modprobe")))))
> -          (replace 'build
> -            (lambda _ (invoke "make")))
>            (replace 'install
> -            (lambda* (#:key inputs native-inputs #:allow-other-keys)
> -              (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
> -                (invoke "make" "install"
> -                        (string-append "DEFAULT_INITCONF_DIR="
> -                                       #$output "/etc/default")
> -                        (string-append "DEPMOD="
> -                                       (search-input-file
> -                                        (or native-inputs inputs)
> -                                        "/bin/depmod"))
> -                        (string-append "INSTALL_PATH=" #$output)
> -                        (string-append "INSTALL_MOD_PATH=" #$output:module)
> -                        "INSTALL_MOD_STRIP=1")
> -                (install-file
> -                 "contrib/bash_completion.d/zfs"
> -                 (string-append #$output
> -                                "/share/bash-completion/completions"))))))))
> +            (lambda _
> +              (invoke "make" "install"
> +                      (string-append "DEFAULT_INITCONF_DIR="
> +                                     #$output "/etc/default")
> +                      (string-append "INSTALL_PATH=" #$output)
> +                      (string-append "bashcompletiondir="
> +                                     #$output
> +                                     "/share/bash-completion/completions")))))))
>      (native-inputs
> -     (list attr kmod pkg-config))
> +     (list attr kmod pkg-config python))
>      (inputs (list eudev
>                    kmod
>                    libaio
> @@ -1712,6 +1680,58 @@ (define-public zfs
>  community.")
>      (license license:cddl1.0)))
>  
> +(define-public (make-zfs-for-kernel kernel-package)

Just to be clear, I don't know much about ZFS licensing issues.

i don't think need a procedure, just a package, If I understand the code
correctly, gnu/services.scm (linux-builder-service-type) will replace
#:linux to target-linux, and see
linux-builder-configuration->system-entry , package-for-kernel.

> +  (package
> +    (inherit zfs)
> +    (name (string-join (list (package-name zfs)
> +                             "for"
> +                             (package-name kernel-package)
> +                             (package-version kernel-package)
> +                             "version")
> +                       "-"))
> +    (build-system linux-module-build-system)
> +    (arguments
> +     (substitute-keyword-arguments
> +         (strip-keyword-arguments '(#:configure-flags)
> +                                  (package-arguments zfs))
> +       ((#:linux _ #f) kernel-package)
> +       ((#:substitutable? _ #t) #f)
> +       ((#:phases phases)
> +        #~(modify-phases %standard-phases
> +            (add-after 'unpack 'patch-source
> +              (assoc-ref #$phases 'patch-source))
> +            (add-after 'configure 'really-configure
> +              (lambda* (#:key inputs #:allow-other-keys)
> +                (substitute* "configure"
> +                  (("-/bin/sh") (string-append "-" (which "sh"))))
> +                (invoke "./configure"
> +                        "--with-config=kernel"
> +                        (string-append "--prefix=" #$output)
> +                        (string-append "--with-udevdir=" #$output
> +                                       "/lib/udev")
> +                        (string-append "--with-linux="
> +                                       (search-input-directory
> +                                        inputs
> +                                        "lib/modules/build")))))
> +            (replace 'build
> +              (lambda* (#:key (make-flags '()) (parallel-build? #t)
> +                        #:allow-other-keys)
> +                (apply invoke "make"
> +                       `(,@(if parallel-build?
> +                               `("-j" ,(number->string (parallel-job-count)))
> +                               '())
> +                         ,@make-flags))))
> +            (replace 'install
> +              (lambda* (#:key inputs native-inputs #:allow-other-keys)
> +                (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
> +                  (invoke "make" "-C" "module" "install"
> +                          (string-append "DEPMOD="
> +                                         (search-input-file
> +                                          (or native-inputs inputs)
> +                                          "/bin/depmod"))
> +                          (string-append "INSTALL_MOD_PATH=" #$output)
> +                          "INSTALL_MOD_STRIP=1"))))))))))
> +
>  (define-public zfs-auto-snapshot
>    (package
>      (name "zfs-auto-snapshot")
>
> base-commit: b7c94d528875415ea7ec6225d88a6b3d55fa2e14
Kaelyn Takata Oct. 5, 2024, 6:06 p.m. UTC | #2
Hi,

On Saturday, October 5th, 2024 at 4:17 PM, Zheng Junjie <zhengjunjie@iscas.ac.cn> wrote:

> 
> 
> Kaelyn Takata via Guix-patches via guix-patches@gnu.org writes:
> 
> > Split the ZFS user-space tools and kernel modules into separate packages, with
> > a new make-zfs-for-kernel procedure for easily creating ZFS kernel module
> > packages for a specific kernel package. The generated kernel module package
> > includes the kernel version for which it was built in the name of the package,
> > such as "zfs-for-linux-libre-6.6.32-version".
> > 
> > & gnu/packages/file-systems.scm (zfs): Change to be the user-space tools.
> > (make-zfs-for-kernel): New procedure which accepts a single 'kernel-package'
> > argument.
> > 
> > Change-Id: Ib2d0e2b0f031d2ab3105d6b46ecd73bde1aa8564
> > ---
> > gnu/packages/file-systems.scm | 126 ++++++++++++++++++++--------------
> > 1 file changed, 73 insertions(+), 53 deletions(-)
> > 
> > diff --git a/gnu/packages/file-systems.scm b/gnu/packages/file-systems.scm
> > index 059bdf67a9..ceaaf7f3ab 100644
> > --- a/gnu/packages/file-systems.scm
> > +++ b/gnu/packages/file-systems.scm
> > @@ -9,7 +9,7 @@
> > ;;; Copyright © 2021 raid5atemyhomework raid5atemyhomework@protonmail.com
> > ;;; Copyright © 2021 Stefan Reichör stefan@xsteve.at
> > ;;; Copyright © 2021 Noisytoot noisytoot@disroot.org
> > -;;; Copyright © 2021, 2023 Kaelyn Takata kaelyn.alexi@protonmail.com
> > +;;; Copyright © 2021, 2023, 2024 Kaelyn Takata kaelyn.alexi@protonmail.com
> > ;;; Copyright © 2022 Brian Cully bjc@spork.org
> > ;;; Copyright © 2023 Aaron Covrig aaron.covrig.us@ieee.org
> > ;;; Copyright © 2024 Ahmad Draidi a.r.draidi@redscript.org
> > @@ -1564,7 +1564,6 @@ (define-public zfs
> > (package
> > (name "zfs")
> > (version "2.2.6")
> > - (outputs '("out" "module" "src"))
> > (source
> > (origin
> > (method url-fetch)
> > @@ -1573,33 +1572,19 @@ (define-public zfs
> > "/zfs-" version ".tar.gz"))
> > (sha256
> > (base32 "19x2a8k25i3y6nr7nx5aaqrpnp55vjmrw86p06zpgpf578804bn9"))))
> > - (build-system linux-module-build-system)
> > + (build-system gnu-build-system)
> > (arguments
> > (list
> > - ;; The ZFS kernel module should not be downloaded since the license
> > - ;; terms don't allow for distributing it, only building it locally.
> > - #:substitutable? #f
> > - ;; Tests cannot run in an unprivileged build environment.
> > - #:tests? #f
> > + #:configure-flags #~(list "--with-config=user"
> > + (string-append "--prefix=" #$output)
> > + (string-append "--with-dracutdir=" #$output
> > + "/lib/dracut")
> > + (string-append "--with-udevdir=" #$output
> > + "/lib/udev")
> > + (string-append "--with-mounthelperdir=" #$output
> > + "/sbin"))
> > #:phases
> > #~(modify-phases %standard-phases
> > - (add-after 'configure 'really-configure
> > - (lambda* (#:key inputs #:allow-other-keys)
> > - (substitute* "configure"
> > - (("-/bin/sh") (string-append "-" (which "sh"))))
> > - (invoke "./configure"
> > - "--with-config=all"
> > - (string-append "--prefix=" #$output)
> > - (string-append "--with-dracutdir=" #$output
> > - "/lib/dracut")
> > - (string-append "--with-udevdir=" #$output
> > - "/lib/udev")
> > - (string-append "--with-mounthelperdir=" #$output
> > - "/sbin")
> > - (string-append "--with-linux="
> > - (search-input-directory
> > - inputs
> > - "lib/modules/build")))))
> > (add-after 'unpack 'patch-source
> > (lambda* (#:key inputs #:allow-other-keys)
> > ;; New feature "compatibility=" in 2.1.0.
> > @@ -1631,14 +1616,6 @@ (define-public zfs
> > ;; Just use 'modprobe' in message to user, since Guix
> > ;; does not have a traditional /sbin/
> > (("'/sbin/modprobe ") "'modprobe "))
> > - (substitute* "configure"
> > - (("/etc/default")
> > - (string-append #$output "/etc/default"))
> > - (("/etc/bash_completion.d")
> > - (string-append #$output "/etc/bash_completion.d")))
> > - (substitute* "Makefile.in"
> > - (("/usr/share/initramfs-tools")
> > - (string-append #$output "/usr/share/initramfs-tools")))
> > (substitute* "contrib/initramfs/Makefile.am"
> > (("/usr/share/initramfs-tools")
> > (string-append #$output "/usr/share/initramfs-tools")))
> > @@ -1668,31 +1645,22 @@ (define-public zfs
> > (dirname (which "sed")) ":"
> > (dirname (which "gawk")))))
> > (substitute* '("Makefile.am" "Makefile.in")
> > - (("\\$\\(prefix)/src") (string-append #$output:src "/src")))
> > + (("@initconfdir@") (string-append #$output "/etc/default"))
> > + (("/usr/share/initramfs-tools" dir) (string-append #$output dir)))
> > (substitute* (find-files "udev/rules.d/" ".rules.in$")
> > (("/sbin/modprobe")
> > (search-input-file inputs "/bin/modprobe")))))
> > - (replace 'build
> > - (lambda _ (invoke "make")))
> > (replace 'install
> > - (lambda* (#:key inputs native-inputs #:allow-other-keys)
> > - (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
> > - (invoke "make" "install"
> > - (string-append "DEFAULT_INITCONF_DIR="
> > - #$output "/etc/default")
> > - (string-append "DEPMOD="
> > - (search-input-file
> > - (or native-inputs inputs)
> > - "/bin/depmod"))
> > - (string-append "INSTALL_PATH=" #$output)
> > - (string-append "INSTALL_MOD_PATH=" #$output:module)
> > - "INSTALL_MOD_STRIP=1")
> > - (install-file
> > - "contrib/bash_completion.d/zfs"
> > - (string-append #$output
> > - "/share/bash-completion/completions"))))))))
> > + (lambda _
> > + (invoke "make" "install"
> > + (string-append "DEFAULT_INITCONF_DIR="
> > + #$output "/etc/default")
> > + (string-append "INSTALL_PATH=" #$output)
> > + (string-append "bashcompletiondir="
> > + #$output
> > + "/share/bash-completion/completions")))))))
> > (native-inputs
> > - (list attr kmod pkg-config))
> > + (list attr kmod pkg-config python))
> > (inputs (list eudev
> > kmod
> > libaio
> > @@ -1712,6 +1680,58 @@ (define-public zfs
> > community.")
> > (license license:cddl1.0)))
> > 
> > +(define-public (make-zfs-for-kernel kernel-package)
> 
> 
> Just to be clear, I don't know much about ZFS licensing issues.
> 
> i don't think need a procedure, just a package, If I understand the code
> correctly, gnu/services.scm (linux-builder-service-type) will replace
> #:linux to target-linux, and see
> linux-builder-configuration->system-entry , package-for-kernel.

Thanks for the pointer to some functionality I wasn't aware of! I'll have to look into it to see if it is sufficient for building the ZFS module for arbitrary kernel packages without also building the module for the default linux-libre kernel, and at the time it is needed. At least right now, I also make use of the function for providing the right ZFS kernel module for inclusion into my initramfs images, so I worry that (linux-builder-service-type)--based on its name-- ay fix up / provide the correct ZFS module too late for uses like the initramfs or a ZFS root. Though to emphasize, I'm going to look into those mechanisms to understand them better. ;)

Cheers,
Kaelyn
> 
> > + (package
> > + (inherit zfs)
> > + (name (string-join (list (package-name zfs)
> > + "for"
> > + (package-name kernel-package)
> > + (package-version kernel-package)
> > + "version")
> > + "-"))
> > + (build-system linux-module-build-system)
> > + (arguments
> > + (substitute-keyword-arguments
> > + (strip-keyword-arguments '(#:configure-flags)
> > + (package-arguments zfs))
> > + ((#:linux _ #f) kernel-package)
> > + ((#:substitutable? _ #t) #f)
> > + ((#:phases phases)
> > + #~(modify-phases %standard-phases
> > + (add-after 'unpack 'patch-source
> > + (assoc-ref #$phases 'patch-source))
> > + (add-after 'configure 'really-configure
> > + (lambda* (#:key inputs #:allow-other-keys)
> > + (substitute* "configure"
> > + (("-/bin/sh") (string-append "-" (which "sh"))))
> > + (invoke "./configure"
> > + "--with-config=kernel"
> > + (string-append "--prefix=" #$output)
> > + (string-append "--with-udevdir=" #$output
> > + "/lib/udev")
> > + (string-append "--with-linux="
> > + (search-input-directory
> > + inputs
> > + "lib/modules/build")))))
> > + (replace 'build
> > + (lambda* (#:key (make-flags '()) (parallel-build? #t)
> > + #:allow-other-keys)
> > + (apply invoke "make"
> > + `(,@(if parallel-build? +` ("-j" ,(number->string (parallel-job-count)))
> > + '())
> > + ,@make-flags))))
> > + (replace 'install
> > + (lambda* (#:key inputs native-inputs #:allow-other-keys)
> > + (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
> > + (invoke "make" "-C" "module" "install"
> > + (string-append "DEPMOD="
> > + (search-input-file
> > + (or native-inputs inputs)
> > + "/bin/depmod"))
> > + (string-append "INSTALL_MOD_PATH=" #$output)
> > + "INSTALL_MOD_STRIP=1"))))))))))
> > +
> > (define-public zfs-auto-snapshot
> > (package
> > (name "zfs-auto-snapshot")
> > 
> > base-commit: b7c94d528875415ea7ec6225d88a6b3d55fa2e14
diff mbox series

Patch

diff --git a/gnu/packages/file-systems.scm b/gnu/packages/file-systems.scm
index 059bdf67a9..ceaaf7f3ab 100644
--- a/gnu/packages/file-systems.scm
+++ b/gnu/packages/file-systems.scm
@@ -9,7 +9,7 @@ 
 ;;; Copyright © 2021 raid5atemyhomework <raid5atemyhomework@protonmail.com>
 ;;; Copyright © 2021 Stefan Reichör <stefan@xsteve.at>
 ;;; Copyright © 2021 Noisytoot <noisytoot@disroot.org>
-;;; Copyright © 2021, 2023 Kaelyn Takata <kaelyn.alexi@protonmail.com>
+;;; Copyright © 2021, 2023, 2024 Kaelyn Takata <kaelyn.alexi@protonmail.com>
 ;;; Copyright © 2022 Brian Cully <bjc@spork.org>
 ;;; Copyright © 2023 Aaron Covrig <aaron.covrig.us@ieee.org>
 ;;; Copyright © 2024 Ahmad Draidi <a.r.draidi@redscript.org>
@@ -1564,7 +1564,6 @@  (define-public zfs
   (package
     (name "zfs")
     (version "2.2.6")
-    (outputs '("out" "module" "src"))
     (source
       (origin
         (method url-fetch)
@@ -1573,33 +1572,19 @@  (define-public zfs
                               "/zfs-" version ".tar.gz"))
           (sha256
            (base32 "19x2a8k25i3y6nr7nx5aaqrpnp55vjmrw86p06zpgpf578804bn9"))))
-    (build-system linux-module-build-system)
+    (build-system gnu-build-system)
     (arguments
      (list
-      ;; The ZFS kernel module should not be downloaded since the license
-      ;; terms don't allow for distributing it, only building it locally.
-      #:substitutable? #f
-      ;; Tests cannot run in an unprivileged build environment.
-      #:tests? #f
+      #:configure-flags #~(list "--with-config=user"
+                                (string-append "--prefix=" #$output)
+                                (string-append "--with-dracutdir=" #$output
+                                               "/lib/dracut")
+                                (string-append "--with-udevdir=" #$output
+                                               "/lib/udev")
+                                (string-append "--with-mounthelperdir=" #$output
+                                               "/sbin"))
       #:phases
       #~(modify-phases %standard-phases
-          (add-after 'configure 'really-configure
-            (lambda* (#:key inputs #:allow-other-keys)
-              (substitute* "configure"
-                (("-/bin/sh") (string-append "-" (which "sh"))))
-              (invoke "./configure"
-                      "--with-config=all"
-                      (string-append "--prefix=" #$output)
-                      (string-append "--with-dracutdir=" #$output
-                                     "/lib/dracut")
-                      (string-append "--with-udevdir=" #$output
-                                     "/lib/udev")
-                      (string-append "--with-mounthelperdir=" #$output
-                                     "/sbin")
-                      (string-append "--with-linux="
-                                     (search-input-directory
-                                      inputs
-                                      "lib/modules/build")))))
           (add-after 'unpack 'patch-source
             (lambda* (#:key inputs #:allow-other-keys)
               ;; New feature "compatibility=" in 2.1.0.
@@ -1631,14 +1616,6 @@  (define-public zfs
                 ;; Just use 'modprobe' in message to user, since Guix
                 ;; does not have a traditional /sbin/
                 (("'/sbin/modprobe ") "'modprobe "))
-              (substitute* "configure"
-                (("/etc/default")
-                 (string-append #$output "/etc/default"))
-                (("/etc/bash_completion.d")
-                 (string-append #$output "/etc/bash_completion.d")))
-              (substitute* "Makefile.in"
-                (("/usr/share/initramfs-tools")
-                 (string-append #$output "/usr/share/initramfs-tools")))
               (substitute* "contrib/initramfs/Makefile.am"
                 (("/usr/share/initramfs-tools")
                  (string-append #$output "/usr/share/initramfs-tools")))
@@ -1668,31 +1645,22 @@  (define-public zfs
                                 (dirname (which "sed")) ":"
                                 (dirname (which "gawk")))))
               (substitute* '("Makefile.am" "Makefile.in")
-                (("\\$\\(prefix)/src") (string-append #$output:src "/src")))
+                (("@initconfdir@") (string-append #$output "/etc/default"))
+                (("/usr/share/initramfs-tools" dir) (string-append #$output dir)))
               (substitute* (find-files "udev/rules.d/" ".rules.in$")
                 (("/sbin/modprobe")
                  (search-input-file inputs "/bin/modprobe")))))
-          (replace 'build
-            (lambda _ (invoke "make")))
           (replace 'install
-            (lambda* (#:key inputs native-inputs #:allow-other-keys)
-              (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
-                (invoke "make" "install"
-                        (string-append "DEFAULT_INITCONF_DIR="
-                                       #$output "/etc/default")
-                        (string-append "DEPMOD="
-                                       (search-input-file
-                                        (or native-inputs inputs)
-                                        "/bin/depmod"))
-                        (string-append "INSTALL_PATH=" #$output)
-                        (string-append "INSTALL_MOD_PATH=" #$output:module)
-                        "INSTALL_MOD_STRIP=1")
-                (install-file
-                 "contrib/bash_completion.d/zfs"
-                 (string-append #$output
-                                "/share/bash-completion/completions"))))))))
+            (lambda _
+              (invoke "make" "install"
+                      (string-append "DEFAULT_INITCONF_DIR="
+                                     #$output "/etc/default")
+                      (string-append "INSTALL_PATH=" #$output)
+                      (string-append "bashcompletiondir="
+                                     #$output
+                                     "/share/bash-completion/completions")))))))
     (native-inputs
-     (list attr kmod pkg-config))
+     (list attr kmod pkg-config python))
     (inputs (list eudev
                   kmod
                   libaio
@@ -1712,6 +1680,58 @@  (define-public zfs
 community.")
     (license license:cddl1.0)))
 
+(define-public (make-zfs-for-kernel kernel-package)
+  (package
+    (inherit zfs)
+    (name (string-join (list (package-name zfs)
+                             "for"
+                             (package-name kernel-package)
+                             (package-version kernel-package)
+                             "version")
+                       "-"))
+    (build-system linux-module-build-system)
+    (arguments
+     (substitute-keyword-arguments
+         (strip-keyword-arguments '(#:configure-flags)
+                                  (package-arguments zfs))
+       ((#:linux _ #f) kernel-package)
+       ((#:substitutable? _ #t) #f)
+       ((#:phases phases)
+        #~(modify-phases %standard-phases
+            (add-after 'unpack 'patch-source
+              (assoc-ref #$phases 'patch-source))
+            (add-after 'configure 'really-configure
+              (lambda* (#:key inputs #:allow-other-keys)
+                (substitute* "configure"
+                  (("-/bin/sh") (string-append "-" (which "sh"))))
+                (invoke "./configure"
+                        "--with-config=kernel"
+                        (string-append "--prefix=" #$output)
+                        (string-append "--with-udevdir=" #$output
+                                       "/lib/udev")
+                        (string-append "--with-linux="
+                                       (search-input-directory
+                                        inputs
+                                        "lib/modules/build")))))
+            (replace 'build
+              (lambda* (#:key (make-flags '()) (parallel-build? #t)
+                        #:allow-other-keys)
+                (apply invoke "make"
+                       `(,@(if parallel-build?
+                               `("-j" ,(number->string (parallel-job-count)))
+                               '())
+                         ,@make-flags))))
+            (replace 'install
+              (lambda* (#:key inputs native-inputs #:allow-other-keys)
+                (let* ((kmod (assoc-ref (or native-inputs inputs) "kmod")))
+                  (invoke "make" "-C" "module" "install"
+                          (string-append "DEPMOD="
+                                         (search-input-file
+                                          (or native-inputs inputs)
+                                          "/bin/depmod"))
+                          (string-append "INSTALL_MOD_PATH=" #$output)
+                          "INSTALL_MOD_STRIP=1"))))))))))
+
 (define-public zfs-auto-snapshot
   (package
     (name "zfs-auto-snapshot")