GNU/Linux – Overlay Block Device and Stackable Block Device

block-deviceloop-devicesnapshot

GNU/Linux has union mount that overlays dirs. So you can mount a writeable dir on top of a read-only dir. When the writeable dir is unmounted the read-only dir is untouched.

I am looking for the same functionality for block devices – preferably with the writeable part stored in a file. So I would like to run something like:

device-setup /dev/newdevice /dev/read-only-device overlayfile

If I write to /dev/newdevice the changes should be stored in overlayfile. If I read the sectors written to, I should get the data from overlayfile. If I read sectors not written to, I should get the data from /dev/read-only-device.

Does such a tool exist?

Best Answer

You can do that with the device mapper and its snapshot target.

Basically, you'd do the same as what LVM does when you create a writable snapshot.

dev=/dev/read-only-device
ovl=/path/to/overlay.file
newdevname=newdevice
size=$(blockdev --getsz "$dev")

loop=$(losetup -f --show -- "$ovl")
printf '%s\n' "0 $size snapshot $dev $loop P 8" |
  dmsetup create "$newdevname"

Then you can access the overlayed device as /dev/mapper/newdevice.

If you also need access to the original device at the same time, you can do:

printf '%s\n' "0 $size snapshot-origin $dev" |
  dmsetup create originaldevice

And access it over /dev/mapper/originaldevice.

You can write to that device, then in addition to the chunks written to the snapshot device, the overlay file will contain a copy of the chunks that have been overwritten when writing to the snapshot-origin.

The overlay file can be a sparse file. (for instance, create it as truncate -s10G the-file), and doesn't have to be as large as the original device. You can tell how full it is with dmsetup status "$newdevname".

Note: There are size and contents reqirements on a snapshot device.

Related Question