[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ZFS on Guix
From: |
raid5atemyhomework |
Subject: |
Re: ZFS on Guix |
Date: |
Mon, 08 Feb 2021 06:13:39 +0000 |
Hi guix-developers and users,
Here are some notes I made about how to get `/` on ZFS, maybe someone else can
think about it.
-------
Most importantly, it seems for this style we need to consider first `/boot`
***not*** on ZFS, and have `/` on ZFS. I presume grub has some way to read
ZFS pools in order to get at the `/boot` if `/boot` is on ZFS, since
`/`-on-ZFS for Ubuntu is able to put even `/boot` on ZFS, however note that
even there the `/boot` is on a different pool from the `/`.
When this works (*cough*) it should be possible to create a ZFS pool (with
`mountpoint=legacy`) from a ZFS-enabled boot of Guix, then create a
`configuration.scm` that we would then `sudo guix system init` onto a
temporary mountpoint. I would strongly suggest putting `/boot` elsewhere
though.
Here are a bunch of things we need for `/` on ZFS:
* ZFS module installing into `initrd`.
* ZFS module loading while in `initrd` before the pivot to the "real" `/`.
* ZFS `import` of the pool containing `/` mount.
## `initrd` module installation
We need a facility to add modules to the `initrd` that are not
part of the kernel. Currently `raw-initrd`/`base-initrd` will
only get `.ko` files from the given `linux` package. We need
to modify the `initrd` interface to add say a `#:module-packages`
list of packages whose `.ko` files we will also add to the `initrd`.
This translates to modifying `flat-linux-module-directory` in
`gnu/system/linux-initrd.scm` to additionally accept a list of packages
all of whose `.ko` and/or `.ko.gz` files will be added to the module
directory. Then somewhere over in `raw-initrd` we would:
(define kodir
(flat-linux-module-directory linux linux-modules module-packages))
We also need an extensible service type that will eventually lead to
adding new entries in the `#:module-packages`.
We need a "root" `initrd` extensible service type that will construct the
`initrd`
via the `operating-system-initrd` field. This service type will accept
additional arguments to pass to the `initrd` function. Then the
`initrd-kernel-loadable-module-service-type` would accept lists of package
specifications, then provide a `#:module-packages` argument to the root
`initrd` service type.
Rough sketch:
(define initrd-arguments-service-type (service-type #;...))
(define initrd-kernel-loadable-module-service-type
(service-type
(name 'initrd-kernel-loadable-module-service-type)
(extensions (list (service-extension
initrd-arguments-service-type
(lambda (module-packages)
(if (null? module-packages)
'()
(list #:module-packages module-packages))))))
(compose concatenate)
(extend append)
(default-value '())))
## `initrd` module explicit loading
Normally modules are loaded "as needed" but ZFS needs to be explicitly loaded.
The `base-initrd` already accepts a list of `linux-modules` to load, we just
need some way to hook into adding `#:linux-modules`. This probably means
modifying how `operating-system-initrd-file` in `(gnu system)` works (which
would probably be needed by the `initrd-arguments-service-type` anyway).
We could try hooking into the currently-deprecated `extra-modules` instead,
here's a sketch:
(define initrd-kernel-module-loader-service-type
(service-type
(name 'initrd-kernel-module-loader-service-type)
(extensions (list (service-extension
initrd-arguments-service-type
(lambda (modules)
(if (null? modules)
'()
(list #:extra-modules modules))))))
(compose concatenate)
(extend append)
(default-value '())))
## `initrd` additional pre-mount actions
Before a `/` on ZFS can be mounted, ZFS has to be told to scan for the
ZFS pool containing the `/`.
We could add yet another argument to `raw-initrd`/`base-initrd`,
`#:premount-actions`,
a list of gexpressions.
Then the `#:pre-mount` argument to `boot-system` would become something like:
#:pre-mount (lambda ()
(and #$@device-mapping-commands
#$@premount-actions))
As usual a service type can be created which extends
`initrd-arguments-service-type`.
For root-on-ZFS specifically we would need to know the root pool and execute
something
like this:
#~(begin
(invoke/quiet #$(file-append zfs/static "/sbin/zpool") "-a" "-N"
#$root-pool))
Then, "normal" root specification would be done, with the root pool name given
as the
device name of the `/` mountpoint, and with the ZFS mountpoint set to `legacy`.