Loop device partition scanning on Ubuntu 14.04

  |   Source

In Embedded Computing, we often face the problem to prepare images for entire storage media. Nowadays this applies especially to SD cards. Whereas other operating systems usually need special utilities for such situations, Linux has all the means already built-in to deal with this. The loopback device plays a central role here as it can expose a regular file as a kernel level block device. This block device can then be used in place of a "real" SD card together with regular programs.

One recurring problem however is how to deal with images that contain partitioned data, i.e. that need to be exposed through "sub devices" on a partition level. Searching the internet for solutions on this usually turns up advice on how to manually use losetup multiple times with manually calculated partition offsets. There are even scripts encapsulating this nicely. Recently I discovered that the kernel already has support for that and makes such scripts completely unnecessary. When you use a util-linux version of 2.21 or later, it is as easy to use as specifying --partscan to losetup and voila, minor number device node are created for the partitions automatically.

Unfortunately, one of the more widely used GNU/Linux distributions, e.g. Ubuntu 14.04 still carries util-linux in version 2.20 and we thus don't have that easy way available. Researching the situation some more shows a mildly complicated workaround however - setting the max_part module parameter for the loop device to some number greater than 0. As the driver is built into the Ubuntu kernel, we have to change it through the kernel command line. Edit /etc/default/grub and change the following line:

GRUB_CMDLINE_LINUX="loop.max_part=63"

Now rerun update-grub and reboot. With this parameter the loop device will do an automatic partition scan and immediately create up to 63 devices. Here's an example from a terminal session:

$ sudo losetup /dev/loop0 core-image-minimal-imx6qsabresd.sdcard
[sudo] password for dzu:
$ sudo fdisk -l /dev/loop0
Disk /dev/loop0: 25 MB, 25165824 bytes
4 heads, 32 sectors/track, 384 cylinders, total 49152 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
Disk identifier: 0x00019a5c

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192       24575        8192    c  W95 FAT32 (LBA)
/dev/loop0p2           24576       40959        8192   83  Linux
$ ls -l /dev/loop0*
brw-rw---- 1 root disk 7, 0 Apr 17 10:47 /dev/loop0
brw-rw---- 1 root disk 7, 1 Apr 17 10:47 /dev/loop0p1
brw-rw---- 1 root disk 7, 2 Apr 17 10:47 /dev/loop0p2
Comments powered by Disqus