Can't boot btrfs snapshot sent to then received from an external disk

Hello,

I have the following usecase: I’d like to be able to put my Btrfs snapshots taken with snapper on an external disk and then send them back when needed to do a snapper rollback.

I’ve no problem to send a Btrfs snapshot on an external disk then to send it back to the origin disk using btrfs send and btrfs receive commands.

The problem is I can’t boot a snapshot received from the external disk. I guess the problem comes from the subvolume UUIDs but I can’t be sure as I don’t know how grub handles Btrfs subvolumes exactly.

Here are the steps I’ve done:

  1. Install openSUSE Tumbleweed on a vm, default partitioning settings, except I didn’t create a separate XFS /home partition, it’s just another Btrfs subvolume:
# btrfs subvolume list -tuRq /
ID    gen    top level    parent_uuid    received_uuid    uuid    path    
--    ---    ---------    -----------    -------------    ----    ----    
257    184    5          -    -    c2c960f4-6f65-bf4c-8f0b-99eb73265b3b    @
258    262    257        -    -    2731a281-7a57-124c-a53a-a48c14e1f8fd    @/.snapshots
259    264    258        c2c960f4-6f65-bf4c-8f0b-99eb73265b3b    -    0a903510-4214-8540-b39f-7a3622ecb8a0    @/.snapshots/1/snapshot
260    184    257        -    -    ac4db657-8ef2-354d-9211-48d21f7a73da    @/boot/grub2/i386-pc
261    184    257        -    -    9b1425e5-2076-814f-acaa-0707725b47dd    @/boot/grub2/x86_64-efi
262    281    257        -    -    f033239a-55e6-3f4a-a1a4-e1e428bcdaad    @/home
263    184    257        -    -    43632d0d-84ba-0a47-bfbc-9cfe63417cdf    @/opt
264    184    257        -    -    ad53afd6-b8e8-8b45-9642-a6edfabb7717    @/srv
265    281    257        -    -    ef23a9c7-0880-f142-9dde-5d6494d85c4f    @/tmp
266    184    257        -    -    a7a1de99-4f13-e744-8a6c-849f25379b6a    @/usr/local
267    225    257        -    -    94d0b4f5-c43a-6b48-9f7c-c1d7d5d96a5c    @/var/cache
268    184    257        -    -    e526bc3f-081f-6349-a740-0f5ca5efdb00    @/var/crash
269    184    257        -    -    80a2ec11-d9ca-fc4e-8468-9524b90f8f84    @/var/lib/libvirt/images
270    184    257        -    -    c0ccb002-d881-f543-9a02-347c10ebeefb    @/var/lib/machines
271    184    257        -    -    28e3e58e-6a55-3a40-b11b-d6099dd852d2    @/var/lib/mailman
272    184    257        -    -    887aa3ce-aca0-b142-937c-06d2f2bf4d6b    @/var/lib/mariadb
273    184    257        -    -    e052e57e-4a0b-6445-b00c-cb69b0a15d2e    @/var/lib/mysql
274    184    257        -    -    17979ee9-09e0-8040-9314-50b2cdaac363    @/var/lib/named
275    184    257        -    -    3a633711-1ad5-164a-b7cc-fe8c5d41bc59    @/var/lib/pgsql
276    264    257        -    -    b73cacdf-88b9-4b4f-b666-f5f6251b4224    @/var/log
277    184    257        -    -    9c473a03-2cad-4241-9b8a-6f44de4727d6    @/var/opt
278    281    257        -    -    c6e11bcc-974c-ed40-8527-e140ee02036c    @/var/spool
279    230    257        -    -    057c9b12-92bc-dc49-9769-e815fe391e37    @/var/tmp
#

  1. Create a snapshot with snapper
# snapper ls
Type   | # | Pre # | Date                             | User        | Cleanup  | Description           | User data
-------+---+-------+----------------------------------+-------------+----------+-----------------------+---------------------
single | 0 |       |                                  | root        |          | current               |                     
single | 1 |       | dim. 09 juil. 2017 15:48:53 CEST | root        |          | first root filesystem |                     
single | 2 |       | dim. 09 juil. 2017 18:19:47 CEST | root        | number   |                       |                     
# btrfs subvolume list -tuRqs /
ID    gen    cgen    top level    otime    parent_uuid    received_uuid    uuid    path    
--    ---    ----    ---------    -----    -----------    -------------    ----    ----    
259    235    11    258        2017-07-09 15:48:53    c2c960f4-6f65-bf4c-8f0b-99eb73265b3b    -    0a903510-4214-8540-b39f-7a3622ecb8a0 @/.snapshots/1/snapshot
294    235    235    258        2017-07-09 18:19:47    0a903510-4214-8540-b39f-7a3622ecb8a0    -    28e73373-4043-e449-9c09-b08b53ee043f @/.snapshots/2/snapshot
#

  1. Send the snapshot to an external disk (not really an external disk, just another virtual disk I added to the vm and mounted at /mnt):

