|
156 | 156 | This assumes the BTRFS filesystem can be found in an LVM volume |
157 | 157 | group called ~root_vg~. Adjust the path as necessary. |
158 | 158 |
|
| 159 | +*** ZFS |
| 160 | + |
| 161 | + Another approach is to use ZFS datasets. Similar to BTRFS |
| 162 | + subvolumes, you can roll the root dataset on each boot by renaming |
| 163 | + it aside and creating a fresh, empty dataset. Old roots are kept |
| 164 | + around, giving you the ability to recover files after a crash or |
| 165 | + power outage. |
| 166 | + |
| 167 | + A setup which would automatically remove roots that are older than |
| 168 | + 30 days could look like this: |
| 169 | + |
| 170 | + #+begin_src nix |
| 171 | + { |
| 172 | + fileSystems."/" = { |
| 173 | + device = "tank/ephemeral/root"; |
| 174 | + fsType = "zfs"; |
| 175 | + }; |
| 176 | + |
| 177 | + boot.initrd.postResumeCommands = lib.mkAfter '' |
| 178 | + # Roll the current root dataset aside, tagged with its creation time |
| 179 | + zfs rename tank/ephemeral/root tank/ephemeral/root-$(date --date=@$(zfs get -Hpo value creation tank/ephemeral/root) "+%Y-%m-%d-%H%M%S") |
| 180 | + |
| 181 | + # Delete old root datasets that are more than 30 days old |
| 182 | + cutoff=$(date -d '30 days ago' '+%s') |
| 183 | + for fs in $(zfs list -Ho name -r tank/ephemeral | grep '^tank/ephemeral/root-'); do |
| 184 | + created=$(zfs get -Hpo value creation "$fs") |
| 185 | + if [ "$created" -lt "$cutoff" ]; then |
| 186 | + zfs destroy -r "$fs" |
| 187 | + fi |
| 188 | + done |
| 189 | + |
| 190 | + # Create a fresh root dataset |
| 191 | + zfs create tank/ephemeral/root |
| 192 | + ''; |
| 193 | + |
| 194 | + fileSystems."/persistent" = { |
| 195 | + device = "tank/persistent"; |
| 196 | + neededForBoot = true; |
| 197 | + fsType = "zfs"; |
| 198 | + }; |
| 199 | + |
| 200 | + fileSystems."/nix" = { |
| 201 | + device = "tank/nix"; |
| 202 | + fsType = "zfs"; |
| 203 | + }; |
| 204 | + |
| 205 | + fileSystems."/boot" = { |
| 206 | + device = "/dev/disk/by-uuid/XXXX-XXXX"; |
| 207 | + fsType = "vfat"; |
| 208 | + }; |
| 209 | + } |
| 210 | + #+end_src |
| 211 | + |
| 212 | + This assumes a ZFS pool called ~tank~ with datasets |
| 213 | + ~tank/ephemeral/root~, ~tank/persistent~, and ~tank/nix~. Adjust |
| 214 | + the pool and dataset names as necessary. |
| 215 | + |
159 | 216 | * Module usage |
160 | 217 |
|
161 | 218 | There are currently two modules: one for NixOS and one for Home Manager. |
|
0 commit comments