Antynea / grub-btrfs

Include btrfs snapshots at boot options. (Grub menu)
GNU General Public License v3.0
745 stars 77 forks source link

BUG: GRUB creates many duplicate comments in grub.cfg when running update-grub #278

Closed Zesko closed 1 year ago

Zesko commented 1 year ago

I notice there are a lot of duplicate comments in /boot/grub/grub.cfg : :point_down:

...
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### BEGIN /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
### END /etc/grub.d/41_snapshots-btrfs ###
...

More than 200 same comments in it.

That would cause GRUB processing to slow down.

How to reproduce the issue:

For grub 2.06.r499 and grub-btrfs 4.12 users.

  1. You have at least one btrfs root snapshot.
  2. You run with root privileges.
  3. Create grub.cfg backup

cp /boot/grub/grub.cfg /boot/grub/grub.cfg_backup

  1. Update grub config

grub-mkconfig -o /boot/grub/grub.cfg

  1. See diff between two files: grub.cfg vs. grub.cfg_backup

diff grub.cfg_backup grub.cfg

Difference output:

197a198,199
> ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
> ### END /etc/grub.d/41_snapshots-btrfs ###
  1. Update grub 5 times again: Difference output:
    
    197a198,209
    > ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
    > ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
    > ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
    > ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
    > ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
    > ### BEGIN /etc/grub.d/41_snapshots-btrfs ###
    > ### END /etc/grub.d/41_snapshots-btrfs ###
    > ### END /etc/grub.d/41_snapshots-btrfs ###
    > ### END /etc/grub.d/41_snapshots-btrfs ###
    > ### END /etc/grub.d/41_snapshots-btrfs ###
    > ### END /etc/grub.d/41_snapshots-btrfs ###
    > ### END /etc/grub.d/41_snapshots-btrfs ###
Zesko commented 1 year ago

The issue would be the GRUB header /etc/grub.d/00_header which would create the same comment with no snapshot-entry , but all snapshot-entries are outside of /boot/grub/grub.cfg, they are in /boot/grub/grub-btrfs.cfg

I did a trick to remove the old grub.cfg and create a new grub.cfg when update grub

I created a new executable GRUB script:

  1. $ sudo vim /etc/grub.d/00_clear_grub_cfg to add
    
    #!/bin/sh

if [ -f "/boot/grub/grub.cfg" ]; then rm /boot/grub/grub.cfg fi


The script name  "00_clear_grub_cfg" has the highest priority in GRUB order.

2. <kbd>$ sudo chmod +x /etc/grub.d/00_clear_grub_cfg</kbd>
3. <kbd>$ sudo grub-mkconfig -o /boot/grub/grub.cfg</kbd>

I think the trick is not recommended.

Maybe you have idea that duplicate comment should be cleaned away?
Zesko commented 1 year ago

This trick is unreliable. I get the warning when the grub.cfg was initially deleted.

grep: /boot/grub/grub.cfg: No such file or directory

WARNING: 'grub-mkconfig' needs to run at least once to generate the snapshots (sub)menu entry in grub the main menu. After that this script can run alone to generate the snapshot entries.

The reliable solution would be:

Create a new executable GRUB script:

  1. $ sudo vim /etc/grub.d/39_clear_grub_btrfs_comments to add
#!/bin/sh

file=/boot/grub/grub.cfg

# Find all duplicate lines and store in array
duplicates=$(grep -n "41_snapshots-btrfs ###" $file | cut -d: -f1)

count=0
i=0
# Loop through duplicates and remove all but the first two comments
for line_num in $duplicates; do
  if [ "$i" -gt 1 ]; then
    # Delete the line if it contains "41_snapshots-btrfs ###"
    line_num=$((line_num - count))
    sed -i "$line_num"d "$file"
    count=$((count + 1))
  fi
  i=$((i + 1))
done
  1. $ sudo chmod +x /etc/grub.d/39_clear_grub_btrfs_comments
  2. $ sudo update-grub

It removes all duplicates, leaving the first two comments.

Schievel1 commented 1 year ago

Thanks for your issue and also the provided solution. I am a bit hesitant to use it, though, because it is rather fighting the symptom down the line instead of going after the root cause.

Have you found out what is causing this?

bkmo commented 1 year ago

I too am seeing the same entries added at the end of grub.cfg after every run of grub-mkconfig on Arch Linux with latest grub and grub-btrfs from repos. grub 2.06.r499 and grub-btrfs 4.12 Edit: If I comment out the last 3 lines in 41_snapshots-btrfs (eliminating the warning check) then I do not get duplicate entries in grub.cfg

bkmo commented 1 year ago

The warning check comes after the 41_snapshots-btrfs script is closed with fi. This seems to cause grub-mkconfig to see it as a second script and add the begin and end comments. This seems to fix it for me:

if [ -e "$grub_btrfs_directory/grub-btrfs.cfg.bkp" ]; then
        mv -f "$grub_btrfs_directory/grub-btrfs.cfg.bkp" "$grub_btrfs_directory/grub-btrfs.cfg"
print_error "Syntax errors were detected in generated ${grub_btrfs_directory}/grub-btrfs.new file. The old grub-btrfs.cfg file (if present) have been restored."
fi

# warn when this script is run but there is no entry in grub.cfg
grep "snapshots-btrfs" "${grub_directory}/grub.cfg" || printf "\nWARNING: '%s' needs to run at least once to generate the snapshots (sub)menu entry in grub the main menu. \
After that this script can run alone to generate the snapshot entries.\n\n" "${GRUB_BTRFS_MKCONFIG:-grub-mkconfig}" >&2 ;
fi
Schievel1 commented 1 year ago

The warning check comes after the 41_snapshots-btrfs script is closed with fi. This seems to cause grub-mkconfig to see it as a second script and add the begin and end comments. This seems to fix it for me:

if [ -e "$grub_btrfs_directory/grub-btrfs.cfg.bkp" ]; then
        mv -f "$grub_btrfs_directory/grub-btrfs.cfg.bkp" "$grub_btrfs_directory/grub-btrfs.cfg"
print_error "Syntax errors were detected in generated ${grub_btrfs_directory}/grub-btrfs.new file. The old grub-btrfs.cfg file (if present) have been restored."
fi

# warn when this script is run but there is no entry in grub.cfg
grep "snapshots-btrfs" "${grub_directory}/grub.cfg" || printf "\nWARNING: '%s' needs to run at least once to generate the snapshots (sub)menu entry in grub the main menu. \
After that this script can run alone to generate the snapshot entries.\n\n" "${GRUB_BTRFS_MKCONFIG:-grub-mkconfig}" >&2 ;
fi

Oh yeah, thanks for figuring that out. I think I know whats going on.

I will release a quick fix.