# mkdir -p /mnt/2
# cp /.snapshots/2/info.xml /mnt/2
# btrfs send /.snapshots/2/snapshot | btrfs receive /mnt/2
# btrfs subvolume list -tuRq /mnt
ID    gen    top level    parent_uuid    received_uuid    uuid    path    
--    ---    ---------    -----------    -------------    ----    ----    
257    324    5          -    -    9942db34-e2f7-1c41-a6d4-53962633c538    @
282    322    257        -    28e73373-4043-e449-9c09-b08b53ee043f    ac2a7ecd-e3c0-e242-b313-9f2690528fea    2/snapshot
#

  1. Delete the snapshot on the origin disk:
# snapper delete 2
#
  1. Send the snapshot from the external disk back to the origin:

# mkdir -p /.snapshots/2
# cp /mnt/2/info.xml /.snapshots/2
# btrfs send /mnt/2/snapshot | btrfs receive /.snapshots/2
# btrfs subvolume list -tuRq /
ID    gen    top level    parent_uuid    received_uuid    uuid    path    
--    ---    ---------    -----------    -------------    ----    ----    
257    184    5        -    -    c2c960f4-6f65-bf4c-8f0b-99eb73265b3b    @
258    262    257        -    -    2731a281-7a57-124c-a53a-a48c14e1f8fd    @/.snapshots
259    264    258        c2c960f4-6f65-bf4c-8f0b-99eb73265b3b    -    0a903510-4214-8540-b39f-7a3622ecb8a0    @/.snapshots/1/snapshot
260    184    257        -    -    ac4db657-8ef2-354d-9211-48d21f7a73da    @/boot/grub2/i386-pc
261    184    257        -    -    9b1425e5-2076-814f-acaa-0707725b47dd    @/boot/grub2/x86_64-efi
262    281    257        -    -    f033239a-55e6-3f4a-a1a4-e1e428bcdaad    @/home
263    184    257        -    -    43632d0d-84ba-0a47-bfbc-9cfe63417cdf    @/opt
264    184    257        -    -    ad53afd6-b8e8-8b45-9642-a6edfabb7717    @/srv
265    281    257        -    -    ef23a9c7-0880-f142-9dde-5d6494d85c4f    @/tmp
266    184    257        -    -    a7a1de99-4f13-e744-8a6c-849f25379b6a    @/usr/local
267    225    257        -    -    94d0b4f5-c43a-6b48-9f7c-c1d7d5d96a5c    @/var/cache
268    184    257        -    -    e526bc3f-081f-6349-a740-0f5ca5efdb00    @/var/crash
269    184    257        -    -    80a2ec11-d9ca-fc4e-8468-9524b90f8f84    @/var/lib/libvirt/images
270    184    257        -    -    c0ccb002-d881-f543-9a02-347c10ebeefb    @/var/lib/machines
271    184    257        -    -    28e3e58e-6a55-3a40-b11b-d6099dd852d2    @/var/lib/mailman
272    184    257        -    -    887aa3ce-aca0-b142-937c-06d2f2bf4d6b    @/var/lib/mariadb
273    184    257        -    -    e052e57e-4a0b-6445-b00c-cb69b0a15d2e    @/var/lib/mysql
274    184    257        -    -    17979ee9-09e0-8040-9314-50b2cdaac363    @/var/lib/named
275    184    257        -    -    3a633711-1ad5-164a-b7cc-fe8c5d41bc59    @/var/lib/pgsql
276    264    257        -    -    b73cacdf-88b9-4b4f-b666-f5f6251b4224    @/var/log
277    184    257        -    -    9c473a03-2cad-4241-9b8a-6f44de4727d6    @/var/opt
278    281    257        -    -    c6e11bcc-974c-ed40-8527-e140ee02036c    @/var/spool
279    230    257        -    -    057c9b12-92bc-dc49-9769-e815fe391e37    @/var/tmp
295    279    258        -    28e73373-4043-e449-9c09-b08b53ee043f    f1d2d421-e0d4-4242-830b-13491c5f863e    @/.snapshots/2/snapshot
  1. Regenerate grub-snapshot.cfg:
