Systems engineers, embedded developers, and digital forensics investigators frequently work with raw disk images (.img, .iso, .raw, or virtual machine disk files). While standard files reside inside established filesystems, a disk image is a virtual container representing raw sectors, partition tables, and nested filesystems. To interact with an individual partition inside a disk image—formatting it with ext4, inspecting metadata, repairing corruption with fsck, or mounting a virtual root file system—the Linux kernel must map the regular file into a virtual block device.
The Linux loop device driver provides this translation layer, and the primary command-line interface for orchestrating loop devices is losetup. By binding disk files to virtual block devices (such as /dev/loop0), losetup enables standard filesystem management utilities (like fdisk, mkfs, and mount) to operate on container files as if they were physical NVMe drives or SATA disks. This technical guide explains how loop devices operate in the Linux kernel, how to configure loop bindings with losetup, how to map partitioned disk images with partx, and how to detach devices cleanly.
Architecture of the Linux Loop Control Driver
The Linux loop driver (/dev/loop-control) dynamically creates and allocates loop block devices (/dev/loopX). When an application reads from or writes to a loop device, the kernel loop subsystem intercepts the block I/O requests and translates them into file offset reads and writes against the underlying image file.
| Operational Mode | Key Parameter | Kernel Behavior |
|---|---|---|
| Direct File Binding | losetup /dev/loopX file.img |
Binds the entire file as an unpartitioned block device. |
| Partition Scanning | losetup -P file.img |
Forces the kernel to scan the disk image partition table and generate sub-devices (e.g., /dev/loop0p1, /dev/loop0p2). |
| Read-Only Access | losetup -r file.img |
Prevents accidental modifications during forensic investigations or recovery tasks. |
| Offset Mapping | losetup -o <offset_bytes> file.img |
Maps a specific byte offset within the disk image directly to the start of the block device. |
Querying Active Loop Devices
Before creating new loop mappings, audit existing block device bindings to identify allocated devices and available loop numbers:
# List all active loop devices with underlying files, offsets, and flags
losetup -a
# Find the first completely unused loop device
sudo losetup -f
The output returns structured mapping details:
/dev/loop0: [66306]:262148 (/var/lib/snapd/snaps/core22_864.snap) (read-only)
/dev/loop1: [66306]:262152 (/var/lib/snapd/snaps/firefox_3200.snap) (read-only)
Step 1: Creating a Blank Raw Disk Image
To simulate a virtual block device or test partitioning schemes, generate an empty raw disk image file using dd or fallocate:
# Rapidly allocate a sparse 2GB virtual disk file
fallocate -l 2G virtual_disk.raw
# Alternatively, create using dd with zeroed blocks
dd if=/dev/zero of=virtual_disk.raw bs=1M count=2048 status=progress
Step 2: Binding Disk Images with Automated Partition Scanning
If your disk image contains multiple partitions (e.g., a master boot record or GUID partition table), the kernel must scan and instantiate sub-devices for each partition. The -P (or --partscan) flag automates this process:
# Bind the disk image to the next available loop device with partition scanning
sudo losetup -Pf virtual_disk.raw
# Verify the assigned loop device name
losetup -j virtual_disk.raw
# Output: /dev/loop2: [66306]:524290 (/home/ubuntu/virtual_disk.raw)
Step 3: Partitioning and Formatting the Virtual Block Device
With the loop device bound, treat /dev/loop2 exactly like a physical hardware disk:
# Partition the virtual disk using fdisk
sudo fdisk /dev/loop2 << 'EOF'
n
p
1
+1G
n
p
2
w
EOF
# Inform the kernel of partition table updates if needed
sudo partx -u /dev/loop2
# Verify the newly spawned partition block devices
lsblk /dev/loop2
The partition table will display nested child block devices:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop2 7:2 0 2G 0 loop
├─loop2p1 7:3 0 1G 0 loop
└─loop2p2 7:4 0 1G 0 loop
Formatting and Mounting Individual Partitions
# Format partition 1 with ext4 and partition 2 with XFS
sudo mkfs.ext4 -L DataVol /dev/loop2p1
sudo mkfs.xfs -L BackupVol /dev/loop2p2
# Create mount points and mount partitions
sudo mkdir -p /mnt/loop_vol1 /mnt/loop_vol2
sudo mount /dev/loop2p1 /mnt/loop_vol1
sudo mount /dev/loop2p2 /mnt/loop_vol2
# Verify active mount statuses
df -hT | grep loop2
Step 4: Manual Offset Mapping for Partition Extraction
When working on legacy systems where partition scanning (-P) is unavailable, map a partition directly by calculating its sector byte offset using fdisk -l:
# Display sector metrics for the disk image
fdisk -l virtual_disk.raw
If partition 1 begins at Sector 2048 and the sector size is 512 bytes, calculate: 2048 * 512 = 1,048,576 bytes offset.
# Bind specifically to partition 1 using the calculated byte offset
sudo losetup -o 1048576 /dev/loop3 virtual_disk.raw
# Mount directly without needing partition suffixes
sudo mount /dev/loop3 /mnt/extracted_partition
Safely Unmounting and Detaching Loop Devices
Failing to detach loop devices prior to deleting image files can lead to orphaned device handles and kernel resource leaks. Follow this safe detachment sequence:
# 1. Unmount all active filesystems associated with the loop device
sudo umount /mnt/loop_vol1 /mnt/loop_vol2
# 2. Detach the specific loop device
sudo losetup -d /dev/loop2
# 3. Detach all orphaned or unused loop devices system-wide
sudo losetup -D
# 4. Verify that loop mappings have cleared
losetup -a
Troubleshooting Common Loop Device Issues
| Issue Encountered | Underlying Cause | Remediation Step |
|---|---|---|
losetup: /dev/loopX: Device or resource busy |
Loop device is still mounted or held open by a process. | Identify blocking handles with fuser -mv /dev/loopX, unmount all filesystems, and re-run losetup -d /dev/loopX. |
Sub-partitions (/dev/loopXp1) missing after binding |
Image bound without -P partition scan flag. |
Execute sudo partx -a /dev/loopX to force the kernel to scan the partition table dynamically. |
losetup: cannot find an unused loop device |
Maximum loop device ceiling reached. | Detach unused loop devices using losetup -D or load additional devices via modprobe loop max_loop=64. |
Mastering the losetup utility provides Linux administrators and forensic analysts with complete control over disk images, enabling seamless partition mounting, filesystem formatting, and virtual storage operations across production environments.