Skip to content

"recursive partition on /dev/sda" with FAT12 partitions formated with "mkfs.vfat [...] --mbr=y".

Hi,

I'm trying to compare 2 FAT12 files that were created with mkfs.vfat -a --mbr=y -n MEDIA --invariant preseed.img. Files were added to it with mcopy -i preseed.img -m preseed.cfg ::/preseed.cfg (and a similar command for the second file).

Here's their content:

$ mdir -i preseed.img.old /
 Volume in drive : is MEDIA      
 Volume Serial Number is 1234-ABCD
Directory for ::/

preseed  cfg      3573 2098-01-01   0:00 
SHUTDO~1 SER       560 2098-01-01   0:00  shutdown-after-boot.service
        2 files               4 133 bytes
                          1 021 952 bytes free
$ mdir -i preseed.img.new /
 Volume in drive : is MEDIA      
 Volume Serial Number is 1234-ABCD
Directory for ::/

preseed  cfg      3573 2098-01-01   0:00 
SHUTDO~1 SER       560 2098-01-01   0:00  shutdown-after-boot.service
        2 files               4 133 bytes
                          1 021 952 bytes free

Here we can see that the same files are decoded fine by fdisk:

$ fdisk -l preseed.img.old 
Disk preseed.img.old: 1 MiB, 1048576 bytes, 2048 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
Disklabel type: dos
Disk identifier: 0x1234abcd

Device           Boot Start   End Sectors Size Id Type
preseed.img.old1 *        0  2047    2048   1M  1 FAT12
$ fdisk -l preseed.img.new 
Disk preseed.img.new: 1 MiB, 1048576 bytes, 2048 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
Disklabel type: dos
Disk identifier: 0x1234abcd

Device           Boot Start   End Sectors Size Id Type
preseed.img.new1 *        0  2047    2048   1M  1 FAT12

Note that here the 'MBR' size is 0.

If I try diffoscope from Guix which lacks support for guestfs, we can see some minimal differences:

 /gnu/store/nx3ayldwfc4nx5ncrgbrdv6602j2x66h-diffoscope-224/bin/diffoscope preseed.img.old preseed.img.new 
--- preseed.img.old
+++ preseed.img.new
│┄ Format-specific differences are supported for ext2/ext3/ext4/btrfs/fat filesystems but no file-specific differences were detected; falling back to a binary diff. file(1) reports: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, root entries 512, sectors 2048 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 2, sectors/track 16, serial number 0x1234abcd, label: "MEDIA      ", FAT (12 bit)
│┄ Installing the 'guestfs' package may produce a better output.
@@ -157,23 +157,23 @@
 000009c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 000009d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 000009e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 000009f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000a00: 4d45 4449 4120 2020 2020 2008 0000 5a4b  MEDIA      ...ZK
 00000a10: 6e46 6e46 0000 5a4b 6e46 0000 0000 0000  nFnF..ZKnF......
 00000a20: 5052 4553 4545 4420 4346 4720 1800 0000  PRESEED CFG ....
-00000a30: 21ec 21ec 0000 0000 21ec 0200 f50d 0000  !.!.....!.......
+00000a30: 21ec 2859 0000 0000 21ec 0200 f50d 0000  !.(Y....!.......
 00000a40: 4365 0000 00ff ffff ffff ff0f 0000 ffff  Ce..............
 00000a50: ffff ffff ffff ffff ffff 0000 ffff ffff  ................
 00000a60: 0272 002d 0062 006f 006f 000f 0000 7400  .r.-.b.o.o....t.
 00000a70: 2e00 7300 6500 7200 7600 0000 6900 6300  ..s.e.r.v...i.c.
 00000a80: 0173 0068 0075 0074 0064 000f 0000 6f00  .s.h.u.t.d....o.
 00000a90: 7700 6e00 2d00 6100 6600 0000 7400 6500  w.n.-.a.f...t.e.
 00000aa0: 5348 5554 444f 7e31 5345 5220 0000 0000  SHUTDO~1SER ....
-00000ab0: 21ec 21ec 0000 0000 21ec 0400 3002 0000  !.!.....!...0...
+00000ab0: 21ec 2859 0000 0000 21ec 0400 3002 0000  !.(Y....!...0...
 00000ac0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000ad0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000ae0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000af0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000b00: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000b10: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000b20: 0000 0000 0000 0000 0000 0000 0000 0000  ................

But if instead I try the diffoscope from Arch Linux which has support for guestfs:

$ pacman -sS diffoscope
extra/diffoscope 277-1 [installed]
    Tool for in-depth comparison of files, archives, and directories

we have a bug (recursive partition on /dev/sda):

$ diffoscope preseed.img.old preseed.img.new =

 |#######################################################################=
#########################################################################=
#########|  100%                             ETA:  00:00:00 Traceback (mo=
st recent call last):
  File "/usr/lib/python3.12/site-packages/diffoscope/main.py", line 767, =
in main
    sys.exit(run_diffoscope(parsed_args))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/main.py", line 718, =
in run_diffoscope
    difference =3D compare_root_paths(path1, path2)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/utils/co=
mpare.py", line 69, in compare_root_paths
    difference =3D compare_files(file1, file2)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/utils/co=
mpare.py", line 149, in compare_files
    return file1.compare(file2, source)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/utils/fi=
le.py", line 536, in compare
    difference =3D self._compare_using_details(other, source)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/utils/fi=
le.py", line 437, in _compare_using_details
    details.extend(self.compare_details(other, source))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/fsimage.=
py", line 121, in compare_details
    if hasattr(self.as_container, "fs"):
               ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/utils/fi=
le.py", line 296, in as_container
    self._as_container =3D klass(self)
                         ^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/utils/ar=
chive.py", line 43, in __init__
    self._archive =3D self.open_archive()
                    ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/diffoscope/comparators/fsimage.=
py", line 72, in open_archive
    self.fs =3D self.g.list_filesystems()[devices[0]]
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/guestfs.py", line 6581, in list=
_filesystems
    r =3D libguestfsmod.list_filesystems(self._o)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: list_filesystems: parted exited with status 1: Error: Inval=
id partition table - recursive partition on /dev/sda.

I can share the files if needed, they take only about 2.1KiB compressed in a tarball but it's probably easier to reproduce with mkfs.vfat and mtools.

The fix here could be to recognize this FAT12 situation as special because for some reason the 'MBR' size is 0, so it's probably implicit somehow from the FAT12 formatting. We can also see that here using mtools didn't require to specify any offset. And this is precisely because of that that I used FAT12 to create these files: it simplify things as we don't need to compute an offset.

Denis.

Edited by Chris Lamb
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information