# /usr/lib/snapper/plugins/grub --refresh
# cat /.snapshots/2/grub-snapshot.cfg
  if  -f "/.snapshots/2/snapshot/boot/grub2/grub.cfg" ]; then
    snapshot_found=true
    saved_subvol=$btrfs_subvol
    menuentry  " openSUSE Tumbleweed  (4.11.8-1,2017-07-09T16:19)" "/.snapshots/2/snapshot" "/@/.snapshots/2/snapshot" {
        btrfs_subvol="$3"
        extra_cmdline="rootflags=subvol=$3"
        export extra_cmdline
        snapshot_num=2
        export snapshot_num
        configfile "$2/boot/grub2/grub.cfg"
        btrfs_subvol=$saved_subvol
      }
  fi
# cat /.snapshots/grub-snapshot.cfg
if  -z "$extra_cmdline" ]; then
  submenu  "Start bootloader from a read-only snapshot" {
    if  -f "/.snapshots/2/grub-snapshot.cfg" ]; then
      source "/.snapshots/2/grub-snapshot.cfg"
    fi
    if  x$snapshot_found != xtrue ]; then
      submenu "Not Found" { true; }
    fi
  }
fi
#
  1. Reboot
  2. On grub, select “boot from read-only snapshot” then select snapshot 2; Nothing happens.

If I create other snapshots they are bootable, but snapshot 2 isn’t. I mean I see the entry in grub but I can’t enter it, I just stay at the list of bootable snapshots.

As I said, I think the problem may come from the UUIDs. When I create more snapshots, I see they all have their parent UUID set to the UUID of /.snapshots/1/snapshot (first root filesystem snapper says).

But when the snapshot is sent with btrfs send, the received snapshot:

  • has no parent UUID; I guess it’s the reason why it’s not seen as a snapshot (not listed with option -s of btrfs subvolume list
    ). - gets a received UUID, which is the UUID (or the received UUID if any) of the sent snapshot
  • gets a new UUID

I know there is a -p option to btrfs send for incremental backup; But it doesn’t make sense to me to do a btrfs send -p /.snapshots/1/snapshot /.snapshots/2/snapshot | … as there is nothing on /mnt side. Anyway command is refused because /.snapshots/1/snapshot is not read-only.

Do you see the reason why I can’t enter the snapshot entry in grub? Do you think it’s related to UUIDs or it’s something different? Do you know how to realize my usecase?

Not even error message? Can you go to command line in grub and check whether /.snapshots/2/snapshot/boot/grub2/grub.cfg is visible? And what its content it (from within grub)?

Thanks for your answer arvidjaar.

No… I just see a blink of the screen but content doesn’t change: I’m still on the list of bootable snapshots or, if I pressed e to edit the entry, I’m still to the same page to edit the entry.

Yes it is visible when I do a cat /.snapshots/2/snapshot/boot/grub2 from grub command line.

When I read it from grub, I’m pretty sure it matches what I can read from the booted system. Not verified line by line though.

Its content is the same as root’s and other snapshots’ grub.cfgs.

#
# 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
  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}"
    save_env saved_entry
    if  "${env_block}" ] ; then
      save_env -f "${env_block}" 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_msdos
insmod btrfs
set root='hd0,msdos2'
if  x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint='hd0,msdos2'  926a75ec-a27c-488a-aa90-ce131f6cd378
else
  search --no-floppy --fs-uuid --set=root 926a75ec-a27c-488a-aa90-ce131f6cd378
fi
    font="/usr/share/grub2/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=fr_FR
  insmod gettext
fi
terminal_output gfxterm
insmod part_msdos
insmod btrfs
set root='hd0,msdos2'
if  x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint='hd0,msdos2'  926a75ec-a27c-488a-aa90-ce131f6cd378
else
  search --no-floppy --fs-uuid --set=root 926a75ec-a27c-488a-aa90-ce131f6cd378
fi
insmod gfxmenu
loadfont ($root)/boot/grub2/themes/openSUSE/ascii.pf2
loadfont ($root)/boot/grub2/themes/openSUSE/DejaVuSans10.pf2
loadfont ($root)/boot/grub2/themes/openSUSE/DejaVuSans12.pf2
loadfont ($root)/boot/grub2/themes/openSUSE/DejaVuSans-Bold14.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
  submenu "Bootable snapshot #$snapshot_num" {
    menuentry "If OK, run 'snapper rollback' and reboot." { true; }
  }
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/00_tuned ###
set tuned_params=""
### END /etc/grub.d/00_tuned ###

