Last active
October 29, 2024 19:15
-
-
Save coderjo/c8de3ecc31f1d6450254b5e97ea2c595 to your computer and use it in GitHub Desktop.
access a disk image read-only with a copy-on-write overlay to allow fsck or the like to write changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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