DRACUT.ZFS(7)

πŸ“¦
version 2.4.4 Β· 6 versions
, in alpine 3.23, alpine 3.24, nixos 26.05, nixpkgs unstable, ubuntu resolute, ubuntu stonking

πŸ’– DRACUT.ZFS πŸ’–

okay bestie, this is dracut.zfs(7) from the Miscellaneous Information Manual β€” it's the whole tea on ZFS dracut hooks. grab a snack, this one's a bop 🫢


✨ NAME ✨

dracut.zfs β€” the ~overview~ of ZFS dracut hooks πŸ’…


✨ SYNOPSIS ✨

here's the flowchart, and no I'm not paraphrasing it, it's art:

                             parse-zfs.sh β†’ dracut-cmdline.service
                                 |                     ↓
                                 |                     …
                                 |                     ↓
                                 \β€”β€”β€”β€”β€”β€”β€”β€”β†’ dracut-initqueue.service
                                                       |                      zfs-import-opts.sh
          zfs-load-module.service                      ↓                          |       |
            |                  |                sysinit.target                    ↓       |
            ↓                  |                       |        zfs-import-scan.service   ↓
       zfs-import-scan.service ↓                       ↓           | zfs-import-cache.service
            |   zfs-import-cache.service         basic.target      |     |
            \__________________|                       |           ↓     ↓
                               ↓                       |     zfs-load-key.sh
            zfs-env-bootfs.service                     |         |
                               ↓                       ↓         ↓
                        zfs-import.target β†’ dracut-pre-mount.service
                               |          ↑            |
                               | dracut-zfs-generator  |
                               | _____________________/|
                               |/                      ↓
                               |                   sysroot.mount ←——— dracut-zfs-generator
                               |                       |
                               |                       ↓
                               |             initrd-root-fs.target ←— zfs-nonroot-necessities.service
                               |                       |                                 |
                               |                       ↓                                 |
                               ↓             dracut-mount.service                        |
              zfs-snapshot-bootfs.service              |                                 |
                               |                       ↓                                 |
                               ↓                       …                                 |
              zfs-rollback-bootfs.service              |                                 |
                               |                       ↓                                 |
                               |          /sysroot/{usr,etc,lib,&c.} ←———————————————————/
                               |                       |
                               |                       ↓
                               |                initrd-fs.target
                               \______________________ |
                                                      \|
                                                       ↓
               export-zfs.sh                      initrd.target
                     |                                 |
                     ↓                                 ↓
          dracut-shutdown.service                      …
                                                       |
                                                       ↓
                        zfs-needshutdown.sh β†’ initrd-cleanup.service

also go compare dracut.bootup(7) for the full flowchart, iykyk 🌈


✨ DESCRIPTION ✨

so under dracut, booting with ZFS-on-/ is handled by a bunch of hooks living in the 90zfs module. πŸ’…