### BEGIN /etc/grub.d/10_linux ###
menuentry 'openSUSE Tumbleweed'  --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-926a75ec-a27c-488a-aa90-ce131f6cd378' {
    load_video
    set gfxpayload=keep
    insmod gzio
    insmod part_msdos
    insmod btrfs
    set root='hd0,msdos2'
    if  x$feature_platform_search_hint = xy ]; then
      search --no-floppy --fs-uuid --set=root --hint='hd0,msdos2'  926a75ec-a27c-488a-aa90-ce131f6cd378
    else
      search --no-floppy --fs-uuid --set=root 926a75ec-a27c-488a-aa90-ce131f6cd378
    fi
    echo    'Chargement de Linux 4.11.8-1-default…'
    linux    /boot/vmlinuz-4.11.8-1-default root=UUID=926a75ec-a27c-488a-aa90-ce131f6cd378  ${extra_cmdline} resume=/dev/disk/by-uuid/a2ec9936-18fe-4910-a50b-c120726264f8 splash=silent quiet showopts
    echo    'Chargement du disque mémoire initial…'
    initrd    /boot/initrd-4.11.8-1-default
}
submenu 'Options avancées pour openSUSE Tumbleweed' --hotkey=1 $menuentry_id_option 'gnulinux-advanced-926a75ec-a27c-488a-aa90-ce131f6cd378' {
    menuentry 'openSUSE Tumbleweed, avec Linux 4.11.8-1-default' --hotkey=2 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.11.8-1-default-advanced-926a75ec-a27c-488a-aa90-ce131f6cd378' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_msdos
        insmod btrfs
        set root='hd0,msdos2'
        if  x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint='hd0,msdos2'  926a75ec-a27c-488a-aa90-ce131f6cd378
        else
          search --no-floppy --fs-uuid --set=root 926a75ec-a27c-488a-aa90-ce131f6cd378
        fi
        echo    'Chargement de Linux 4.11.8-1-default…'
        linux    /boot/vmlinuz-4.11.8-1-default root=UUID=926a75ec-a27c-488a-aa90-ce131f6cd378  ${extra_cmdline} resume=/dev/disk/by-uuid/a2ec9936-18fe-4910-a50b-c120726264f8 splash=silent quiet showopts
        echo    'Chargement du disque mémoire initial…'
        initrd    /boot/initrd-4.11.8-1-default
    }
    menuentry 'openSUSE Tumbleweed, avec Linux 4.11.8-1-default (mode de dépannage)' --hotkey=3 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.11.8-1-default-recovery-926a75ec-a27c-488a-aa90-ce131f6cd378' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_msdos
        insmod btrfs
        set root='hd0,msdos2'
        if  x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint='hd0,msdos2'  926a75ec-a27c-488a-aa90-ce131f6cd378
        else
          search --no-floppy --fs-uuid --set=root 926a75ec-a27c-488a-aa90-ce131f6cd378
        fi
        echo    'Chargement de Linux 4.11.8-1-default…'
        linux    /boot/vmlinuz-4.11.8-1-default root=UUID=926a75ec-a27c-488a-aa90-ce131f6cd378  ${extra_cmdline} 
        echo    'Chargement du disque mémoire initial…'
        initrd    /boot/initrd-4.11.8-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/20_memtest86+ ###
### END /etc/grub.d/20_memtest86+ ###

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

### 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 ###
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/90_persistent ###
### END /etc/grub.d/90_persistent ###

### BEGIN /etc/grub.d/95_textmode ###
### END /etc/grub.d/95_textmode ###

Sorry for delay, but I needed time to dig in. Could you please do the following:

  1. Download https://github.com/knorrie/python-btrfs
  2. Provide output of “show_directory_contents.pl” example script for both top-level subvolume, one of “regular” snapshots and your received snapshot. Below is example of what I would like to see
linux-gtrk:/host/home/src/python-btrfs/examples # sudo mount -o ro,subvol=/ /dev/sda3 /mnt
linux-gtrk:/host/home/src/python-btrfs/examples # ./show_directory_contents.py /mnt/
directory /mnt/@ tree 257 inum 256
inode generation 6 transid 315 size 72 nbytes 0 block_group 0 mode 40755 nlink 1 uid 0 gid 0 rdev 0 flags 0x0(none)
inode ref index 0 name utf-8 ..
...
dir item list hash 1921786525 size 1
    dir item location (258 ROOT_ITEM -1) type DIR name utf-8 .snapshots
