-
-
Save coderjo/c8de3ecc31f1d6450254b5e97ea2c595 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# usage: attach_cow_image.sh [imagefile] [cowfile] [devname] | |
# imagefile: path to the image file you want to load | |
# cowfile: path to the file to store writes into. If it doesn't exist, a sparse 1GB file will be created. | |
# devname: the name you want the drive to show up as in /dev/mapper | |
imgfile="$1" | |
cowfile="$2" | |
dmname="$3" | |
# create COW file if it doesn't exist (otherwise, assume we are using a file from a previous use) | |
# the if you don't think 1000MiB will be enough, you can create a larger one. | |
[ -f "$cowfile" ] || dd if=/dev/zero of="$cowfile" bs=1 count=1 seek=1048576000 | |
# attach the files to loop devices (with the image file read-only) | |
imgdev=`losetup -f -r --show "$imgfile"` | |
cowdev=`losetup -f --show "$cowfile"` | |
# get the size of the image device | |
imgsz=`blockdev --getsz $imgdev` | |
# create the devmapper table for a copy-on-write device using the two loop devices | |
# p means persist the snapshot data | |
# The 4 is the number of sectors to use per COW image chunk | |
echo 0 $imgsz snapshot $imgdev $cowdev p 4| dmsetup create $dmname | |
# and now probe the partition table of the new device | |
partprobe -s /dev/mapper/$dmname | |
# to detatch everything: | |
# dmsetup remove $dmname | |
# losetup -d $cowdev | |
# losetup -d $imgdev |
Since you are recovering a drive, I have another script that can take the log file output by GNU's ddrescue and output a dm table which forces errors where the original drive had read errors, if you have need for that behavior.
If you're working on recovering a drive, you should probably also make the block device read only so you can't accidentally make changes with any tools.
For example:
# blockdev --setro /dev/sda
Wow, thanks!
Is there a way to resize new device to larger without changing backing RO one?
You could make a devmapper device with the linear target. You could probably actually append the linear target to this table after the snapshot target. Check out the manpage for dmsetup.
I did it like that:
# echo "0 $imgsz linear $imgdev 0"$'\n'"$imgsz 204800 zero" | dmsetup create big_xp
# echo "0 $((imgsz+204800)) snapshot /dev/mapper/big_xp $cowdev p 8" | dmsetup create big_xp_rw
man
didn't help even a bit, but this gentoo wiki was helpful as hell: https://wiki.gentoo.org/wiki/Device-mapper#Create
To make sure the loop device is RO can add although not necessary since dm should never write on the $imgdev when 'snapshot target:
blockdev --setro $imgdev
Oops. I don't know how I missed that. I might have been typing this up from memory and didn't actually run this version until later. I'm glad it was helpful.