Bug 26996 - wrongly detects partition on unpartitioned VFAT device
Summary: wrongly detects partition on unpartitioned VFAT device
Status: RESOLVED FIXED
Alias: None
Product: udisks
Classification: Unclassified
Component: detection (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Martin Pitt
QA Contact:
URL: https://launchpad.net/bugs/536670
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-10 08:44 UTC by Martin Pitt
Modified: 2010-03-12 08:44 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Martin Pitt 2010-03-10 08:44:54 UTC
For a few weeks now, my Sony E-Book reader isn't automounted any more. Today I debugged this, and confirmed that it seems to happen consistently for all unpartitioned device (i. e. fs on raw /dev/sdb).

I tracked it down to gdu not finding any volumes because udisks claims that DeviceIsPartitionTable=True (and thus doesn't get to the check whether there's a volume on the raw device):

Showing information for /org/freedesktop/UDisks/devices/sdb
  native-path:                 /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8.2/1-8.2:1.0/host13/target13:0:0/13:0:0:0/block/sdb
  device-file:                 /dev/sdb
    presentation:              (not set)
[...]
  has media:                   1 (detected at Mi 10 Mär 2010 17:43:50 CET)
[...]
  usage:                       filesystem
  type:                        vfat
  version:                     FAT32
  uuid:                        AC4B-3B29
  label:                       PittiRAW
  partition table:
    scheme:                    mbr
    count:                     0

This looks wrong.
Comment 1 Martin Pitt 2010-03-10 08:48:08 UTC
I just checked that I can reproduce that in the test suite, which uses a clean and zeroed-out device, so it's not the usual "gets confused about two different signatures on the device".

http://cgit.freedesktop.org/udisks/commit/?id=47ac2676ca6d209705f9f814cded2daf19f24e76

Now the test suite properly fails:

$ sudo tests/run FS.test_vfat
Testing binaries from local build tree
daemon path: src/udisks-daemon
mdadm: array /dev/md125 started.
fs: FAT ... [cli]FAIL

======================================================================
FAIL: fs: FAT
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests/run", line 412, in test_vfat
    self._do_fs_check('vfat')
  File "tests/run", line 443, in _do_fs_check
    self._do_mkfs_check(type)
  File "tests/run", line 473, in _do_mkfs_check
    self.failIf ('partition_scheme' in i)
AssertionError
Comment 2 Martin Pitt 2010-03-10 08:50:56 UTC
Interesting, it only seems to happen for VFAT, not for any other file system.

It seems likely that the bug is actually in libparted:

$ sudo /lib/udev/udisks-part-id /dev/sdb
device=0xe56e00' for devpath=/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8.2/1-8.2:1.0/host13/target13:0:0/13:0:0:0/block/sdb
Expected `linear' in UDISKS_DM_TARGETS_TYPE=`(null)'
using device_file=/dev/sdb syspath=/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8.2/1-8.2:1.0/host13/target13:0:0/13:0:0:0/block/sdb, offset=0 ao=0 and number=0 for /dev/sdb
Entering MS-DOS parser (offset=0, size=1028653056)
MSDOS_MAGIC found
looking at part 0 (offset 0, size 0, type 0x00)
new part entry
looking at part 1 (offset 0, size 0, type 0x00)
new part entry
looking at part 2 (offset 0, size 0, type 0x00)
new part entry
looking at part 3 (offset 0, size 0, type 0x00)
new part entry
Exiting MS-DOS parser
MSDOS partition table detected
UDISKS_PARTITION_TABLE=1
UDISKS_PARTITION_TABLE_SCHEME=mbr
UDISKS_PARTITION_TABLE_COUNT=0
Comment 3 David Zeuthen (not reading bugmail) 2010-03-10 09:12:35 UTC
(In reply to comment #2)
> Interesting, it only seems to happen for VFAT, not for any other file system.
> 
> It seems likely that the bug is actually in libparted:

Nitpick: We don't use libparted code at all for detection - the code in question is in src/helpers/partutil.c

> $ sudo /lib/udev/udisks-part-id /dev/sdb
> device=0xe56e00' for
> devpath=/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8.2/1-8.2:1.0/host13/target13:0:0/13:0:0:0/block/sdb
> Expected `linear' in UDISKS_DM_TARGETS_TYPE=`(null)'
> using device_file=/dev/sdb
> syspath=/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8.2/1-8.2:1.0/host13/target13:0:0/13:0:0:0/block/sdb,
> offset=0 ao=0 and number=0 for /dev/sdb
> Entering MS-DOS parser (offset=0, size=1028653056)
> MSDOS_MAGIC found
> looking at part 0 (offset 0, size 0, type 0x00)
> new part entry
> looking at part 1 (offset 0, size 0, type 0x00)
> new part entry
> looking at part 2 (offset 0, size 0, type 0x00)
> new part entry
> looking at part 3 (offset 0, size 0, type 0x00)
> new part entry
> Exiting MS-DOS parser
> MSDOS partition table detected
> UDISKS_PARTITION_TABLE=1
> UDISKS_PARTITION_TABLE_SCHEME=mbr
> UDISKS_PARTITION_TABLE_COUNT=0

The (known) problem is that VFAT on the main block device looks a lot like a Master Boot Record partition table. We need to fix the MBR probing code.



Comment 4 Martin Pitt 2010-03-10 10:25:01 UTC
Personal notekeeping:

I checked out a very old udisks version, and the partition prober has the same problem. It just was hidden in the past by the different media detection logic.

Commit 589ec28a2c156676d4efe976e49bd87226e7dad2 works (wrt. the DeviceIsPartitionTable property), commit d1c41e95ffe11917dd945694be5ebad9a831d294 fails. I didn't bisect it down, since the particular patch which exposed that bug is most probably not at fault, we need to fix part-id itself.
Comment 5 Martin Pitt 2010-03-10 10:39:25 UTC
Got to stop for today. Ideas for tomorrow: 

 - It's implausible to have a partition start at offset 0 (since that's where the MBR is)
 - TODO: check if partition type 0 is allowed
 - TODO: current blkid can tell them apart just fine, check its logic (since eventually udisks-part-id will go away, and we'll use blkid for partition probing)
Comment 6 David Zeuthen (not reading bugmail) 2010-03-10 11:31:48 UTC
(In reply to comment #5)
> Got to stop for today. Ideas for tomorrow: 
> 
>  - It's implausible to have a partition start at offset 0 (since that's where
> the MBR is)
>  - TODO: check if partition type 0 is allowed
>  - TODO: current blkid can tell them apart just fine, check its logic (since
> eventually udisks-part-id will go away, and we'll use blkid for partition
> probing)
> 

Right. Might be worth looking at the kernel partition table probing code too (it's in fs/partitions/msdos.c).

Note that partition type 0 and/or offset 0 and/or size 0 normally means "partition slot not used". For example, it's perfectly valid to have only two partitions in slots 1 and 3 - and the kernel represents such a device as /dev/sda for the whole disk and /dev/sda1 and /dev/sda3 for the two partitions.
Comment 7 Martin Pitt 2010-03-10 14:46:28 UTC
So, both the kernel code and blkid look surprisingly similar (what a coincidence :-P). I also checked the MBR spec [1], and if we allow 0 offset/type partitions for empty partitions we can't indeed reliably detect an MSDOS partition table by itself, we have to check whether it is a valid FAT header (which has a much more rigid structure), and if we don't find one, assume that we have an MBR.

Now, I see two possibilities:

 1) We can copy the FAT detection logic from blkid (which is a tad more rigid than the kernel's)

 2) We can assume that blkid is reliable (I don't see much evidence that it isn't), and skip partition probing if we already have a fs:

  ENV{ID_FS_TYPE}=="", IMPORT{program}="udisks-part-id $tempnode"

(2) is essentially the same logic as (1) but avoids the overhead of calling part-id if we already know that there's a file system. It's also one step closer to getting rid of part-id in favor of a blkid based partition probing.

I verified that this rule brings back automounting, and the automatic tests are happy again as well.

So I'd favor (2), but if you see a reason to always call part-id, I can also work on (1).

[1] http://en.wikipedia.org/wiki/Master_boot_record
Comment 8 David Zeuthen (not reading bugmail) 2010-03-10 16:02:26 UTC
(In reply to comment #7)
> So, both the kernel code and blkid look surprisingly similar (what a
> coincidence :-P). I also checked the MBR spec [1], and if we allow 0
> offset/type partitions for empty partitions we can't indeed reliably detect an
> MSDOS partition table by itself, we have to check whether it is a valid FAT
> header (which has a much more rigid structure), and if we don't find one,
> assume that we have an MBR.
> 
> Now, I see two possibilities:
> 
>  1) We can copy the FAT detection logic from blkid (which is a tad more rigid
> than the kernel's)
> 
>  2) We can assume that blkid is reliable (I don't see much evidence that it
> isn't), and skip partition probing if we already have a fs:
> 
>   ENV{ID_FS_TYPE}=="", IMPORT{program}="udisks-part-id $tempnode"
> 
> (2) is essentially the same logic as (1) but avoids the overhead of calling
> part-id if we already know that there's a file system. It's also one step
> closer to getting rid of part-id in favor of a blkid based partition probing.
> 
> I verified that this rule brings back automounting, and the automatic tests are
> happy again as well.
> 
> So I'd favor (2), but if you see a reason to always call part-id, I can also
> work on (1).

Let's just go for (2) - seems simpler. Thanks.

> 
> [1] http://en.wikipedia.org/wiki/Master_boot_record
> 

Comment 10 David Zeuthen (not reading bugmail) 2010-03-11 12:28:30 UTC
Actually I had to revert this:

http://cgit.freedesktop.org/udisks/commit/?id=b51dc7ac853ec3f11735a0e893dfe11365f14ee2

We should probably do the ID_FS_TYPE comparison inside part-id only when we are sure we are dealing with the main block device and not a partition. Have to be careful here, remember we support kpartx style partitions now...
Comment 11 Martin Pitt 2010-03-11 23:33:53 UTC
(In reply to comment #10)
> We should probably do the ID_FS_TYPE comparison inside part-id only when we are
> sure we are dealing with the main block device and not a partition. Have to be
> careful here, remember we support kpartx style partitions now...
> 

> This commit actually broke partition table parsing for the partitions itself, 
> e.g. this output [...] if the partition in question had a recognizable 
> filesystem.

Hm, I'm afraid I don't follow -- If a partition has a recognizable file system, how can it have a partition table at the same time? The device which you quoted in the reversion git log, which ID_FS_* properties did it have, and which kind of partition was that?

I see that the previous change would break situations where a particular device (raw or partition, doesn't matter) is both a fs and a partition table, but I don't know how this is possible?
Comment 12 Martin Pitt 2010-03-12 04:25:03 UTC
Ergh, sorry for my density, ignore my previous comment. I'll work on a better fix.
Comment 13 Martin Pitt 2010-03-12 07:21:40 UTC
I made the test suite more complete (test partitions with and without file systems), to catch that regression:

http://cgit.freedesktop.org/udisks/commit/?id=b2b116296d9973203c20be1a1060015ebdd1ce39


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.