...
linux-gtrk:/host/home/src/python-btrfs/examples # ./show_directory_contents.py /mnt/@/.snapshots/251/snapshot/
directory /mnt/@/.snapshots/251/snapshot/ tree 774 inum 256
inode generation 6 transid 15867 size 164 nbytes 0 block_group 0 mode 40755 nlink 1 uid 0 gid 0 rdev 0 flags 0x0(none)
inode ref index 0 name utf-8 ..
...
dir item list hash 1921786525 size 1
    dir item location (258 ROOT_ITEM -1) type DIR name utf-8 .snapshots
...
linux-gtrk:/host/home/src/python-btrfs/examples # 

You can provide full output, but I actually am only interested in objectids for .snapshots sub-(volume|directory), My theory is that received snapshot has different tree ID which breaks expectations of snapshot handling code.

Hello,

Thanks for digging in :wink:

A regular snapshot:


~# ./show_directory_contents.py /.snapshots/3/snapshot
directory /.snapshots/3/snapshot/ tree 297 inum 256
inode generation 7 transid 68 size 156 nbytes 0 block_group 0 mode 40755 nlink 1 uid 0 gid 0 rdev 0 flags 0x0(none)
inode ref index 0 name utf-8 ..
dir item list hash 145260132 size 1
    dir item location (289 INODE_ITEM 0) type DIR name utf-8 dev
dir item list hash 217684952 size 1
    dir item location (292 INODE_ITEM 0) type DIR name utf-8 run
dir item list hash 300800368 size 1
    dir item location (13769 INODE_ITEM 0) type DIR name utf-8 selinux
dir item list hash 308198373 size 1
    dir item location (261 INODE_ITEM 0) type DIR name utf-8 boot
dir item list hash 883143349 size 1
    dir item location (13758 INODE_ITEM 0) type DIR name utf-8 lib
dir item list hash 935466660 size 1
    dir item location (13768 INODE_ITEM 0) type DIR name utf-8 sbin
dir item list hash 1230135107 size 1
    dir item location (267 INODE_ITEM 0) type DIR name utf-8 srv
dir item list hash 1289463356 size 1
    dir item location (269 INODE_ITEM 0) type DIR name utf-8 usr
dir item list hash 1493301263 size 1
    dir item location (266 INODE_ITEM 0) type DIR name utf-8 opt
dir item list hash 1802746451 size 1
    dir item location (13763 INODE_ITEM 0) type DIR name utf-8 lib64
dir item list hash 1921786525 size 1
    dir item location (258 ROOT_ITEM -1) type DIR name utf-8 .snapshots
dir item list hash 2415965623 size 1
    dir item location (13724 INODE_ITEM 0) type DIR name utf-8 bin
dir item list hash 2651688704 size 1
    dir item location (265 INODE_ITEM 0) type DIR name utf-8 home
dir item list hash 2753648287 size 1
    dir item location (257 INODE_ITEM 0) type DIR name utf-8 etc
dir item list hash 3195381536 size 1
    dir item location (271 INODE_ITEM 0) type DIR name utf-8 var
dir item list hash 3284084670 size 1
    dir item location (268 INODE_ITEM 0) type DIR name utf-8 tmp
dir item list hash 3578798206 size 1
    dir item location (291 INODE_ITEM 0) type DIR name utf-8 sys
dir item list hash 3715156233 size 1
    dir item location (13764 INODE_ITEM 0) type DIR name utf-8 mnt
dir item list hash 4087742454 size 1
    dir item location (290 INODE_ITEM 0) type DIR name utf-8 proc
dir item list hash 4214885080 size 1
    dir item location (13765 INODE_ITEM 0) type DIR name utf-8 root
