Loop device partition scanning on Ubuntu 14.04
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:
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