3

What I have: I know the place in the filesystem where a microSD card is mounted, e.g. /storage/sdcard1

What I need: To find out which device folder it corresponds to, e.g. /sys/class/mmc_host/mmc0 (which is a link to /sys/devices/msm_sdcc.1/mmc_host/mmc0) vs. /sys/class/mmc_host/mmc1 (which is a link to /sys/devices/msm_sdcc.2/mmc_host/mmc1).

I need to find the right directory so that I can grab the contents of files under it, such as cid, serial, oemid, and so on.

I could take a guess that /sys/class/mmc_host/mmc1 corresponds to the microSD card mounted at /storage/sdcard1, but on some Android devices it's mmc0.

Since we're on Android, we have some limitations relative to more typical Linux:

  • no /etc/mtab or /etc/fstab files exist
  • no hwinfo or hdparm commands
  • dmesg doesn't run (klogctl: operation not permitted)
  • df doesn't output the "mounted on" column
  • no access to stat() or other low-level calls; at least not without some NDK development, which is a deep swimming pool to dive into, requiring architecture-specific builds

Here's the output of df related to the microSD card:

Filesystem               Size     Used     Free   Blksize
/storage/sdcard1        29.0G     2.0G    27.0G   32768

(which is confusing because I thought, and mount indicates, that /storage/sdcard is the mount point rather than the filesystem).

And the relevant output of mount:

/dev/block/vold/179:65 /mnt/media_rw/sdcard1 vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1023,gid=1023,fmask=0007,dmask=0007,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
/dev/fuse /storage/sdcard1 fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0

The above shows that the filesystem mounted at /storage/sdcard1 is /dev/fuse. But /dev/fuse is mounted in three places:

$ mount | grep fuse                                    
/dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /storage/emulated/legacy fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /storage/sdcard1 fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0

and in any case I still don't see any way to figure out which /sys/class/... or /sys/devices/... directory corresponds to /storage/sdcard1.