dir index 2 location (257 INODE_ITEM 0) type DIR name utf-8 etc
dir index 3 location (258 ROOT_ITEM -1) type DIR name utf-8 .snapshots
dir index 4 location (261 INODE_ITEM 0) type DIR name utf-8 boot
dir index 5 location (265 INODE_ITEM 0) type DIR name utf-8 home
dir index 6 location (266 INODE_ITEM 0) type DIR name utf-8 opt
dir index 7 location (267 INODE_ITEM 0) type DIR name utf-8 srv
dir index 8 location (268 INODE_ITEM 0) type DIR name utf-8 tmp
dir index 9 location (269 INODE_ITEM 0) type DIR name utf-8 usr
dir index 10 location (271 INODE_ITEM 0) type DIR name utf-8 var
dir index 11 location (289 INODE_ITEM 0) type DIR name utf-8 dev
dir index 12 location (290 INODE_ITEM 0) type DIR name utf-8 proc
dir index 13 location (291 INODE_ITEM 0) type DIR name utf-8 sys
dir index 14 location (292 INODE_ITEM 0) type DIR name utf-8 run
dir index 15 location (13724 INODE_ITEM 0) type DIR name utf-8 bin
dir index 16 location (13758 INODE_ITEM 0) type DIR name utf-8 lib
dir index 17 location (13763 INODE_ITEM 0) type DIR name utf-8 lib64
dir index 18 location (13764 INODE_ITEM 0) type DIR name utf-8 mnt
dir index 19 location (13765 INODE_ITEM 0) type DIR name utf-8 root
dir index 20 location (13768 INODE_ITEM 0) type DIR name utf-8 sbin
dir index 21 location (13769 INODE_ITEM 0) type DIR name utf-8 selinux
~#

My received snasphot:


~# ./show_directory_contents.py /.snapshots/2/snapshot
directory /.snapshots/2/snapshot/ tree 304 inum 256
inode generation 754 transid 899 size 156 nbytes 0 block_group 0 mode 40755 nlink 1 uid 0 gid 0 rdev 0 flags 0x0(none)
inode ref index 0 name utf-8 ..
dir item list hash 145260132 size 1
    dir item location (287 INODE_ITEM 0) type DIR name utf-8 dev
dir item list hash 217684952 size 1
    dir item location (290 INODE_ITEM 0) type DIR name utf-8 run
dir item list hash 300800368 size 1
    dir item location (13763 INODE_ITEM 0) type DIR name utf-8 selinux
dir item list hash 308198373 size 1
    dir item location (261 INODE_ITEM 0) type DIR name utf-8 boot
dir item list hash 883143349 size 1
    dir item location (13752 INODE_ITEM 0) type DIR name utf-8 lib
dir item list hash 935466660 size 1
    dir item location (13762 INODE_ITEM 0) type DIR name utf-8 sbin
dir item list hash 1230135107 size 1
    dir item location (267 INODE_ITEM 0) type DIR name utf-8 srv
dir item list hash 1289463356 size 1
    dir item location (269 INODE_ITEM 0) type DIR name utf-8 usr
dir item list hash 1493301263 size 1
    dir item location (266 INODE_ITEM 0) type DIR name utf-8 opt
dir item list hash 1802746451 size 1
    dir item location (13757 INODE_ITEM 0) type DIR name utf-8 lib64
dir item list hash 1921786525 size 1
*   # See my note above about this .snapshots folder*
    dir item location (86645 INODE_ITEM 0) type DIR name utf-8 .snapshots
dir item list hash 2415965623 size 1
    dir item location (13718 INODE_ITEM 0) type DIR name utf-8 bin
dir item list hash 2651688704 size 1
    dir item location (265 INODE_ITEM 0) type DIR name utf-8 home
dir item list hash 2753648287 size 1
    dir item location (257 INODE_ITEM 0) type DIR name utf-8 etc
dir item list hash 3195381536 size 1
    dir item location (271 INODE_ITEM 0) type DIR name utf-8 var
dir item list hash 3284084670 size 1
    dir item location (268 INODE_ITEM 0) type DIR name utf-8 tmp
dir item list hash 3578798206 size 1
    dir item location (289 INODE_ITEM 0) type DIR name utf-8 sys
dir item list hash 3715156233 size 1
    dir item location (13758 INODE_ITEM 0) type DIR name utf-8 mnt
dir item list hash 4087742454 size 1
    dir item location (288 INODE_ITEM 0) type DIR name utf-8 proc
dir item list hash 4214885080 size 1
    dir item location (13759 INODE_ITEM 0) type DIR name utf-8 root
