17

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?

imz -- Ivan Zakharyaschev
  • 15,113
  • 15
  • 61
  • 123
Ole Tange
  • 33,591
  • 31
  • 102
  • 198

1 Answers1

27

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.

Tom Hale
  • 28,728
  • 32
  • 139
  • 229
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • 1
    A subsequent interesting question is whether the acc.umulated changes can later be merged into the original device – imz -- Ivan Zakharyaschev Aug 03 '14 at 15:54
  • 1
    The subsequent answer: yes. "Device-mapper allows you … *) To merge a snapshot of a block device back into the snapshot's origin device." https://www.kernel.org/doc/Documentation/device-mapper/snapshot.txt – imz -- Ivan Zakharyaschev Aug 03 '14 at 17:02
  • What does the chunksize parameter to the snapshot target (8 in your case) mean? How to choose it? – imz -- Ivan Zakharyaschev Aug 04 '14 at 04:21
  • Another important aspect: Will the devices setup by dmsetup (and losetup) survive a reboot (so that one could write an fstab entry for them), or one will have to run the script to set them up every time? – imz -- Ivan Zakharyaschev Aug 04 '14 at 10:04
  • @Ivan, all those questions are easily answered by the link you pointed to – Stéphane Chazelas Aug 04 '14 at 10:06
  • I get `device-mapper: reload ioctl on bk-ovl failed: Device or resource busy Command failed`. The journal has: `device-mapper: table: 254:4: snapshot: Cannot get origin device` and `device-mapper: ioctl: error adding target to table`. Any tips? – Tom Hale Jul 07 '17 at 15:11
  • Any reason to set the sector chunk size to 8 and not 1? – Tom Hale Sep 17 '17 at 04:52
  • @TomHale (`s/sector/chunk/`). The smaller it is, the more overhead (in terms of _work_). Most file systems have a block size of at least 4KiB, so a chunk size smaller than that would be counter-productive I would think. You'll notice that's what LVM uses by default (`--chunksize` option to for instance to change it) – Stéphane Chazelas Sep 17 '17 at 05:36
  • @StéphaneChazelas: `Changed chunks of sectors will be stored on the .` If the unit is sectors not bytes, and a sector is the smallest unit of "work" then how would increasing the chunksize reduce the workload? – Tom Hale Sep 17 '17 at 06:06
  • If has 512 byte blocks and has 4096 byte blocks, then 8 makes sense. But if both are 4096 byte blocks (`blockdev --getsz `), then how can using `1` for be a disadvantage? – Tom Hale Sep 17 '17 at 06:11
  • 1
    @Tom Those numbers in DM tables always refer to 512 byte units, not physical sector size of underlying block devices. So using something that is not a multiple of 8 a snapshot on top of a device with 4K sectors would be a bad idea. – Stéphane Chazelas Sep 17 '17 at 06:15
  • 1
    @Tom, the chunksize determines the granularity of the snapshoting. it's not about the blocksize of the FS for the overlay file, but the ganularity of I/O operations done on whatever is sitting on the block device. Hence the rollback. Thanks for the getsz vs getsize. – Stéphane Chazelas Sep 17 '17 at 13:13
  • @StéphaneChazelas So if the device is being used for a filesystem, then one would [find and use the FS block size](https://unix.stackexchange.com/a/392778/143394), yes? Thanks for your patience on this! – Tom Hale Sep 18 '17 at 05:39
  • Yes, though there are more things you may want into consideration (or not as 4KiB is a good default in many cases). Too small and that means more fragmentation bigger mapping tables (I don't know the exact structure of snapshots but I suppose there would be some), more work, and all that for nothing if the FS on top writes in bigger blocks. Two big and that could mean wasting disk space and I/O (when more copying is done than necessary) – Stéphane Chazelas Sep 18 '17 at 06:26