Bug 89121 - BTRFS mixes up mounted devices with their snapshots
Summary: BTRFS mixes up mounted devices with their snapshots
Status: NEW
Alias: None
Product: File System
Classification: Unclassified
Component: btrfs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Josef Bacik
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-01 11:23 UTC by MegaBrutal
Modified: 2016-03-20 11:18 UTC (History)
2 users (show)

See Also:
Kernel Version: 3.18.0-rc7
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description MegaBrutal 2014-12-01 11:23:05 UTC
I found a bug which presents itself when the following conditions are met: you have your BTRFS root device over LVM, and you make a snapshot of it while it is being mounted. The kernel will erroneously report that the device being mounted at "/" is the snapshot you've just made.

The information reported in /proc/mounts is certainly bogus, since still the origin device is being written, the kernel does not actually mix up the devices for write operations, and such, the phenomenon does not cause data corruption. (I did an entire distro release upgrade while the conditions were present, and I centainly would have suffered severe data corruption otherwise. Fortunately, the origin device had the new distro, and the snapshot device had the old one, so besides the mixup in /proc/mounts, no actual damage happened.)

The following script reproduces the bug, when your VG is named "vg", and your root device is "rootlv" in "vg":

#!/bin/sh -v
lvs

grub-probe --target=device /

grep " / " /proc/mounts

lvcreate --snapshot --size=128M --name z vg/rootlv

lvs

ls -l /dev/vg/

grub-probe --target=device /

grep " / " /proc/mounts

lvremove --force vg/z

grub-probe --target=device /

grep " / " /proc/mounts


The output of this script when run on an affected system:

#!/bin/sh -v
lvs
  LV     VG   Attr      LSize   Pool Origin Data%  Move Log Copy%  Convert
  rootlv vg   -wi-ao---   1.00g                                           
  swap0  vg   -wi-ao--- 256.00m                                           

grub-probe --target=device /
/dev/mapper/vg-rootlv

grep " / " /proc/mounts
rootfs / rootfs rw 0 0
/dev/dm-1 / btrfs rw,relatime,space_cache 0 0

lvcreate --snapshot --size=128M --name z vg/rootlv
  Logical volume "z" created

lvs
  LV     VG   Attr      LSize   Pool Origin Data%  Move Log Copy%  Convert
  rootlv vg   owi-aos--   1.00g                                           
  swap0  vg   -wi-ao--- 256.00m                                           
  z      vg   swi-a-s-- 128.00m      rootlv   0.11                        

ls -l /dev/vg/
total 0
lrwxrwxrwx 1 root root 7 Nov 18 18:29 rootlv -> ../dm-1
lrwxrwxrwx 1 root root 7 Nov 18 12:19 swap0 -> ../dm-0
lrwxrwxrwx 1 root root 7 Nov 18 18:29 z -> ../dm-2

grub-probe --target=device /
/dev/mapper/vg-z

grep " / " /proc/mounts
rootfs / rootfs rw 0 0
/dev/dm-2 / btrfs rw,relatime,space_cache 0 0

lvremove --force vg/z
  Logical volume "z" successfully removed

grub-probe --target=device /
/dev/mapper/vg-rootlv

grep " / " /proc/mounts
rootfs / rootfs rw 0 0
/dev/dm-1 / btrfs rw,relatime,space_cache 0 0


Steps to build a Debian-based test system:
1. Create an LV, format it to btrfs.
2. Mount the LV, create subvolume '@' on the file system.
3. debootstrap a base system to the subvolume.
4. chroot to the subvolume, do whatever it takes to make it bootable (install kernel, lvm2, btrfs-tools).
5. Boot the new system.
6. Create an LVM-snapshot of the root LV.
7. 'grub-probe --target=device /' will tell you that your root device is the snapshot. You will find the same information in /proc/mounts.

A virtual machine image on which I reproduced the conditions can be downloaded here:
http://undead.megabrutal.com/kvm-reproduce-1391429.img.xz
(Download size: 113 MB; Unpacked image size: 2 GB.)

The problem also presents itself when the identical device is not actually an LVM snapshot, but a clone made with dd. The phenomenon is not reproducible with non-root file systems (in that case, no erroneous behaviour is detected).

There is an ongoing debate on the BTRFS mailing list about how the kernel should treat identical devices. While it is an interesting question, my point is, whatever is the case, such mixup should certainly not happen WHILE the file system is BEING mounted. How BTRFS should differentiate between identical devices BEFORE mounting them is a different issue.
http://www.spinics.net/lists/linux-btrfs/msg39168.html


Reported downstream at Ubuntu Launchpad as #1391429.
(https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1391429)

Note You need to log in before you can comment on or make changes to this bug.