dir index 3 location (257 INODE_ITEM 0) type DIR name utf-8 etc
dir index 8 location (261 INODE_ITEM 0) type DIR name utf-8 boot
dir index 13 location (265 INODE_ITEM 0) type DIR name utf-8 home
dir index 15 location (266 INODE_ITEM 0) type DIR name utf-8 opt
dir index 17 location (267 INODE_ITEM 0) type DIR name utf-8 srv
dir index 19 location (268 INODE_ITEM 0) type DIR name utf-8 tmp
dir index 21 location (269 INODE_ITEM 0) type DIR name utf-8 usr
dir index 24 location (271 INODE_ITEM 0) type DIR name utf-8 var
dir index 41 location (287 INODE_ITEM 0) type DIR name utf-8 dev
dir index 43 location (288 INODE_ITEM 0) type DIR name utf-8 proc
dir index 45 location (289 INODE_ITEM 0) type DIR name utf-8 sys
dir index 47 location (290 INODE_ITEM 0) type DIR name utf-8 run
dir index 13476 location (13718 INODE_ITEM 0) type DIR name utf-8 bin
dir index 13511 location (13752 INODE_ITEM 0) type DIR name utf-8 lib
dir index 13517 location (13757 INODE_ITEM 0) type DIR name utf-8 lib64
dir index 13519 location (13758 INODE_ITEM 0) type DIR name utf-8 mnt
dir index 13521 location (13759 INODE_ITEM 0) type DIR name utf-8 root
dir index 13525 location (13762 INODE_ITEM 0) type DIR name utf-8 sbin
dir index 13527 location (13763 INODE_ITEM 0) type DIR name utf-8 selinux
* # See my note above about this .snapshots folder*
dir index 13528 location (86645 INODE_ITEM 0) type DIR name utf-8 .snapshots
~#

IDs are completely different.

Here’s another regular snapshot, which is very similar to the other regular snapshot:


~# ./show_directory_contents.py /.snapshots/9/snapshot
directory /.snapshots/9/snapshot/ tree 310 inum 256
inode generation 7 transid 741 size 156 nbytes 0 block_group 0 mode 40755 nlink 1 uid 0 gid 0 rdev 0 flags 0x0(none)
inode ref index 0 name utf-8 ..
dir item list hash 145260132 size 1
    dir item location (289 INODE_ITEM 0) type DIR name utf-8 dev
dir item list hash 217684952 size 1
    dir item location (292 INODE_ITEM 0) type DIR name utf-8 run
dir item list hash 300800368 size 1
    dir item location (13769 INODE_ITEM 0) type DIR name utf-8 selinux
dir item list hash 308198373 size 1
    dir item location (261 INODE_ITEM 0) type DIR name utf-8 boot
dir item list hash 883143349 size 1
    dir item location (13758 INODE_ITEM 0) type DIR name utf-8 lib
dir item list hash 935466660 size 1
    dir item location (13768 INODE_ITEM 0) type DIR name utf-8 sbin
dir item list hash 1230135107 size 1
    dir item location (267 INODE_ITEM 0) type DIR name utf-8 srv
dir item list hash 1289463356 size 1
    dir item location (269 INODE_ITEM 0) type DIR name utf-8 usr
dir item list hash 1493301263 size 1
    dir item location (266 INODE_ITEM 0) type DIR name utf-8 opt
dir item list hash 1802746451 size 1
    dir item location (13763 INODE_ITEM 0) type DIR name utf-8 lib64
dir item list hash 1921786525 size 1
    dir item location (258 ROOT_ITEM -1) type DIR name utf-8 .snapshots
dir item list hash 2415965623 size 1
    dir item location (13724 INODE_ITEM 0) type DIR name utf-8 bin
dir item list hash 2651688704 size 1
    dir item location (265 INODE_ITEM 0) type DIR name utf-8 home
dir item list hash 2753648287 size 1
    dir item location (257 INODE_ITEM 0) type DIR name utf-8 etc
dir item list hash 3195381536 size 1
    dir item location (271 INODE_ITEM 0) type DIR name utf-8 var
dir item list hash 3284084670 size 1
    dir item location (268 INODE_ITEM 0) type DIR name utf-8 tmp
dir item list hash 3578798206 size 1
    dir item location (291 INODE_ITEM 0) type DIR name utf-8 sys
dir item list hash 3715156233 size 1
    dir item location (13764 INODE_ITEM 0) type DIR name utf-8 mnt
dir item list hash 4087742454 size 1
    dir item location (290 INODE_ITEM 0) type DIR name utf-8 proc
dir item list hash 4214885080 size 1
    dir item location (13765 INODE_ITEM 0) type DIR name utf-8 root
