{"id":16333708,"url":"https://github.com/dasj/sd-zfs","last_synced_at":"2025-03-20T23:30:35.243Z","repository":{"id":52358864,"uuid":"64948042","full_name":"dasJ/sd-zfs","owner":"dasJ","description":"Compatibility between systemd and ZFS roots","archived":false,"fork":false,"pushed_at":"2021-04-30T13:57:29.000Z","size":64,"stargazers_count":43,"open_issues_count":11,"forks_count":13,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-01T00:53:31.043Z","etag":null,"topics":["boot","initrd","mkinitcpio","pool","sd-zfs","snapshot","systemd","systemd-unit","zfs","zfsonlinux"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dasJ.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-04T15:56:47.000Z","updated_at":"2024-08-25T20:23:12.000Z","dependencies_parsed_at":"2022-09-07T19:51:28.941Z","dependency_job_id":null,"html_url":"https://github.com/dasJ/sd-zfs","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dasJ%2Fsd-zfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dasJ%2Fsd-zfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dasJ%2Fsd-zfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dasJ%2Fsd-zfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dasJ","download_url":"https://codeload.github.com/dasJ/sd-zfs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244088997,"owners_count":20396207,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boot","initrd","mkinitcpio","pool","sd-zfs","snapshot","systemd","systemd-unit","zfs","zfsonlinux"],"created_at":"2024-10-10T23:36:19.530Z","updated_at":"2025-03-20T23:30:34.970Z","avatar_url":"https://github.com/dasJ.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sd-zfs\n\nThis project is an attempt to allow using systemd in the initrd and also having a ZFS dataset as root.\nIt is intended for [mkinitcpio](https://git.archlinux.org/mkinitcpio.git/) (used by [Arch Linux](https://www.archlinux.org/)) but should also work with other systems.\nYou are expected to already have a root filesystem on a ZFS dataset.\n\nPlease note that legacy root mounts are not supported because they are legacy technology (as the name implies).\n\n## Functionality\n- Boot from any ZFS dataset. All subdatasets are mounted as well\n- Use `bootfs` to decide what dataset to use\n- Use zpool.cache for pool caching (can be overridden)\n- Included udev rules for importing by vdev\n- All pools are exported on shutdown\n- root is mounted as read-only when `rw` is not set on command line\n- Actual hostid value is used when it's not found in `/etc/hostid`\n- `/etc/modprobe.d/{spl,zfs}.conf` is included in initrd\n\n## Snapshot booting\n`sd-zfs` supports booting from ZFSsnapshots.\nAs snapshots are read-only and not bootable, they are automatically cloned to new datasets which are booted.\nAll subdatasets wil be checked for the same snapshot.\n\nExample:\n- Boot with root=ZFS=tank/root@snap\n- The following datasets with the following snapshots exist:\n```\ntank/root\ntank/root@snap\ntank/root/etc\ntank/root/etc@snap\n```\n- When booting, the following datasets are created (**they get deleted before creating if they exist**):\n```\ntank/root_initrd_snap\ntank/root_initrd_snap/etc\n```\n- `sd-zfs` will boot from `tank/root_initrd_snap`\n\n## Installation\nGet [mkinitcpio-sd-zfs](https://aur.archlinux.org/packages/mkinitcpio-sd-zfs/) from the [AUR](https://wiki.archlinux.org/index.php/Arch_User_Repository).\nUsers without Arch should read the manual installation instructions at the bottom of this document.\n**sd-zfs is not ready for use yet. You need to configure it first.**\n\n## Configuration\n\n### Kernel parameters\nsd-zfs supports multiple kernel parameters to select what dataset to boot from and to tune the booting process.\n\n#### Which dataset to boot from\n- `root=ZFS=somepool/somedataset` - Use this dataset to boot from\n- `root=ZFS=AUTO` - Check all pools for the bootfs value. See rpool to narrow the search\n- `rpool=somepool` - Check only this pool for the bootfs value. This may not contain slashes\n\nThe root option can be suffixed with `@snap` to boot from a snapshot named `snap`.\nSee \"Snapshot booting\" for more information.\n\n#### Other options\n- `rootflags=flags` - Use these flags when mounting the dataset\n- `zfs_force=1` - Force import of the pools\n- `zfs_ignorecache=1` - Ignore the pool cache file while booting\n\n### Bootfs\nsd-zfs can use the bootfs value of your zpools.\nThis is an property of ZFS pools which is intended to point to the root filesystem that is used for booting.\nYou need to set it on any pool (the pool with the root fielsystem is recommended).\nIf you set it to different values on multiple pools, the first one that is found will be used.\n\nCheck the bootfs value of all pools:\n```\n# zpool get -p bootfs\nNAME   PROPERTY  VALUE   SOURCE\ntank   bootfs    -       default\n```\n\nSet the bootfs value:\n```\n# zpool set bootfs=tank/root tank\n```\n\nThis will make the system boot from the dataset \"`root`\" of the pool \"`tank`\".\n\n**The `mountpoint` value of the dataset needs to be `/`.**\n\n### Custom module options\nIf you have any options for the SPL and ZFS modules, you can add them to `/etc/modprobe.d/zfs.conf` and `/etc/modprobe.d/spl.conf`.\nThese files will be included into the initrd if they exist during initrd build.\n\n### mkinitcpio.conf\nAdd `sd-zfs` to the `HOOK` array of `/etc/mkinitcpio.conf`.\nAs it depends on the `systemd` hook, it needs to come after it.\nThere are no more dependencies than `systemd`.\n\n### Cache file\nWhen booting the system, all devices are scanned to check for pools.\nDepending on the number of devices you have, it can be faster to cache the pools.\nThis is accomplished by using the standard ZFS `cachefile`, which will be created at `/etc/zfs/zpool.cache`.\nIf it exists during creation of the initrd, it will be included.\n\n### Hostid\nIf `/etc/hostid` exists during build, it will be included in the initrd.\nIt is highly recommended to use this file.\nMore information is found in the [Arch wiki](https://wiki.archlinux.org/index.php/Installing_Arch_Linux_on_ZFS#After_the_first_boot).\nIf the file is not found, the actual value of the `hostid` command will be written to the initrd.\n\n### Rebuilding initrd\nAfter changing any of these mkinitcpio related things (apart from the kernel command line and the bootfs value), you need to rebuild your initrd.\nAssuming you have the default `linux` package, you can just run:\n```\n# mkinitcpio -p linux\n```\nIf you use another kernel (like `linux-lts`), you need to adapt the command.\n\n## How it works\n\n### Generating\nWhen systemd is starting, all generators are run, this includes a generator for ZFS units.\nThis generator parses the kernel parameters and creates systemd services for importing the pools as well as overriding `sysroot.mount` which is responsible for mounting the root filesystem.\n\n### Importing\nWhen systemd is running, the pools are imported (without actually mounting them).\n\nThere are two ways to import the pools:\n\n#### By scan\nIf no cachefile exists, all devices in `/etc/disk/by-id` are scanned and all pools that imported without actually mounting them.\nThis can be forced via kernel parameter.\n\n#### By cachefile\nIf the cachefile exists, all devices from the cachefile are imported without actually mounting them.\nThis can be prevented via kernel parameter.\n\n### Mounting\nThe systemd unit `sysroot.mount` is overriden so it will run a custom command.\nThis command figures out the bootfs (if `ZFS=AUTO` is used) and handles snapshot creation.\nIt proceeds to mount the correct dataset, including all subdatasets.\n\n### Switching root\nsystemd will now take care of killing all processes and switching root to `/sysroot`.\n\n### Shutdown\nWhen shutting down, systemd pivots back to another ramdisk.\nAll executables from `/usr/lib/systemd/system-shutdown` are run.\nOne of them is provided by this package and is responsible for forcefully exporting all pools.\nTo accomplish that, `zpool` is added to the ramdisk via a systemd unit.\n\n## Manual installation\nSee `mkinitcpio-install/sd-zfs`, which instructs `mkinitcpio` what to do.\n`$BUILDROOT` is the root of the initrd that is currently being built.\nYou need to `make all` and put the resulting files to the locations mentioned in the install file.\n\n`mkinitcpio-install/sd-zfs-shutdown` is responsible for copying `zpool` to the ramdisk on shutdown.\nThis is required for `zfs-shutdown`.\n\n## Warranty\nNope.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdasj%2Fsd-zfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdasj%2Fsd-zfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdasj%2Fsd-zfs/lists"}