Venom1991 / refind-btrfs

Generate rEFInd manual boot stanzas from Btrfs snapshots
GNU General Public License v3.0
144 stars 8 forks source link

Couldn't find boot stanza matched with root partition #10

Closed Barbaross93 closed 3 years ago

Barbaross93 commented 3 years ago

Hey there, Thanks for this tool! Refind is so much nicer to work with than GRUB in this day and age. Unfortunately, I can't seem to get this to work. I get the following output/error message when I run sudo refind-btrfs:

Initializing the block devices using lsblk.
Initializing the physical partition table for device '/dev/sda' using lsblk.
Initializing the live partition table for device '/dev/sda' using findmnt.
Initializing the physical partition table for device '/dev/sdb' using lsblk.
Initializing the live partition table for device '/dev/sdb' using findmnt.
Initializing the physical partition table for device '/dev/sdc' using lsblk.
Initializing the live partition table for device '/dev/sdc' using findmnt.
Initializing the physical partition table for device '/dev/sdd' using lsblk.
Initializing the live partition table for device '/dev/sdd' using findmnt.
Initializing the physical partition table for device '/dev/sde' using lsblk.
Initializing the live partition table for device '/dev/sde' using findmnt.
Initializing the physical partition table for device '/dev/sdf' using lsblk.
Initializing the live partition table for device '/dev/sdf' using findmnt.
Initializing the physical partition table for device '/dev/sdg' using lsblk.
Initializing the live partition table for device '/dev/sdg' using findmnt.
Found the ESP mounted at '/boot/efi' on '/dev/sdc1'.
Found the root partition on '/dev/mapper/cryptroot'.
Found a separate boot partition on '/dev/sdc2'.
Searching for snapshots of the '@' subvolume in the '/.snapshots' directory.
Found subvolume '@' mounted as the root partition.
Found 88 snapshots of the '@' subvolume.
Searching for the 'refind.conf' file on '/dev/sdc1'.
Analyzing the 'refind.conf' file.
ERROR (refind_btrfs.state_management.conditions/conditions.py/check_matched_boot_stanzas): Could not find a boot stanza matched with the root partition!

I have this stanza defined in my refind.conf:

menuentry "Arch Linux" {
    icon     /EFI/refind/themes/refind-black/icons/os_arch.png
    volume   Arch
    loader   /@/boot/vmlinuz-linux
    initrd   /@/boot/initramfs-linux.img
    options  "root=UUID=bb313edb-4aba-4ac4-985d-d7cfec425604 rw rootflags=subvol=@ cryptdevice=UUID=3e2000ae-4aab-4ae6-af8f-8f4a12341f43:cryptroot initrd=amd-ucode.img quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0 nvidia-drm.modeset=1  resume=UUID=bb313edb-4aba-4ac4-985d-d7cfec425604 resume_offset=13737151"
    submenuentry "Boot using fallback initramfs" {
        initrd @/boot/initramfs-linux-fallback.img
    }
    submenuentry "Boot to terminal" {
        add_options "systemd.unit=multi-user.target"
    }
    submenuentry "single user mode" {
    add_options "single"
    }
}

It's probably something simple, but I can't for the life of me figure out what I'm missing here. In case it's necessary info, /dev/sdc3 or otherwise the root partition is encrypted.

Venom1991 commented 3 years ago

