Missing snapshots from read-only snapshots

I have an issue where I don’t see all my snapshots when I go to the read-only snapshots in GRUB.

I’m on microos.

This is the output from running snapper ls;

 # | Type   | Præ # | Dato                          | Bruger | Brugt plads | Oprydning | Beskrivelse             | Brugerdata
-----+--------+-------+-------------------------------+--------+-------------+-----------+-------------------------+--------------
  0  | single |       |                               | root   |             |           | current                 |
 70  | single |       | tir 28 nov 2023 10:05:20 CET  | root   |  132,38 MiB | number    | Snapshot Update of #69  | important=yes
 71  | single |       | ons 29 nov 2023 11:17:08 CET  | root   |  115,97 MiB | number    | Snapshot Update of #70  | important=yes
 72  | single |       | fre 01 dec 2023 09:53:49 CET  | root   |  160,53 MiB | number    | Snapshot Update of #71  | important=yes
 73  | single |       | lør 02 dec 2023 23:30:05 CET  | root   |  134,33 MiB | number    | Snapshot Update of #72  | important=yes
 74  | single |       | søn 03 dec 2023 18:50:25 CET  | root   |  215,76 MiB | number    | Snapshot Update of #73  | important=yes
 78  | single |       | fre 08 dec 2023 11:18:33 CET  | root   |  864,74 MiB | number    | Snapshot Update of #72  | important=yes
 84  | single |       | fre 15 dec 2023 10:01:28 CET  | root   |  111,95 MiB | number    | Snapshot Update of #70  | important=yes
 85  | single |       | lør 16 dec 2023 22:16:39 CET  | root   |   29,77 MiB | number    | Snapshot Update of #84  | important=yes
149  | single |       | fre 29 mar 2024 22:25:09 CET  | root   |    2,91 GiB | number    | Snapshot Update of #148 | important=yes
194  | single |       | ons 12 jun 2024 09:56:06 CEST | root   |   39,32 MiB | number    | Snapshot Update of #193 |
195  | single |       | tor 13 jun 2024 10:56:50 CEST | root   |   25,96 MiB | number    | Snapshot Update of #194 |
196  | single |       | fre 14 jun 2024 10:01:19 CEST | root   |   27,41 MiB | number    | Snapshot Update of #195 |
197  | single |       | lør 15 jun 2024 13:01:40 CEST | root   |   38,36 MiB | number    | Snapshot Update of #196 |
198  | single |       | tir 18 jun 2024 11:38:38 CEST | root   |  130,94 MiB | number    | Snapshot Update of #197 |
199  | single |       | ons 19 jun 2024 10:13:19 CEST | root   |   48,00 KiB | number    | Snapshot Update of #198 |
200  | single |       | tor 20 jun 2024 09:51:59 CEST | root   |  934,87 MiB | number    | Snapshot Update of #199 |
201  | single |       | fre 21 jun 2024 10:48:01 CEST | root   |   16,00 KiB | number    | Snapshot Update of #85  |
202- | single |       | fre 21 jun 2024 11:07:27 CEST | root   |   16,00 KiB | number    | rollback backup of #201 | important=yes
203  | single |       | fre 21 jun 2024 11:07:27 CEST | root   |   48,00 KiB |           | writable copy of #199   |
204+ | single |       | fre 21 jun 2024 11:35:31 CEST | root   |  958,79 MiB | number    | Snapshot Update of #203 |

I’m only seeing snapshot #70-84 and #202 in the GRUB boot menu. All others are missing.

This is my /.snapshots/grub-snapshot.cfg;

