Using kpartx/losetup With Disk Image (.img) Files and Partitions
Amongst the different types of virtual disk images, we occasionally bump into the .img
type.
There are various methods that can be used when analyzing or working with these virtual disks, and/or their respective partitions.
This article describes some of these alternative options using a combination of mount, losetup, kpartx
and loop
devices.
Packages Required
Installing kpartx
for mapping partitions. Using apt
on Ubuntu, kpartx
can installed as follows:
sudo apt install kpartx
Virtual Disk Image Demo Details
For examples used throughout the article, we’ll be using the .img
file, as listed below, consisting of 2 partitions. Our primary focus will be on manipulating/mounting the data partition (i.e. partition number 2).
Name of Image: system_built_ext4.img
> ls system_built_ext4.imgsystem_built_ext4.img
Partition Details
Using parted
, lets find partition detail info along with their respective offsets. These offsets will come in handy later on.
- Run the command
sudo parted system_built_ext4.img UNIT b print
, as shown below. This tells parted to print out partition details, includingstart
andend
offsets inbytes
,
> sudo parted system_built_ext4.img UNIT b print
which produces the following output:
Model: (file)Disk /mnt/hgfs/vm-disks/system_built_ext4.img: 3232759808BSector size (logical/physical): 512B/512B
Partition Table: gptDisk Flags: Number Start End Size File system
1 1048576B 2097151B 1048576B
2 2097152B 3231711231B 3229614080B ext4
- If your preference is to work in sectors, substitute
UNIT b
(bytes) withUNIT s
(sectors) in the above command, i.e.
> sudo parted system_built_ext4.img UNIT s print
which generates the following output:
Model: (file)Disk /mnt/hgfs/vm-disks/system_built_ext4.img: 6313984sSector size (logical/physical): 512B/512B
Partition Table: gptDisk Flags: Number Start End Size File system
1 2048s 4095s 2048s
2 4096s 6311935s 6307840s ext4
Partition Offset Calculations
Since offset calculations need to be accurate for mounts to work, we’ll start out by the outlining the different methods foroffsets
calculations.
Method 1
From the output details of the first parted
command above, our second partition (Number 2
) is our data partition, and its starting point is at byte
number 2097152
. That's all there is to it. If you're using parted
or any other partitioning tool that supports options for specifying your data units, then all you need to do is set output Units to bytes, and record the start offset of the partition.
Method 2
You will on some occasions see references to calculating start offset using the partition’s startsector
. From the output of the second parted
command above, we can see that partition Number 2
starts at sector 4096
. You will also notice the output tells us that each sector is made up of 512 Bytes
:
Sector size (logical/physical): 512B/512B
So, to calculate the offset
in bytes
using sectors
and sector sizes
Partition 2, starts at sector : 4096
Number of bytes per sector : 512Offset converted to bytes = 4096 * 512 = 2097152
Option 1: Mount using losetup
We’re going to mount our data partition (i.e. Number 2
) to ablock/loop
device, but lets do some exploration before we start.
Status of loop Devices
To get a status of all loop devices, we run:
> losetup -a
, which produces the output:
/dev/loop1: []: (/var/lib/snapd/snaps/core18_1754.snap)
/dev/loop6: []: (/var/lib/snapd/snaps/software-boutique_54.snap)
/dev/loop4: []: (/var/lib/snapd/snaps/core_9289.snap)
/dev/loop2: []: (/var/lib/snapd/snaps/software-boutique_39.snap)
/dev/loop0: []: (/var/lib/snapd/snaps/ubuntu-mate-welcome_539.snap)
/dev/loop5: []: (/var/lib/snapd/snaps/ubuntu-mate-welcome_420.snap)
/dev/loop3: []: (/var/lib/snapd/snaps/core_9066.snap)
From reading the notes listed in doco, man losetup
, we can use the following commands:
- to get the details of the first unused
loop
device, runlosetup -f
> losetup -f/dev/loop7
- setup a loop device and associate it with our virtual disk image (
system_built_ext4.img
), specifying the offset to where our data partition (Number 2
) begins
> sudo losetup -f /mnt/hgfs/vm-disks/system_built_ext4.img -o 2097152
- in the above
losetup
command, we pass the virtual disk image path/name as an argument to-f
, followed by the offset-o
inbytes
of the partition's start location. This automatically "maps" the second partition within our virtual disk image with the first available loop device. Below has been taken from aman losetup
-f, --find [file] Find the first unused loop device. If a file argument is present, use the found device as loop device. Otherwise, just print its name.-o, --offset offset The data start is moved offset bytes into the specified file or device. The offset may be followed by the multiplicative suffixes
- To confirm the the image is now associated with a loop device we run a
losetup -a
:
> sudo losetup -a/dev/loop7: [0050]:32 (/mnt/hgfs/vm-disks/system_built_ext4.img)
,offset 2097152
- Now we can mount loop device onto a mount point and access the data/filesystem
> sudo mkdir /mnt/p2> sudo mount /dev/loop7 /mnt/p2
- To confirm we have a valid mount
> df | grep loop7/dev/loop7 3055092 4616 2876396 1% /mnt/p2
- To unmount
/mnt/p2
> sudo umount /mnt/p2
- To detach/free our loop device
> sudo losetup -d /dev/loop7
Option 2: One-Liner Mount Command
The mount
command allows us to perform a mount with the option loop
. Here are the details from man mount
:
THE LOOP DEVICE
One further possible type is a mount via the loop device.
For example, the command mount /tmp/disk.img /mnt -t vfat -o loop=/dev/loop3
will set up the loop device /dev/loop3
to correspond to the file /tmp/disk.img,
and then mount this device on /mnt. If no explicit loop device is mentioned
(but just an option '-o loop'; is given),
then mount will try to find some
unused loop device and use that, for example
....
....
This type of mount knows about three options,
namely loop, offset and sizelimit....
- So, translation of the above, we get our one-liner
> sudo mount /mnt/hgfs/vm-disks/system_built_ext4.img /mnt/p2 \
-o loop,offset=2097152
- To confirm
loop
device to.img
mapping
> sudo losetup -a /dev/loop7 [0050]:32 (/mnt/hgfs/vm-disks/system_built_ext4.img)
, offset 2097152> df | grep loop7/dev/loop7 3055092 4616 2876396 1% /mnt/p2
- To unmount filesystem and detach loop device
> sudo umount /mnt/p2
Option 3: Using kpartx
With kpartx
, we get the benefit of not having to worry about partition offsets. kpartx
handles the partition device mappings automatically. Refer to the extracts from parts of man kpartx
, which are attached at the end of this section.
- List partitions by specifying
-l
as an option
> sudo kpartx -l /mnt/hgfs/vm-disks/system_built_ext4.imgloop7p1 : 0 2048 /dev/loop7 2048
loop7p2 : 0 6307840 /dev/loop7 4096
- To setup the partition mappings
> sudo kpartx -a -v /mnt/hgfs/vm-disks/system_built_ext4.imgadd map loop7p1 (253:0): 0 2048 linear 7:7 2048
add map loop7p2 (253:1): 0 6307840 linear 7:7 4096
- According to the output of
man
, we can use the mappings, established by the above command, at location/dev/mapper
to access the partitions, i.e./dev/mapper/loop7p1
&/dev/mapper/loop7p2
- To mount our
Number 2
partition,
> sudo mount /dev/mapper/loop7p2 /mnt/p2
- and to confirm the the mount has occurred
> df | grep loop7p2/dev/mapper/loop7p2 3055092 4616 2876396 1% /mnt/p2
- Once you’re done, remove devices as follows
> sudo umount /mnt/p2> sudo kpartx -d /mnt/hgfs/vm-disks/system_built_ext4.img
kpartx man Excerpts
NAME: kpartx - Create device maps from partition tables.
SYNOPSIS
kpartx [-a|-d|-u|-l] [-r] [-p] [-f] [-g] [-s] [-v] wholediskDESCRIPTIONThis tool, derived from util-linux's; partx,
reads partition tables on specified device
and create device maps over partitions segments
detected. OPTIONS
-a Add partition mappings.
-d Delete partition mappings.
-u Update partition mappings.
-l List partition mappings that would be added -a.
-r Read-only partition mappings.
-p Set device name-partition number delimiter.
-f Force creation of mappings;
overrides 'no_partitions' feature.
-g Force GUID partition table (GPT).
-s Sync mode. Don't return until the partitions are created.
-v Operate verbosely.EXAMPLE
To mount all the partitions in a raw disk image:
kpartx -av disk.imgThis will output lines such as:
add map loop1p1 (254:4): 0 409597 linear 7:1 3The loop1p1 is the name of a device file under /dev/mapper which you can use to access the partitionWhen you're done, you need to remove the devices:
kpartx -d disk.img
Logging Out of this Article
There is nothing new about the techniques used in this article, i.e. you will find several online examples of the methods that were described. My main aim was to take an independent approach and use the official man
documentation as a reference to gain an understanding of the commands themselves, rather than copying and pasting from existing blogs/websites.
I’ve also covered the use of libguestfs-tools, via a custom docker, in one of my previous articles for working with virtual disk images, which is, yet again, another approach you could look into for working with virtual .img
images.