Bug#1061168: grub-common: update-grub2 breaks root= directive when / is a BTRFS raid1 on LVM with other LVs using raidintegrity

2024-01-19 Thread Patrick Plenefisch
I should also mention that the grub configuration isn't really the system I
tested this on, though it is mounted in /srv/chroot/mebsuta

That system is Debian 12


Bug#1061168: grub-common: update-grub2 breaks root= directive when / is a BTRFS raid1 on LVM with other LVs using raidintegrity

2024-01-19 Thread Patrick Plenefisch
Package: grub-common
Version: 2.06-3~deb11u6
Severity: important
Tags: upstream
X-Debbugs-Cc: simonp...@gmail.com


If you have an LVM setup with a VG that contains a raidintegrity=y volume, and
two other volumes that form a BTRFS raid1 filesystem, and the BTRFS filesystem
is the root filesystem, then update-grub2 will generate grub.cfg with:

linux [...] root=/dev/lvm/btrfs1
/dev/lvm/btrfs2 [..]

instead of:
linux [...] root=/dev/lvm/btrfs1 [..]

or
linux [...] root=UUID=[...] [..]

Note: that is a newline in the configuration file, so the config file is broken

When doing this, update-grub2 will spit out several errors about unknown nodes
(listing the raidintegrity volumes) and disks (the id's for the first LV in the
VG)

To create a LVM system that fails in this way, first assemble a VG called
myGrubBreakingVG with two PVs in it. Then run:
lvcreate -L 128MiB -n theRaidVol --mirrors 1 --type raid1 --raidintegrity y
myGrubBreakingVG
lvcreate -L 5GiB -n btrfsSideA myGrubBreakingVG
lvcreate -L 5GiB -n btrfsSideB myGrubBreakingVG
mkfs.btrfs -m raid1 -d raid1 /dev/myGrubBreakingVG/btrfsSideA
/dev/myGrubBreakingVG/btrfsSideB

Then you can mount the btrfs volumes, and debootstrap a system into it, chroot,
and inside that chroot update grub will fail as described


-- Package-specific info:

*** BEGIN /proc/mounts
/dev/sde1 / btrfs rw,noatime,ssd,space_cache,subvolid=461,subvol=/root-subvol 0 0
/dev/mapper/lvm-polluxHome /home btrfs 
rw,noatime,ssd,space_cache,subvolid=5,subvol=/ 0 0
/dev/mapper/lvm-codemop /home/patrick/code btrfs 
rw,noatime,ssd,space_cache,subvolid=257,subvol=/code 0 0
/dev/sdd1 /boot/efi vfat 
rw,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro
 0 0
/dev/sdc1 /boot/efi2 vfat 
rw,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro
 0 0
/dev/sdb1 /boot/efi3 vfat 
rw,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro
 0 0
/dev/mapper/lvm-coldSnow /home/patrick/bigfiles btrfs 
rw,noatime,space_cache,subvolid=839,subvol=/@bigfiles 0 0
/dev/sdh1 /media/patrick/Ventoy exfat 
rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,iocharset=utf8,errors=remount-ro
 0 0
/dev/sdg1 /media/patrick/FastNloose ext4 
rw,nosuid,nodev,relatime,errors=remount-ro 0 0
/dev/sdg3 /media/patrick/HeptMigf btrfs 
rw,nosuid,nodev,relatime,space_cache,subvolid=5,subvol=/ 0 0
/dev/mapper/molasses-stripeFast /media/patrick/StripedFast ext4 
rw,nosuid,nodev,relatime,errors=remount-ro,stripe=64 0 0
/dev/mapper/mebsuta-mebsutaRoot /srv/chroot/mebsuta btrfs 
rw,relatime,ssd,space_cache=v2,subvolid=256,subvol=/@rootfs 0 0
/dev/nvme1n1p3 /srv/chroot/mebsuta/boot ext4 rw,relatime 0 0
/dev/mapper/molasses-stripeFast /srv/chroot/mebsuta/mnt ext4 
rw,relatime,errors=remount-ro,stripe=64 0 0
/dev/mapper/lvm-coldSnow /media/patrick/ColdSnowStorage btrfs 
rw,relatime,space_cache,subvolid=5,subvol=/ 0 0
/dev/mapper/molasses-photos /media/patrick/Photos btrfs 
rw,nosuid,nodev,relatime,space_cache,subvolid=5,subvol=/ 0 0
*** END /proc/mounts

*** BEGIN /boot/grub/grub.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="0"
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
  fi
}
function load_video {
  if [ x$feature_all_video_module = xy ]; then
insmod all_video
  else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
  fi
}

if [ x$feature_default_font_path = xy ] ; then
   font=unicode
else
insmod part_gpt
insmod btrfs
set root='hd3,gpt1'
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint-bios=hd3,gpt1 
--hint-efi=hd3,gpt1 --hint-baremetal=ahci3,gpt1  
2331b700-3f81-4711-b5d2-19b22456cd0d
else
  search --no-floppy --fs-uuid --set=root 2331b700-3f81-4711-b5d2-19b22456cd0d
fi
font="/root-subvol/usr/share/grub/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=en_US
  insmod gettext
fi
terminal_output gfxterm
if [ "${recordfail}" = 1 ] ; then
  set timeout=30
else
  if [