if [ -z "$extra_cmdline" ]; then
  submenu  "Start bootloader from a read-only snapshot" {
    if [ -f "/.snapshots/202/grub-snapshot.cfg" ]; then
      source "/.snapshots/202/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/85/grub-snapshot.cfg" ]; then
      source "/.snapshots/85/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/84/grub-snapshot.cfg" ]; then
      source "/.snapshots/84/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/78/grub-snapshot.cfg" ]; then
      source "/.snapshots/78/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/74/grub-snapshot.cfg" ]; then
      source "/.snapshots/74/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/73/grub-snapshot.cfg" ]; then
      source "/.snapshots/73/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/72/grub-snapshot.cfg" ]; then
      source "/.snapshots/72/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/71/grub-snapshot.cfg" ]; then
      source "/.snapshots/71/grub-snapshot.cfg"
    fi
    if [ -f "/.snapshots/70/grub-snapshot.cfg" ]; then
      source "/.snapshots/70/grub-snapshot.cfg"
    fi
    if [ x$snapshot_found != xtrue ]; then
      submenu "Not Found" { true; }
    fi
  }
fi

How do I fix this? It seems whenever the transactional-update.timertriggers a new update only second-latest snapshots get added.

Show output of

LC_ALL=en_US.UTF-8 LANGUAGE=en ls -l /.snapshots/*/grub-snapshot.cfg
-rw-r-----. 1 root root 511 Jun 24 10:51 /.snapshots/202/grub-snapshot.cfg
-rw-r-----. 1 root root 511 Jun 24 10:51 /.snapshots/205/grub-snapshot.cfg
-rw-r-----. 1 root root 511 Jun 24 10:51 /.snapshots/208/grub-snapshot.cfg
-rw-r-----. 1 root root 506 Jun 24 10:51 /.snapshots/72/grub-snapshot.cfg
-rw-r-----. 1 root root 506 Jun 24 10:51 /.snapshots/73/grub-snapshot.cfg
-rw-r-----. 1 root root 506 Jun 24 10:51 /.snapshots/74/grub-snapshot.cfg
-rw-r-----. 1 root root 506 Jun 24 10:51 /.snapshots/78/grub-snapshot.cfg
-rw-r-----. 1 root root 506 Jun 24 10:51 /.snapshots/84/grub-snapshot.cfg
-rw-r-----. 1 root root 506 Jun 24 10:51 /.snapshots/85/grub-snapshot.cfg

You can see it has added new snapshots but the other snapshots are still missing.

You got it backwards. The other snapshots are missing in grub menu because grub-snapshot.cfg files are missing in these snapshots. As long as it works now I would just ignore it.

Yes - but no new snapshots are created in the GRUB read-only snapshots menu. This ONLY happens if I do a sudo transactional-update rollback. Sorry I did not mention that.

I really would like it to add new entries whenever a transactional-update is done. Just like it did originally when everything worked.

Start with showing (with English messages please)

zypper search -si snapper

Appreciate the help! Here you go;

Loading repository data...
Reading installed packages...

S  | Name                 | Type    | Version    | Arch   | Repository
---+----------------------+---------+------------+--------+------------------------
i  | grub2-snapper-plugin | package | 2.12-20.1  | noarch | openSUSE-Tumbleweed-Oss
i  | libsnapper7          | package | 0.11.0-1.1 | x86_64 | openSUSE-Tumbleweed-Oss
i+ | snapper              | package | 0.11.0-1.1 | x86_64 | openSUSE-Tumbleweed-Oss

That should be enough. AFAICT it creates grub-snapshot.cfg if

  • snapshot is read-only
  • the file /boot/grub2/grub.cfg inside this snapshot exists

Can you check it for the snapshots that are missing?

1 Like
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
set btrfs_relative_path="y"
export btrfs_relative_path
if [ -f ${config_directory}/grubenv ]; then
  load_env -f ${config_directory}/grubenv
elif [ -s $prefix/grubenv ]; then
  load_env
fi

if [ "${env_block}" ] ; then
  set env_block="(${root})${env_block}"
  export env_block
  load_env -f "${env_block}"
fi

if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   if [ "${env_block}" ] ; then
     save_env -f "${env_block}" next_entry
   fi
   set boot_once=true
else
   set default="${saved_entry}"
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}"
    if [ "${env_block}" ] ; then
      save_env -f "${env_block}" saved_entry
    else
      save_env saved_entry
    fi

  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
search --no-floppy --fs-uuid --set=root 4571a217-be71-46a9-a2a1-793b1c20ba18
    font="/usr/share/grub2/unicode.pf2"
fi

if loadfont $font ; then
  if [ "${grub_platform}" = "efi" ]; then
    echo "Please press 't' to show the boot menu on this console"
  fi

  set gfxmode=auto
  load_video
  insmod gfxterm
fi
terminal_input console

for i in gfxterm; do
  if [ x${use_append} = xtrue ]; then
     terminal_output --append $i
  elif terminal_output $i; then
     use_append=true;
  fi
done

insmod part_gpt
insmod btrfs
search --no-floppy --fs-uuid --set=root 4571a217-be71-46a9-a2a1-793b1c20ba18
insmod gfxmenu
loadfont ($root)/boot/grub2/themes/openSUSE/DejaVuSans-Bold14.pf2
loadfont ($root)/boot/grub2/themes/openSUSE/DejaVuSans10.pf2
loadfont ($root)/boot/grub2/themes/openSUSE/DejaVuSans12.pf2
loadfont ($root)/boot/grub2/themes/openSUSE/ascii.pf2
insmod png
set theme=($root)/boot/grub2/themes/openSUSE/theme.txt
export theme
if [ x${boot_once} = xtrue ]; then
  set timeout=0
elif [ x$feature_timeout_style = xy ] ; then
  set timeout_style=menu
  set timeout=8
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
  set timeout=8
fi
if [ -n "$extra_cmdline" ]; then
  menuentry "Help on bootable snapshot #$snapshot_num" {
    echo "Select the default entry of the snapshot boot menu."
    echo "Examine the snapshot, and if it's OK,"
    echo "   run 'snapper rollback' and reboot."
    echo "See 'System Rollback by Booting from Snapshots'"
    echo "   in the manual for more information."
    echo "  ** Hit Any Key to return to boot menu **  "
    read
  }
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/01_suse_ro_root ###
# On read-only root file systems /boot/writable provides a writeable
# subvolume, e.g. to store the GRUB environment block.
set boot_rw_subvol=/boot/writable
if [ "${root}" != "host" ]; then
  btrfs-mount-subvol "(${root})" "${boot_rw_subvol}" "/@/boot/writable"
fi

# Use above location to load GRUB environment variables
if [ -f ${boot_rw_subvol}/grubenv ]; then
  load_env -f ${boot_rw_subvol}/grubenv
fi
# btrfs header always beats config file
if [ "${env_block}" ] ; then
  load_env -f "${env_block}"
fi
### END /etc/grub.d/01_suse_ro_root ###

### BEGIN /etc/grub.d/05_crypttab ###
### END /etc/grub.d/05_crypttab ###

### BEGIN /etc/grub.d/05_health_check ###
# Only consider showing a fallback entry on the top level menu
if [ -z "${chosen}" -a -z "${boot_once}" ]; then
  # If flag is set on boot the last start seems to have failed - the flag
  # should have been cleared by userspace
  if [ "${health_checker_flag}" -ge 1 ]; then
    # Reset flag; it will be set again by a supported menu entry.
    # This prevents getting stuck in a loop when booting an entry that
    # doesn't support this flag yet.
    health_checker_flag=0
    if [ "${env_block}" ] ; then
      save_env -f "${env_block}" health_checker_flag
    fi
    # Try to mount /var/lib/misc from know subvolume locations
    btrfs-mount-subvol (${root}) /var /@/var
    btrfs-mount-subvol (${root}) /var/lib/misc /@/var/lib/misc

    if [ -e /var/lib/misc/health-checker.state ]; then
      source /var/lib/misc/health-checker.state
      if [ -n ${LAST_WORKING_SNAPSHOT} ]; then
        LAST_WORKING_SNAPSHOTS=${LAST_WORKING_SNAPSHOT}
      fi
    fi

    # Backwards compatibility (for state file created with old
    # health-checker versions):
    # Due to boo#1048088 btrfs-list-subvols currently doesn't give a list of
    # subvolumes, so it's not possible to map
    # /var/lib/misc/health-checker.state to a snapshot directory; use
    # transactional-update state file as a workaround.
    if [ -z ${LAST_WORKING_SNAPSHOTS} -a -e /var/lib/misc/transactional-update.state ]; then
      source /var/lib/misc/transactional-update.state
    fi

    if [ -n "${LAST_WORKING_SNAPSHOTS}" ]; then
      btrfs-mount-subvol ($root) /.snapshots @/.snapshots
      for snapshot in ${LAST_WORKING_SNAPSHOTS}; do
        if [ -e "/.snapshots/${snapshot}/grub-snapshot.cfg" ]; then
          menuentry "Previous boot failed; booting snapshot ${snapshot}" { true; }
          source /.snapshots/${snapshot}/grub-snapshot.cfg
          menuentry "________________" { true; }
          set default=1
          break
        fi;
      done
    fi
  fi
fi
### END /etc/grub.d/05_health_check ###

### BEGIN /etc/grub.d/10_linux ###
menuentry 'openSUSE MicroOS'  --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-4571a217-be71-46a9-a2a1-793b1c20ba18' {
	health_checker_flag=1
	if [ "${env_block}" ] ; then
		save_env -f "${env_block}" health_checker_flag
	fi
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_gpt
	insmod btrfs
	search --no-floppy --fs-uuid --set=root 4571a217-be71-46a9-a2a1-793b1c20ba18
	echo	'Loading Linux 6.9.4-1-default ...'
	linux	/boot/vmlinuz-6.9.4-1-default root=UUID=4571a217-be71-46a9-a2a1-793b1c20ba18  ${extra_cmdline} splash=silent swapaccount=1 mitigations=auto quiet security=selinux selinux=1 enforcing=0
	echo	'Loading initial ramdisk ...'
	initrd	/boot/initrd-6.9.4-1-default
}
submenu 'Advanced options for openSUSE MicroOS' --hotkey=1 $menuentry_id_option 'gnulinux-advanced-4571a217-be71-46a9-a2a1-793b1c20ba18' {
	menuentry 'openSUSE MicroOS, with Linux 6.9.4-1-default' --hotkey=2 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.9.4-1-default-advanced-4571a217-be71-46a9-a2a1-793b1c20ba18' {
		load_video
		set gfxpayload=keep
		insmod gzio
		insmod part_gpt
		insmod btrfs
		search --no-floppy --fs-uuid --set=root 4571a217-be71-46a9-a2a1-793b1c20ba18
		echo	'Loading Linux 6.9.4-1-default ...'
		linux	/boot/vmlinuz-6.9.4-1-default root=UUID=4571a217-be71-46a9-a2a1-793b1c20ba18  ${extra_cmdline} splash=silent swapaccount=1 mitigations=auto quiet security=selinux selinux=1 enforcing=0
		echo	'Loading initial ramdisk ...'
		initrd	/boot/initrd-6.9.4-1-default
	}
	menuentry 'openSUSE MicroOS, with Linux 6.9.4-1-default (recovery mode)' --hotkey=3 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.9.4-1-default-recovery-4571a217-be71-46a9-a2a1-793b1c20ba18' {
		load_video
		set gfxpayload=keep
		insmod gzio
		insmod part_gpt
		insmod btrfs
		search --no-floppy --fs-uuid --set=root 4571a217-be71-46a9-a2a1-793b1c20ba18
		echo	'Loading Linux 6.9.4-1-default ...'
		linux	/boot/vmlinuz-6.9.4-1-default root=UUID=4571a217-be71-46a9-a2a1-793b1c20ba18 single  ${extra_cmdline}
		echo	'Loading initial ramdisk ...'
		initrd	/boot/initrd-6.9.4-1-default
	}
}

### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/20_linux_xen ###

### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/25_bli ###
if [ "$grub_platform" = "efi" ]; then
  insmod bli
fi
### END /etc/grub.d/25_bli ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/30_uefi-firmware ###
if [ "$grub_platform" = "efi" ]; then
	menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
                fwsetup --is-supported
                if [ "$?" = 0 ]; then
                        fwsetup
                else
                        echo "Your firmware doesn't support setup menu entry from a boot loader"
                        echo "Press any key to return ..."
                        read
                fi
        }
fi
### END /etc/grub.d/30_uefi-firmware ###

### BEGIN /etc/grub.d/35_fwupd ###
### END /etc/grub.d/35_fwupd ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg
fi
### END /etc/grub.d/41_custom ###

### BEGIN /etc/grub.d/80_suse_btrfs_snapshot ###
btrfs-mount-subvol ($root) /.snapshots @/.snapshots
if [ -f "/.snapshots/grub-snapshot.cfg" ]; then
  source "/.snapshots/grub-snapshot.cfg"
fi
### END /etc/grub.d/80_suse_btrfs_snapshot ###

### BEGIN /etc/grub.d/83_health_check_marker ###
# Prevent infinite waiting for disk if drivers in initrd are broken
extra_cmdline="${extra_cmdline} rd.timeout=60 rd.retry=45"
### END /etc/grub.d/83_health_check_marker ###

### BEGIN /etc/grub.d/90_persistent ###
### END /etc/grub.d/90_persistent ###

### BEGIN /etc/grub.d/95_textmode ###
if [ "${grub_platform}" = "efi" ]; then
  # On EFI systems we can only have graphics *or* serial, so allow the user
  # to switch between the two
  hiddenentry 'Text mode' --hotkey 't' {
    set textmode=true
    terminal_output console
  }
fi
### END /etc/grub.d/95_textmode ###

It seem completely normal.

Now I’m actually in even more trouble - my latest snapshot fails when I boot with emergency mode activating. Almost every time. I can still boot older snapshots that I have thankfully.

Is is safe to use; btrfs check --repair /dev/nvme0n1p2 in emergency mode?
It fails to mount all of the below filesystems.

These are my mounted filesystems;

/dev/nvme0n1p2 on / type btrfs (ro,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=481,subvol=/@/.snapshots/214/snapshot)
/dev/nvme0n1p2 on /root type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=260,subvol=/@/root)
/dev/nvme0n1p2 on /var type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=257,subvol=/@/var)
/dev/nvme0n1p2 on /.snapshots type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=266,subvol=/@/.snapshots)
/dev/nvme0n1p2 on /boot/grub2/i386-pc type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=265,subvol=/@/boot/grub2/i386-pc)
/dev/nvme0n1p2 on /boot/grub2/x86_64-efi type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=264,subvol=/@/boot/grub2/x86_64-efi)
/dev/nvme0n1p2 on /boot/writable type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=263,subvol=/@/boot/writable)
/dev/nvme0n1p2 on /home type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=262,subvol=/@/home)
/dev/nvme0n1p2 on /opt type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=261,subvol=/@/opt)
/dev/nvme0n1p2 on /srv type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=259,subvol=/@/srv)
/dev/nvme0n1p2 on /usr/local type btrfs (rw,relatime,seclabel,ssd,discard=async,space_cache=v2,subvolid=258,subvol=/@/usr/local)
/dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)

After investigating this further it seems the issue is that relabel of filesystem fails.

I’m just writing to report that my issues have gone away.

The relabeling issue is gone; not completely sure why it happened but maybe the /etc/selinux/.autorelabel was created.

The issue with the missing snapshots is still a mystery but thankfully new snapshots now appear normally.

@arvidjaar thank you for trying to help! :wink:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.