Mount dd Image As Disk – A Useful Little Hack

Yesterday I did a barely nothing start of an update on my Slackware image. Just downloaded the update listing prior to doing an actual update.

Being a Systems Admin sort, I figured that the “rational level of paranoia” meant I ought to do a backup prior to doing the actual update. It turns out my paranoia level was not quite high enough.

You see, I had only found a -current repository to point at (that’s the development branch) and on first check the package system informed me I was a slightly older version and was I SURE I wanted to use this repository? Well, as I had a choice of one, I agreed. I also figured that it was all of 2 days or so since I’d first installed this image so my fallback was one “useradd” run after a reinstall, and that being on -current might not be so bad. I was a tiny bit wrong.

“Something” unknown in just that “prepare to update” caused the system to then not boot after the backup. What? I don’t know what. I looked at /boot and the boot commands in it. Everything looks fine. It never puts anything on the screen nor does it get a dhcp address, so it is failing very early in the boot process.

I decided to just drop back to the raw install image, run useradd (adduser) and start over. That’s about 30 minutes elapsed (most of it waiting for dd to write the uSD image so can happen while making breakfast…) then a couple of minutes to make the user account again.

But that got me thinking I ought to check the uSD image for anything I might have downloaded or saved, or like the FireFox config files, might save me a few minutes once again telling FFox “No, I do NOT want you telling everyone in the world where I am, handing them my microphone, camera and speaker, letting them run videos at me, and making their trackers at home.” in preferences.

Which then had me thinking “Wait a mo… I have that in the backup image. Can’t I use it and proceed with flashing the uSD copy instead of mounting IT and sucking it off as a tarball or something readable?”

Which puts us at this posting.

Yes, you can.

It really isn’t all that hard. I realized I’d need to use the “loopback device” but also knew that with the disk header at the front, it would not be just a straight “mount -o loop” yada yada… A quick bit of web search showed several pages, so I took one at random off the top:

The key bit is the use of ‘fdisk’ to find out what to put in the mount command. In the mount command, you must give it the block size and how many blocks to skip to get to the actual file system to mount. ‘fdisk’ tells you that.

I did my usual and stuck this into trivial little script things. As this is a two step process, I made two of them. These are crudely done. IF I do this very much, then I’ll put in the time to make it one smooth script that doesn’t require you to manually choose things. As it is, you run the first one and then put the values into the second one. Clunky, but works. And 2 years from now when I need to do this again, self explanatory…

Here’s the first one:

root@odroidxu4:/SG2/ext/SysImages/Rock64/BUPS# bcat mntdd
fdisk -lu ${1-disk.img}
echo  Look at the "start" point.  Use that in a command to mount
echo  the disk partition such as:
echo  mount -o loop,offset=$((512*OFFSET_blocks)) dd_disk.img /mnt/dd_image
echo  Or do "mntdd2 BLOCKS OFFSET_Blocks DISK_IMG MNT_POINT"

I put the default of “disk.img” in there so that if you do not pass a parameter you don’t get the fdisk output of every single disk on your system…

So this will look at the dd disk image, and tell you the block size and offset:

root@odroidxu4:/Rock64/BUPS# mntdd SlackArm_Rock64_Conf_BBr_ems_21Oct2019 
Disk SlackArm_Rock64_Conf_BBr_ems_21Oct2019: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xaccdcd0a

Device                                   Boot Start      End  Sectors  Size Id Type
SlackArm_Rock64_Conf_BBr_ems_21Oct2019p1      32768 62333951 62301184 29.7G 83 Linux

Look at the start point. Use that in a command to mount
the disk partition such as:
mount -o loop,offset=0 dd_disk.img /mnt/dd_image

Here you can see it is 512 byte blocks and the start is at 32768. On to step 2.

root@odroidxu4:Rock64/BUPS# bcat mntdd2
echo first do a mntdd to get the block size and count, then 
echo call this command with them as \$1 and \$2
echo disk image is \$3 and mount point \$4
echo -n "Ready?: (Ctl-C to exit) "
read ANS
mount -o loop,offset=$(($1*$2)) ${3-disk.img} ${4-/mnt}

All the “magic sauce” is in the last line, and some directions to that 2 years from now “me” in the intro, with a chance to bail out if I didn’t do that yet. Yes, planning ahead ;-)

Again I’ve set some protective defaults. disk.img to prevent an attempt to mount nothing and /mnt as the default place for it to throw any malformed mounts (or just to save typing the 4th variable).

And yes, this really ought to be cleaned up into a one step script… but really? For a 2 minute use? Once every year or two? IFF I ever use it again a few time, then I sink time into polish for it…

root@odroidxu4:/Rock64/BUPS# mntdd2 512 32768 SlackArm_Rock64_Conf_BBr_ems_21Oct2019 /mnt

first do a mntdd to get the block size and count, then
call this command with them as $1 and $2
disk image is $3 and mount point $4

Ready?: (Ctl-C to exit) 

root@odroidxu4:/SG2/ext/SysImages/Rock64/BUPS# df
Filesystem      1K-blocks      Used  Available Use% Mounted on
udev               953008         0     953008   0% /dev
tmpfs              204484     11052     193432   6% /run
/dev/mmcblk1p1   29522764   2884708   26290524  10% /
tmpfs             1022408     94476     927932  10% /dev/shm
tmpfs                5120         4       5116   1% /run/lock
tmpfs             1022408         0    1022408   0% /sys/fs/cgroup
tmpfs             2097152     24508    2072644   2% /tmp
/dev/zram0          49584     48560          0 100% /var/log
tmpfs              204480         8     204472   1% /run/user/1616
/dev/sdb1        30672556   6264828   24391344  21% /SD/ext
/dev/loop0       30672556   6264828   24391344  21% /mnt
root@odroidxu4:/SG2/ext/SysImages/Rock64/BUPS# ls /mnt
SG5       bin   dev  home  lib64       media  opt   proc  run   srv   sys  usr
SWAPFILE  boot  etc  lib   lost+found  mnt    pkgs  root  sbin  swap  tmp  var

Now here you can see that the size is identical to the actual uSD card mounted at /SD/ext from /dev/sdb1 and an ls of the contents shows it really is there.

Now I can proceed to just flash the basic install image onto /dev/sdb and not worry about any need to pull particular files off of it (nor any need to spend 1/2 hour dumping that dd image BACK onto a uSD card to read it to retrieve some file…)

I’m “good to go” on the restore to a few days ago first fire Slackware image and “try again” on how to do that whole update / upgrade equivalent…

And… I have a new tool in my bag. Any and ALL of the various “dd” backup images I’ve made from all my various systems can now be mounted as a file system and read as desired. No need to put them back on some media first.

And… a few years from now when I’m thinking “I know I did that, how did that work again?” I have two script fragments with names that are easy to spot as relevant that can remind me how I did it ;-) for that “Oh Yeah” moment ;-)

Subscribe to feed


About E.M.Smith

A technical managerial sort interested in things from Stonehenge to computer science. My present "hot buttons' are the mythology of Climate Change and ancient metrology; but things change...
This entry was posted in Tech Bits and tagged , , , , , , , . Bookmark the permalink.