Hello I’m still learning a lot of basic linux things and there is definitely a gap in my understanding when I try and read through the common impermanence script for btrfs.
I’m looking at the ones here which are basically the same with minor path tweaks:
But what I’m trying to understand are:
if this script is running before my btrfs volumes are mounted where is “mkdir -p /btrfs_tmp” making this directory?
since impermanence would be starting fresh, why does one person include -p for the possibility of btrfs_tmp already existing? Wouldn’t it certainly not exist on any startup? I understand -p for the old roots folder creation after, but not for the initial btrfs_tmp.
So the script mounts the root subvolume, renames the mounted directory with a timestamp and moves it to old_roots. But that is just making a copy of the data right? It doesn’t change the subvolume name since it’s a command on the mounted directory not the btrfs subvolume? I’m not understanding the interplay here of the first few commands making directories but the later commands calling delete subvolume as if those directories are subvolumes instead of directories.
Probably the same misunderstanding I’m having with 3, in that the final command creates a subvolume named root, but I didn’t see that we ever deleted previous subvolume root, just moved a mounted directory of it.
If anyone can set me straight I would highly appreciate it.
The boot loader loads both the kernel and an “initrd” into memory. The initrd is a file archive with a very small OS’s worth of software. The kernel unpacks this archive into a ram file system that serves as the root file system for “stage 1” of NixOS. This stage uses the software from the initrd to find and mount the “stage 2” root file system (probably your hard drive), before it switches and makes that file system the new root file system so that stage 2 can start from it. Point being, that /btrfs_tmp directory is being made in the ram file system that serves as the stage 1 root file system.
Yea that just isn’t necessary.
This isn’t really how btrfs works. A subvolume is a directory. When you do mount /dev/pool/root /btrfs_tmp, you’re mounting the file system’s root directory, and the subvolumes are not mountpoints within it. They’re just directories with special btrfs characteristics. You can also mount a btrfs file system’s individual subvol with the right mount options, but this is not (meaningfully) different from just mounting the root of the btrfs in a hidden place and bind mounting the subvol directory to the mountpoint. The point is, when you mount /dev/pool/root /btrfs_tmp and move the directory that a subvol exists at in that mountpoint, you are actually literally moving the subvolume within the btrfs root.
I think another thing tripping me up is that my disko config I defined a subvolume named root, mounted at /, but in this script I’m making a temporary directory at btrfs’s root /, so it’s like I have root inside root. But if I’m understanding right that’s because of the stage 1 RAM version of root, and as the boot process proceeds the RAM root will go away and I will be left with the subvolume root that the uncompressed OS kernel will be put on.
Or this goes beyond the stage 1 RAM aspect, and there is still a meaningful difference between btrfs’s root and the subvolume root that Nix will use even past stage 1 of boot?
The difference between stage 1’s root fs and stage 2’s root fs has nothing to do with the difference between the btrfs root directory and the subvolume root directory. Like I said, a btrfs subvolume is a directory in the btrfs root directory. When I say “btrfs root directory”, I mean “the root of this particular file system”, not “the root of the OS as a whole”. When you create a btrfs file system, it contains one root directory, in which everything else inside the file system exists.
This has created a btrfs file system and a sub subvolume that exists as the directory sub relative to the btrfs root directory /mnt. i.e. /mnt/sub/ is the subvolume, while /mnt/ is the btrfs root directory.
When you mount a subvolume, you’re mounting just the subvolume directory and hiding the stuff above it.
umount /mnt
mount -o subvol=sub /dev/foo /mnt
stat /mnt/file-in-subvolume
We no longer need to access the files in the subvolume using the sub directory, because that directory has been mounted at /mnt instead.
The kernel is in memory. That never changes. The OS root file system for stage 1 is also in memory and it is made up of the contents of the initrd. During stage 1 the OS does things like mounting other file systems at subdirectories under the stage 1 OS root directory. But eventually the OS transitions into stage 2 by making one of those other file systems the new OS root directory, at which point the RAM file system that served as stage 1’s OS is forgotten.