Hm, there was a similar issue some time ago (check that user's stanza in the first post). But, there the /boot and the ESP were one and the same. I don't really think you need the subvolume path prefix defined for your "loader" and "initrd" fields considering these files most probably don't reside in a subvolume at all (nor in any of the snapshots, consequently) - unless I'm missing something here? I haven't checked its source code but I suppose rEFInd just silently reverts to standard ("non-subvolume", so to speak) paths in case it cannot find anything there.
Either way, these fields wont be changed and will remain the same due to /boot being a separate partition. Only the "rootflags=subvol=@" will be changed once we figure out what is wrong.

This stanza should probably work just as fine, I believe:

menuentry "Arch Linux" {
    icon     /EFI/refind/themes/refind-black/icons/os_arch.png
    volume   Arch
    loader   /vmlinuz-linux
    initrd   /initramfs-linux.img
    options  "root=UUID=bb313edb-4aba-4ac4-985d-d7cfec425604 rw rootflags=subvol=@ cryptdevice=UUID=3e2000ae-4aab-4ae6-af8f-8f4a12341f43:cryptroot initrd=\amd-ucode.img quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0 nvidia-drm.modeset=1 resume=UUID=bb313edb-4aba-4ac4-985d-d7cfec425604 resume_offset=13737151"
    submenuentry "Boot using fallback initramfs" {
        initrd /initramfs-linux-fallback.img
    }
    submenuentry "Boot to terminal" {
        add_options "systemd.unit=multi-user.target"
    }
    submenuentry "single user mode" {
        add_options "single"
    }
}

I've removed the subvolume prefixes and added the "\" prefix to the microcode image path (more "correct" way of defining it, I think). It could be that I got this wrong and your stanza is just fine (that is, the way you've defined it shouldn't be an issue) but I don't really understand the need for a subvolume prefix, to be honest.

Lastly (and most importantly), I'm going to need the output of the following commands:

lsblk --json --merge --paths --output NAME,TYPE,MAJ:MIN
lsblk /dev/sdc --json --paths --tree --output PTUUID,PTTYPE,PARTUUID,PARTTYPE,PARTLABEL,UUID,NAME,FSTYPE,LABEL,MOUNTPOINT
findmnt --json --mtab --real --nofsroot --output PARTUUID,PARTLABEL,UUID,SOURCE,FSTYPE,LABEL,TARGET,OPTIONS
Barbaross93 commented 3 years ago

Thanks for the response! Unfortunately the stanza changes aren't enough. Still getting the same error. In regards to paths, you're probably right. I was basing my stanza off of https://github.com/Venom1991/refind-btrfs/issues/5. Here's the output of those commands: lsblk --json --merge --paths --output NAME,TYPE,MAJ:MIN:

{
   "blockdevices": [
      {"name":"/dev/sda", "type":"disk", "maj:min":"8:0",
         "children": [
            {"name":"/dev/sda1", "type":"part", "maj:min":"8:1"}
         ]
      },
      {"name":"/dev/sdb", "type":"disk", "maj:min":"8:16",
         "children": [
            {"name":"/dev/sdb1", "type":"part", "maj:min":"8:17"},
            {"name":"/dev/sdb2", "type":"part", "maj:min":"8:18"}
         ]
      },
      {"name":"/dev/sdc", "type":"disk", "maj:min":"8:32",
         "children": [
            {"name":"/dev/sdc1", "type":"part", "maj:min":"8:33"},
            {"name":"/dev/sdc2", "type":"part", "maj:min":"8:34"},
            {"name":"/dev/sdc3", "type":"part", "maj:min":"8:35",
               "children": [
                  {"name":"/dev/mapper/cryptroot", "type":"crypt", "maj:min":"254:0"}
               ]
            }
         ]
      },
      {"name":"/dev/sdd", "type":"disk", "maj:min":"8:48",
         "children": [
            {"name":"/dev/sdd1", "type":"part", "maj:min":"8:49"}
         ]
      },
      {"name":"/dev/sde", "type":"disk", "maj:min":"8:64",
         "children": [
            {"name":"/dev/sde1", "type":"part", "maj:min":"8:65"},
            {"name":"/dev/sde2", "type":"part", "maj:min":"8:66"}
         ]
      },
      {"name":"/dev/sdf", "type":"disk", "maj:min":"8:80",
         "children": [
            {"name":"/dev/sdf1", "type":"part", "maj:min":"8:81"},
            {"name":"/dev/sdf2", "type":"part", "maj:min":"8:82"}
         ]
      },
      {"name":"/dev/sdg", "type":"disk", "maj:min":"8:96",
         "children": [
            {"name":"/dev/sdg1", "type":"part", "maj:min":"8:97"},
            {"name":"/dev/sdg2", "type":"part", "maj:min":"8:98"},
            {"name":"/dev/sdg3", "type":"part", "maj:min":"8:99"},
            {"name":"/dev/sdg4", "type":"part", "maj:min":"8:100"}
         ]
      }
   ]
}

lsblk /dev/sdc --json --paths --tree --output PTUUID,PTTYPE,PARTUUID,PARTTYPE,PARTLABEL,UUID,NAME,FSTYPE,LABEL,MOUNTPOINT

{
   "blockdevices": [
      {"ptuuid":"313b7b11-dbe0-c540-8eea-aca4ce3af209", "pttype":"gpt", "partuuid":null, "parttype":null, "partlabel":null, "uuid":null, "name":"/dev/sdc", "fstype":null, "label":null, "mountpoint":null,
         "children": [
            {"ptuuid":"313b7b11-dbe0-c540-8eea-aca4ce3af209", "pttype":"gpt", "partuuid":"f56f0f68-0178-f846-b741-a77adea70034", "parttype":"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", "partlabel":null, "uuid":"6B73-4584", "name":"/dev/sdc1", "fstype":"vfat", "label":null, "mountpoint":"/boot/efi"},
            {"ptuuid":"313b7b11-dbe0-c540-8eea-aca4ce3af209", "pttype":"gpt", "partuuid":"5e12b151-2817-1b4b-87c0-08c48752878a", "parttype":"0fc63daf-8483-4772-8e79-3d69d8477de4", "partlabel":"Arch", "uuid":"ccbdf408-e3d9-40ed-812b-8d11db9d7b64", "name":"/dev/sdc2", "fstype":"btrfs", "label":null, "mountpoint":"/boot"},
            {"ptuuid":"313b7b11-dbe0-c540-8eea-aca4ce3af209", "pttype":"gpt", "partuuid":"c194c58b-71c1-c140-8321-dbe02da140a8", "parttype":"0fc63daf-8483-4772-8e79-3d69d8477de4", "partlabel":null, "uuid":"3e2000ae-4aab-4ae6-af8f-8f4a12341f43", "name":"/dev/sdc3", "fstype":"crypto_LUKS", "label":null, "mountpoint":null,
               "children": [
                  {"ptuuid":null, "pttype":null, "partuuid":null, "parttype":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "name":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "mountpoint":"/var/tmp"}
               ]
            }
         ]
      }
   ]
}

findmnt --json --mtab --real --nofsroot --output PARTUUID,PARTLABEL,UUID,SOURCE,FSTYPE,LABEL,TARGET,OPTIONS

{
   "filesystems": [
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=256,subvol=/@"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/.snapshots", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=259,subvol=/@snapshots"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/home", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=257,subvol=/@home"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/var", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=258,subvol=/@var"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/swap", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=264,subvol=/@swap"},
      {"partuuid":"5e12b151-2817-1b4b-87c0-08c48752878a", "partlabel":"Arch", "uuid":"ccbdf408-e3d9-40ed-812b-8d11db9d7b64", "source":"/dev/sdc2", "fstype":"btrfs", "label":null, "target":"/boot", "options":"rw,relatime,ssd,space_cache,subvolid=5,subvol=/"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/var/log", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=262,subvol=/@var/log"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/var/spool", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=261,subvol=/@var/spool"},
      {"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/var/tmp", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=260,subvol=/@var/tmp"},
      {"partuuid":"f56f0f68-0178-f846-b741-a77adea70034", "partlabel":null, "uuid":"6B73-4584", "source":"/dev/sdc1", "fstype":"vfat", "label":null, "target":"/boot/efi", "options":"rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro"}
   ]
}
Venom1991 commented 3 years ago

I believe that the following line is causing the error (findmnt output's / partition):

{"partuuid":null, "partlabel":null, "uuid":"bb313edb-4aba-4ac4-985d-d7cfec425604", "source":"/dev/mapper/cryptroot", "fstype":"btrfs", "label":null, "target":"/", "options":"rw,noatime,compress-force=zstd:3,ssd,space_cache=v2,subvolid=256,subvol=/@"}

The filesystem label ("label" property) is null and cannot be matched with the "volume" field that you've defined in your stanza ("Arch"). Compare your output with this one, for instance.
Unfortunately, in your case both the "partuuid" and the "partlabel" properties are also null which means that you cannot use them either in your stanza. From rEFInd's documentation (regarding the "volume" field): "You pass this token a filesystem's label, a partition's label, or a partition's GUID."
Is it perhaps possible to define a filesystem label AFTER it's already been created (formatted, that is)? A quick Google search came up with this. I've never had to do this because I always use the -L option when creating the filesystem - for instance: "mkfs.btrfs -L some_label ...".

Barbaross93 commented 3 years ago

You were right! Turned out to be an easy fix using

sudo cryptsetup config /dev/sdc3 --label ArchLinux

And then renaming the volume as "ArchLinux" in the stanza. Unfortunately, I'm hit with another error:

Initializing the block devices using lsblk.
Initializing the physical partition table for device '/dev/sda' using lsblk.
Initializing the live partition table for device '/dev/sda' using findmnt.
Initializing the physical partition table for device '/dev/sdb' using lsblk.
Initializing the live partition table for device '/dev/sdb' using findmnt.
Initializing the physical partition table for device '/dev/sdc' using lsblk.
Initializing the live partition table for device '/dev/sdc' using findmnt.
Initializing the physical partition table for device '/dev/sdd' using lsblk.
Initializing the live partition table for device '/dev/sdd' using findmnt.
Initializing the physical partition table for device '/dev/sde' using lsblk.
Initializing the live partition table for device '/dev/sde' using findmnt.
Initializing the physical partition table for device '/dev/sdf' using lsblk.
Initializing the live partition table for device '/dev/sdf' using findmnt.
Initializing the physical partition table for device '/dev/sdg' using lsblk.
Initializing the live partition table for device '/dev/sdg' using findmnt.
Found the ESP mounted at '/boot/efi' on '/dev/sdc1'.
Found the root partition on '/dev/mapper/cryptroot'.
Found a separate boot partition on '/dev/sdc2'.
Searching for snapshots of the '@' subvolume in the '/.snapshots' directory.
Found subvolume '@' mounted as the root partition.
Found 70 snapshots of the '@' subvolume.
Searching for the 'refind.conf' file on '/dev/sdc1'.
Found 1 boot stanza matched with the root partition.
Initializing the static partition table for subvolume '@snapshots/413/snapshot' from its fstab file.
ERROR (refind_btrfs.state_management.refind_btrfs_machine/refind_btrfs_machine.py/run): The 'subvol' mount option cannot be defined multiple times!

I checked my /etc/fstab file and indeed, I had somehow defined subvol twice as a mount option for all subvolumes. I removed the duplicates, in /etc/fstab but I'm still getting the same error. Do I need to remove all of my snapshots and create a new one? It seems like my snapshots are "tainted" with this error

Venom1991 commented 3 years ago

Unfortunately, they are messed up (genfstab is usually the culprit, AFAIK). Instead of deleting them you could just create a new one (whose fstab should now be fine) and set the "selection_count" to 1 in the refind-btrfs.conf file. After that, slowly increase that number as new snapshots are periodically taken, up to a certain reasonable value (I keep mine at 5, which is the default).

Barbaross93 commented 3 years ago

So your suggestion worked, but I ran into some problems. When trying to boot the manual stanza, I kept getting errors that the loader file vmlinuz-linux was invalid. At first, I thought it was because I indeed do not have linux installed but linux-zen installed so I changed that to vmlinuz-linux-zen as well as adjustments for the initramfs. That didn't work. I rationalized that rEFInd for whatever reason wasn't picking up /dev/sdc2 partition after trying all sorts of alternative paths for the loader, initrd, etc. Finally, I just copied everything from /dev/sdc2 onto the ESP, deleted /dev/sdc2, changed the mountpoint of /dev/sdc1 (the ESP) to /boot and voila, everything works! Maybe it's possible to have an option to specify the boot partition, but I suspect I would've needed to change the volume parameter in the manual stanza to explictly point to /dev/sdc2, but it seems that refind-btrfs is quite displeased if I do that. So all in all, I now have an oversized ESP, a lost 1mb of impossible to allocate space, but a working refind btrfs with bootable snapshots. A net positive I'd say :)

Thanks for all of your help!

Venom1991 commented 3 years ago

Yeah, this kind of software is pretty hard to design and develop due to the sheer number of different setups that it is supposed to function correctly on.
Right from the start I wanted it to do as much as possible on its own, without the need for complex configuration but you're right regarding corner cases such as yours - it would be nice if the end user could somehow "guide" the tool in the right direction.

I'm glad that you finally managed to wrestle it into submission, albeit with certain tradeoffs.

Venom1991 commented 3 years ago

So your suggestion worked, but I ran into some problems. When trying to boot the manual stanza, I kept getting errors that the loader file vmlinuz-linux was invalid. At first, I thought it was because I indeed do not have linux installed but linux-zen installed so I changed that to vmlinuz-linux-zen as well as adjustments for the initramfs. That didn't work. I rationalized that rEFInd for whatever reason wasn't picking up /dev/sdc2 partition after trying all sorts of alternative paths for the loader, initrd, etc. Finally, I just copied everything from /dev/sdc2 onto the ESP, deleted /dev/sdc2, changed the mountpoint of /dev/sdc1 (the ESP) to /boot and voila, everything works! Maybe it's possible to have an option to specify the boot partition, but I suspect I would've needed to change the volume parameter in the manual stanza to explictly point to /dev/sdc2, but it seems that refind-btrfs is quite displeased if I do that. So all in all, I now have an oversized ESP, a lost 1mb of impossible to allocate space, but a working refind btrfs with bootable snapshots. A net positive I'd say :)

Thanks for all of your help!

Just to clarify (after reading your comment more thoroughly), you've changed the original boot stanza to the one I suggested? If that one didn't work properly on its own, as is, then of course the generated boot stanzas wouldn't work either.
You could have perhaps just let it be as it was because, like I said previously, only the "rootflags=subvol=@" part of the "options" field would have been changed in the generated stanzas (due to the existence of a separate boot partition). I was merely wondering how the boot stanza you've provided actually worked. It apparently wasn't causing problems for this tool.

But I guess it doesn't really matter anymore, I'm just thinking out loud here.

Barbaross93 commented 3 years ago

Woops, I think I was trying to say too much too quickly. What happened was, I started out with your suggestions for the boot stanza and that didn't work. I kept getting the invalid loader file error. After that, I knew it had to be a problem with how refind was getting access, so I tried altering the loader and initrd paths to various different paths without success. This is including what I had originally defined. At that point, I figured it must be because the boot partition /dev/sdc2 wasn't being noticed by refind for whatever reason. I guessed that it must be because the volume part of the stanza had to specify /dev/sdc2 in order for it to work, but refind-btrfs wants it to be the root volume. In my last post, your suggestion to simply make a new snapshot once the fstab file was fixed was finally what allowed sudo refind-btrfs to run without an error. That was when I started to boot from the manual stanza without success and thus the tinkering of loader and initrd paths