I'm working on a huge complex application. You connect a disk, press a button, and it partitions and formats the disk, mounts it, and copies some files onto it.

To test this application, we have a test system which loop-mounts a disk image and runs through the same process. Except we changed the application logic, and now the test system doesn't work. If you give the program a real disk, everything works fine. But if you give it a loop device, it fails.

Specifically, the application partitions the disk, formats it, and then whines that it can't mount the partition. The exact command is

mount /dev/vda /mnt --rw -o offset=111149056,sizelimit=314572800

(Here /dev/vda is merely a symlink to /dev/loop0. It makes no difference if I refer to loop0 directly.)

If I run the command by hand, I get this:

root# mount /dev/vda /mnt --rw -o offset=111149056,sizelimit=314572800
FUSE exfat 1.0.1
ERROR: exFAT file system is not found.
root# echo $?

I can run this command over and over again, and it just doesn't work. No reason, it just doesn't.

Here is the terrifying part: If I run cfdisk /dev/vda and then immediately quit without changing anything, now it mounts!!

What the hell does cfdisk do to the disk that makes it suddenly start working? And how can I remove the need to call this program?

(I tried in vain to call sfdisk -R /dev/vda; it just complains about "invalid parameter" or something.)

I can kludge the application to call cfdisk -Ps /dev/vda or something, but I would really, really rather not do that. I want to find out why any of this is even necessary. Before we changed the application, everything worked fine...

  • Check the contents of /proc/partitions before and after cfdisk and see if anything changes. Additionally: when it does mount, what filesystem is used? Does it help if you explicitly tell mount what filesystem to use if it's not exfat? – wurtel Sep 17 '14 at 14:12
  • Correct filesystem is ext4. I will take a look at /proc/partitions... – MathematicalOrchid Sep 17 '14 at 14:25
  • Is the type always ext4? If so use, mount -t ext4 /dev/vda /mnt --rw -o offset=111149056,sizelimit=314572800. The -t option specifies the filesystem type. – eyoung100 Sep 17 '14 at 14:34
  • MD5 of /proc/partitions doesn't ever change. Adding -t ext4 causes the error text to change to wrong fs type, bad option, bad superblock on /dev/loop0. – MathematicalOrchid Sep 17 '14 at 14:38

A stab in the dark, but maybe cfdisk updates the kernel partition table when it runs?

Is your application logic compatible with loop devices?

  1. Format the disk image file, creating your desired partitions
  2. Setup the loopback device using the -P option to update the kernel's partition table:

    losetup -P /dev/loop0 <image file>

  3. Mount the partition: mount /dev/loop0p1 /mnt

This way, there is no need to bother with offsets and your mount command is closer to the one you'd use with a real disk. You could presumably add another step between 2 and 3 to create a symlink as you have.

  • We deliberately moved away from using partition nodes so that we don't have to rely on the OS to correctly parse the partition table(s). We have code that reads the MBR and/or GPT and figures out all the correct offsets automatically. And until today, it's all worked fine. I don't know what's so different about this setup that it fails with loop devices, yet works with real ones... – MathematicalOrchid Sep 17 '14 at 14:42
  • Frankly, chances are reasonable that your homebrewed solution has bugs, that the kernel or partx code already fixed. As for cfdisk - check kernel buffer to see what kernel thought when you used cfdisk. – peterph Sep 17 '14 at 14:49
  • Turns out using /dev/mapper/loop0p1 doesn't work anyway... – MathematicalOrchid Sep 18 '14 at 9:12

The kernel first has to learn about the partitions. Once you partition a loop device (say /dev/loop0) you can't really mount it as such (the partition obviously doesn't begin at the beginning of the device). For physical drives you can instruct the kernel to re-read the partition table (at least fro (S)ATA drives) with hdparm -z.

Another option is to use a special utility, that will scan the device for a partition table (not necessarily just GPT or MBR) and create the partition device files for you. One of those is partx (comes with util-linux).

  • The test framework already has logic to run kpartx and symlink all the device nodes it creates, such that /dev/vda, /dev/vda1, /dev/vda2, etc exist - just like with a real disk. – MathematicalOrchid Sep 17 '14 at 14:40
  • OK, in that case you probably want to include that in the question. You should also say, what are you using for formatting the partitions etc. – peterph Sep 18 '14 at 12:55

I made a small change to the test framework, and the problem went away.

Specifically, rather than calling kpartx -u /dev/vda after I repartition the device, I call kpartx -d followed by kpartx -a. And now everything is fine. Weird...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.