dir index 2 location (257 INODE_ITEM 0) type DIR name utf-8 etc
dir index 3 location (258 ROOT_ITEM -1) type DIR name utf-8 .snapshots
dir index 4 location (261 INODE_ITEM 0) type DIR name utf-8 boot
dir index 5 location (265 INODE_ITEM 0) type DIR name utf-8 home
dir index 6 location (266 INODE_ITEM 0) type DIR name utf-8 opt
dir index 7 location (267 INODE_ITEM 0) type DIR name utf-8 srv
dir index 8 location (268 INODE_ITEM 0) type DIR name utf-8 tmp
dir index 9 location (269 INODE_ITEM 0) type DIR name utf-8 usr
dir index 10 location (271 INODE_ITEM 0) type DIR name utf-8 var
dir index 11 location (289 INODE_ITEM 0) type DIR name utf-8 dev
dir index 12 location (290 INODE_ITEM 0) type DIR name utf-8 proc
dir index 13 location (291 INODE_ITEM 0) type DIR name utf-8 sys
dir index 14 location (292 INODE_ITEM 0) type DIR name utf-8 run
dir index 15 location (13724 INODE_ITEM 0) type DIR name utf-8 bin
dir index 16 location (13758 INODE_ITEM 0) type DIR name utf-8 lib
dir index 17 location (13763 INODE_ITEM 0) type DIR name utf-8 lib64
dir index 18 location (13764 INODE_ITEM 0) type DIR name utf-8 mnt
dir index 19 location (13765 INODE_ITEM 0) type DIR name utf-8 root
dir index 20 location (13768 INODE_ITEM 0) type DIR name utf-8 sbin
dir index 21 location (13769 INODE_ITEM 0) type DIR name utf-8 selinux
~#

Note: This very morning, it seems I’ve found a workaround:

  • Try to enter the received snapshot in the list of bootable snapshots in grub; Nothing happens visually
  • Press e to edit the entry then ctrl+c to get command line; I get command line
  • Enter:
configfile /.snapshots/2/snapshot/boot/grub.cfg

; I can see the bootable snapshot and boot it.

But when I boot it, I get an emergency shell. The log says system fails to mount /.snapshots/; indeed, the folder does not exist in the received snapshot – whereas it exists for regular snapshots.

So back to the default subvolume:


btrfs property set -t s /.snapshots/2/snapshot ro false
mkdir -p /.snapshots/2/snapshot/.snapshots
btrfs property set -t s /.snapshots/2/snapshot ro true

I still have to do the workaround but I can properly boot the snapshot now. I haven’t tried to rollback yet.

Thanks, that confirms it.

Enter:

configfile /.snapshots/2/snapshot/boot/grub.cfg

; I can see the bootable snapshot and boot it.

That I do not understand. There should be no /boot/grub.cfg; are you sure you type in path correctly?

But when I boot it, I get an emergency shell. The log says system fails to mount /.snapshots/; indeed, the folder does not exist in the received snapshot

Again - it obvously exists in ouptut you provided.

btrfs property set -t s /.snapshots/2/snapshot ro false
mkdir -p /.snapshots/2/snapshot/.snapshots
btrfs property set -t s /.snapshots/2/snapshot ro true

So you collected output that I requested after you manually created .snapshots directory? Is it correct? In this case is .snapshots directory present in backed up snapshot (i.e. in your original example - /mnt/2/snapshot)?

Anyway, could you please try the following - in grub go to CLI and do

btrfs-mount-subvol ($root) /.snapshots @/.snapshots

then go back to menu with ESC and try booting snapshot again.

Thanks for pointing this out. Of course path is /boot/grub2/grub.cfg, I just mistyped it here :wink:

Yeah, that’s right, that’s why I added a not-very-clear-I-admit comment in the output (also s/above/below/g)…

dir item list hash 1921786525 size 1 *   # See my note above about this .snapshots folder*
    dir item location (86645 INODE_ITEM 0) type DIR name utf-8 .snapshots

An no, I didn’t create the folder in /mnt/2/snapshot then received the snapshot, I directly modified the snapshot already received.

Yes, that works!

So how manually mounting /.snapshots to @/.snapshots makes it work?

That’s clear and not what I asked. I asked whether this directory was already missing in /mnt/2/snapshot.

Yes, that works!

OK, could you open bug report on bugzilla.opensuse.org and tell number.

So how manually mounting /.snapshots to @/.snapshots makes it work?

That’s a bit complicated. (open)SUSE snapshot handling relies on the content of /.snapshots being always available. When Linux is booted this is ensured by simply mounting actual subvolume. In grub this worked due to bug in grub btrfs driver which (incorrectly) linked .snapshots directory to actual subvolume; but received subvolume lacks properties that trigger this bug. “Mounting” it in grub (this is SUSE specific BTW) simply does the same as in Linux ensuring the content can be accessed.

It was.

boo#1049994.

OK, thanks for the explanation.