to boot into a ZFS dataset you need mountpoint=/ set on the dataset that holds the root filesystem (we're calling that "the boot dataset" from here on, bestie) β€” and at the absolute bare minimum you also need either the bootfs property pointing at that dataset, or the root= kernel cmdline (or a dracut drop-in) to name it. no cap. 🫢

every child of the boot dataset with canmount=on whose mountpoints match the /etc, /bin, /lib, /lib??, /libx32, and /usr globs is deemed essential and gets mounted too. periodt. πŸ‘‘

and fr fr, zfs-mount-generator(8) is recommended if you want the system to actually behave afterward (correct mount properties, remounting, &c.). the vibes depend on it. ✨


✨ CMDLINE ✨

πŸŽ€ Standard

  • root=zfs:dataset, root=ZFS=dataset β€” use dataset as the boot dataset. every single plus sign (+) gets swapped for a space ( ). πŸ¦‹
  • root=zfs:AUTO, root=zfs:, root=zfs, [root=] β€” after import, go hunt down the first pool that has the bootfs property set, and use its value exactly as-if you'd specified it as the dataset above. ✨
  • rootfstype=zfs root=dataset β€” equivalent to root=zfs:dataset.
  • rootfstype=zfs [root=] β€” equivalent to root=zfs:AUTO.
  • rootflags=flags β€” mount the boot dataset with -o flags; cf. "Temporary Mount Point Properties" in zfsprops(7). heads up though β€” these properties will not last, because all filesystems get re-mounted from the real root. it's giving temporary. πŸ’€
  • debug β€” if you specify it, dracut-zfs-generator logs to the journal. πŸ‘€
⚠️ bestie be careful β€” if you set neither rootfstype=zfs nor root=zfs:dataset, other automatic boot selection methods like systemd-gpt-auto-generator and systemd-fstab-generator might take precedent. don't get sniped. 😭

πŸŽ€ ZFS-specific

  • bootfs.snapshot[=snapshot-name] β€” runs zfs snapshot boot-dataset@snapshot-name before pivoting to the real root. snapshot-name defaults to the current kernel release. πŸ“Έ
  • bootfs.rollback[=snapshot-name] β€” runs zfs rollback -Rf boot-dataset@snapshot-name before pivoting to the real root. snapshot-name defaults to the current kernel release. βͺ
  • spl_hostid=host-id β€” uses zgenhostid(8) to set the host ID to host-id; otherwise, /etc/hostid inherited from the real root is used. πŸͺͺ
  • zfs_force, zfs.force, zfsforce β€” appends -f to all zpool import invocations; primarily useful together with spl_hostid=, or if no host ID was inherited at all. πŸ’ͺ

✨ FILES ✨

  • parse-zfs.sh (cmdline) β€” processes spl_hostid=. if root= matches a known pattern from above, it provides /dev/root and delays the initqueue until zfs(4) is loaded. ⏳
  • zfs-import-opts.sh (systemd environment generator) β€” turns zfs_force, zfs.force, or zfsforce into ZPOOL_IMPORT_OPTS=-f for zfs-import-scan.service or zfs-import-cache.service. πŸ”§
  • zfs-load-key.sh (pre-mount) β€” loads encryption keys for the boot dataset and its essential descendants:
    • keylocation=prompt β€” is prompted for via systemd-ask-password thrice. πŸ™ˆ
    • keylocation=https://URL, keylocation=http://URL β€” network-online.target is started before loading. 🌐
    • keylocation=file://path β€” if path doesn't exist, udevadm is settled. if it still doesn't exist, it's waited for for up to 10s. ⏱️
  • zfs-env-bootfs.service (systemd service) β€” after pool import, sets BOOTFS= in the systemd environment to the first non-null bootfs value in iteration order. 🎯
  • dracut-zfs-generator (systemd generator) β€” generates sysroot.mount (using rootflags=, if any). if an explicit boot dataset was specified, it also generates the essential mountpoints (sysroot-etc.mount, sysroot-bin.mount, &c.); otherwise it generates zfs-nonroot-necessities.service, which mounts them explicitly after /sysroot using BOOTFS=. πŸ› οΈ
  • zfs-snapshot-bootfs.service, zfs-rollback-bootfs.service (systemd services) β€” consume bootfs.snapshot and bootfs.rollback as described in "CMDLINE". they use BOOTFS= if no explicit boot dataset was specified. πŸ”
  • zfs-needshutdown.sh (cleanup) β€” if any pools were imported, it signals that shutdown hooks are required. 🚨
  • export-zfs.sh (shutdown) β€” forcibly exports all pools. bye bestie πŸ‘‹
  • /etc/hostid, /etc/zfs/zpool.cache, /etc/zfs/vdev_id.conf (regular files) β€” included verbatim, hostonly. πŸ“„
  • mount-zfs.sh (mount) β€” does nothing on systemd systems (if dracut-zfs-generator succeeded). otherwise, it loads the encryption key for the boot dataset from the console or via plymouth. and honestly? it may not work at all! 😭

✨ SEE ALSO ✨

dracut.bootup(7), zfsprops(7), zpoolprops(7), dracut-shutdown.service(8), systemd-fstab-generator(8), systemd-gpt-auto-generator(8), zfs-mount-generator(8), zgenhostid(8)


okay that's the whole thing, you ate that πŸ’… this was OpenZFS, dated July 13, 2024 β€” go forth and boot, main character. πŸ‘‘πŸŒΈπŸ¦‹

πŸ“¦ where this page comes from