guix-devel
[Top][All Lists]
Advanced

[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`.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]