So, one way to answer the initial question would probably be to answer the sub-question, How can I find out the /sys/class or /sys/devices entry for a FUSE-mounted filesystem? That should answer the question for this case at least (but I don't know if all Android devices mount microSD cards in the same way).

Any suggestions are appreciated.

1
  • It was difficult to choose which answer to award the bounty to, since there were three helpful answers, but none of them led to a full solution (yet). Thank you all for your effort and input. – LarsH Nov 2 '15 at 16:30
4

As explained by Dan, this filesystem is provided by FUSE, which means that it is implemented in user-space and the mount line you quote doesn't say which user-space file-system is in use. So for all we know it could be any program and could do any random thing. E.g. it might provide the data blocks by combining blocks from various devices, and/or from the network, and/or any other way that might have crossed the programmer's mind.

Of course, in practice you can probably expect, based on contextual knowledge, that the data comes from one of those mmc devices. But even that might be difficult to figure out because it could gets its data from that mmc device via the device-mapper (as seems to be the case here where I'd be tempted to guess that /storage/sdcard1 is provided via FUSE from /mnt/media_rw/sdcard1 which itself comes from /dev/block/vold/179:65 which is defined in the device-mapper to come from one of the mmc devices (tho of course it too could be a combination of devices, since device-mapper can do RAID-0/1).

So in theory, you could try to figure out (not sure how) which process is is associated (as a FUSE-daemon) to this mount point, then look at this process in /proc/ to see which files it has open and guess from these open files where it takes its data (i.e. find out that it comes from /mnt/media_rw/sdcard1), then look at /proc/mounts again to find out that this comes from /dev/block/vold/179:65, then somehow figure out the configuration of this logical volume (I couldn't find the info in /sys or /proc but it might be there somewhere) to finally find the device you're looking for.

I'm pretty sure that in theory you can't write a program which can guarantee it will find your answer. In practice, you can probably cobble up something that works for your use-cases, given enough motivation, time, and ugly hacks.

Depending on details of the resources to which you have access, an easier solution might be to do it more "holistically": don't pay attention to the path that the data takes from the device to the mount-point (and back), but instead look at the data in that mount point then look at the data on the various devices, and decide which device it is based on how they correlate.

E.g. write a file that contains 512 bytes of random data in that file system, and then look for that exact sequence of 512 bytes in the candidate devices's blocs. If you can find it there, you can bet that this is your answer. Or if you don't want to have to write: take the first 512 bytes of some file on that file-system, then look for it in the devices's blocs. If it's only found on one of the devices, then you have your answer.

3
  • Thank you, this is helpful. I can't rely on being able to write to devices, but reading a file on them should work fine. How would I find the data in a candidate device's blocs? E.g. if the device is at /sys/class/mmc_host/mmc1(/mmc1:1234), where do I look for its data? And would I have to look through all the gigabytes of data on the SD card? – LarsH Oct 28 '15 at 14:05
  • 1
    I guess you'd have to look at something like /proc/emmc to find the partitions that exist for this device, then look for the corresponding device nodes in /dev/ (e.g. /dev/[block/]mmcblk1p2), then read from that device node (which probably requires root access). And yes, you'd have to look through the gigabytes of data on that card. You could probably weed out most candidate device nodes if you compare the size of that device with the size of the filesystem. – Stefan Oct 28 '15 at 14:13
  • Unfortunately, Android (at least the version I have on this phone) doesn't have a /proc/emmc. I like the idea of comparing the size of the device with the size of the filesystem; going through gigabytes of data would be too slow. – LarsH Oct 31 '15 at 2:28
2

The /sys directory (AKA the Linux kernel sysfs) only applies to kernel objects.

The /storage/sdcard1 device you mention is not directly mounted as a kernel driver, it's mounted in userspace, wrapped using FUSE.

The mapping of a FUSE mount point to a particular /sys device (if any, FUSE-mounted filesystems might not even have an underlying kernel device) cannot usually be determined from regular mounting information, except maybe by reasoning, for example if it's the only device (of that specific type) being mounted.

It might be possible to obtain the mapping info from FUSE, but I have no clue if/how.

2
  • Thanks for responding. The cid, serial, and so on are available under /sys (e.g. under /sys/class/mmc_host/mmc0). Maybe you mean, the mapping between /storage/sdcard1 and /sys/class/mmc_host/mmc0 isn't available under /sys? Do you know where I could find mount mapping information for devices that are mounted under FUSE? – LarsH Oct 26 '15 at 14:31
  • 1
    Yep, that's what I meant. I updated the answer. – Dan Cornilescu Oct 26 '15 at 15:05
1
+150

Some scratches too long to be a comment:

  1. It is not unusual to have the same device mounted in more than one place (maybe with different read/write rights...). A mount | grep fuse | grep -v emulated in your example should help to select among the emulated mount point.

  2. In android 4.2.2 and earlier it actually exists vold.fstab, an help script that does the job instead of /etc/fstab (before it was vold.conf[1]). Probably you can parse that script and obtain a good starting point. The syntax for Android 4.2.2 and earlier is [2]:

    dev_mount <label> <mount_point> <partition> <sysfs_path> [flags]
    
    • label: Label for the volume.
    • mount_point: Filesystem path where the volume should be mounted.
    • partition: Partition number (1 based), or 'auto' for first usable partition.
    • sysfs_path: One or more sysfs paths to devices that can provide this mount point. Separated by spaces, and each must start with /.
    • flags: Optional comma separated list of flags, must not contain /. Possible values include nonremovable and encryptable.
  3. For Android releases 4.3 and later

    the various fstab files used by init, vold and recovery were unified in the /fstab.<device> file.

    So you should have your device name highlighted in the filename.

    Again it is reported [2] that for the external storage volumes that are managed by vold, you should find the following format:

    <src> <mnt_point> <type> <mnt_flags> <fs_mgr_flags>
    

    where

    • src: A path under sysfs (usually mounted at /sys) to the device that can provide the mount point. The path must start with /.
    • mount_point: Filesystem path where the volume should be mounted.
    • type: The type of the filesystem on the volume. For external cards, this is usually vfat.
    • mnt_flags: Vold ignores this field and it should be set to defaults
    • fs_mgr_flags: Vold ignores any lines in the unified fstab that do not include the voldmanaged= flag in this field. This flag must be followed by a label describing the card, and a partition number or the word auto. Here is an example: voldmanaged=sdcard:auto. Other possible flags are nonremovable, encryptable=sdcard, noemulatedsd, and encryptable=userdata.

References

  1. Questions about vold.conf and vold.fstab.
  2. Android code Device Configuration page.
5
  • Thank you for this helpful information. /fstab.qcom exists on my Android 5.1.1 device, but only root has permission to read it. – LarsH Nov 2 '15 at 16:23
  • You're welcome. Moreover in Android 5.x there is the file storage_list.xml ,then they remove something in the 6.0... Read here... – Hastur Nov 2 '15 at 16:38
  • I've seen the references to storage_list.xml, but could never find such a file in 5.1.1. The documentation you referenced doesn't say what directory it's in. Any idea where to find it? – LarsH Nov 2 '15 at 16:40
  • To be honest no :) It seems to be under device. Read comments here. – Hastur Nov 2 '15 at 16:54
  • I'm striking out on all counts. There's no top-level /device folder. There are some lower, e.g. /sys/block/mmcblk0/device, but no storage_list.xml there. There's a /vendor/overlay, but it doesn't contain storage_list.xml. No frameworks either. – LarsH Nov 2 '15 at 17:38

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.