3

Что у меня есть: я знаю место в файловой системе, где монтируется карта microSD, например /storage/sdcard1

Что мне нужно: чтобы узнать, какой папке устройства она соответствует, например /sys/class/mmc_host/mmc0 (которая является ссылкой на /sys/devices/msm_sdcc.1/mmc_host/mmc0) против /sys/class/mmc_host/mmc1 (это ссылка на /sys/devices/msm_sdcc.2/mmc_host/mmc1).

Мне нужно найти правильный каталог, чтобы я мог получить содержимое файлов в нем, таких как cid , serial , oemid и так далее.

Можно предположить, что /sys/class/mmc_host/mmc1 соответствует карте microSD, установленной в /storage/sdcard1 , но на некоторых устройствах Android это mmc0.

Поскольку мы находимся на Android, у нас есть некоторые ограничения относительно более типичного Linux:

  • файлы /etc/mtab или /etc/fstab существуют
  • нет команд hwinfo или hdparm
  • dmesg не запускается (klogctl: операция не разрешена)
  • df не выводит столбец "установлен на"
  • нет доступа к stat() или другим вызовам низкого уровня; по крайней мере, без некоторой разработки NDK, которая представляет собой глубокий бассейн для погружения, требующий архитектурно-специфических сборок

Вот вывод df относящийся к карте microSD:

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

(что сбивает с толку, потому что я думал, и mount указывает, что /storage/sdcard - это точка монтирования, а не файловая система).

И соответствующий вывод 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

Выше показано, что файловая система, смонтированная в /storage/sdcard1 является /dev/fuse . Но /dev/fuse монтируется в трех местах:

$ 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

и в любом случае я до сих пор не вижу способа выяснить, какой каталог /sys/class/ ... или /sys/devices/ ... соответствует /storage/sdcard1 .

Таким образом, один из способов ответить на первоначальный вопрос, вероятно, будет ответить на подвопрос: Как я могу найти запись /sys /class или /sys /devices для FUSE -монтированной файловой системы? Это должно как минимум ответить на вопрос для этого случая (но я не знаю, все ли устройства Android монтируют карты microSD одинаково).

Любые предложения приветствуются.

3 ответа3

4

Как объяснил Дэн, эта файловая система предоставляется FUSE, что означает, что она реализована в пользовательском пространстве, а указанная вами строка монтирования не говорит, какая файловая система в пользовательском пространстве используется. Таким образом, для всех мы знаем, что это может быть любая программа и может делать любые случайные вещи. Например, он может предоставлять блоки данных, комбинируя блоки с различных устройств и / или из сети, и / или любым другим способом, который мог прийти в голову программисту.

Конечно, на практике вы, вероятно, можете ожидать, основываясь на контекстных знаниях, что данные поступают с одного из этих устройств mmc. Но даже это может быть трудно понять, потому что он может получать свои данные от этого устройства mmc через устройство отображения (как здесь может показаться, что я бы догадался, что /storage /sdcard1 предоставляется через FUSE от /mnt /media_rw /sdcard1, который сам по себе происходит из /dev /block /vold /179:65, который определен в устройстве отображения устройств как одно из устройств mmc (хотя, конечно, это тоже может быть комбинация устройств, поскольку устройство-маппер может делать RAID-0/1).

Таким образом, теоретически вы можете попытаться выяснить (не уверен, каким образом), какой процесс связан (как FUSE-демон) с этой точкой монтирования, а затем посмотреть на этот процесс в /proc /, чтобы увидеть, какие файлы он открыл, и угадать из этих открытых файлов, куда он берет свои данные (т. е. узнает, что они получены из /mnt /media_rw /sdcard1), затем снова посмотрите на /proc /mounts и выясните, что они получены из /dev /block /vold / 179:65 затем каким-то образом определите конфигурацию этого логического тома (я не смог найти информацию в / sys или /proc, но она может быть где-то там), чтобы наконец найти устройство, которое вы ищете.

Я уверен, что теоретически вы не можете написать программу, которая может гарантировать, что найдет ваш ответ. На практике вы, вероятно, можете собрать что-то подходящее для ваших сценариев использования, учитывая достаточную мотивацию, время и уродливые хаки.

В зависимости от информации о ресурсах, к которым у вас есть доступ, более простым решением может быть сделать это более "целостным": не обращайте внимания на путь, по которому данные проходят от устройства до точки монтирования (и обратно), но вместо этого посмотрите на данные в этой точке монтирования, затем посмотрите на данные на различных устройствах и решите, на каком устройстве они основаны, как они соотносятся.

Например, запишите файл, который содержит 512 байтов случайных данных в этой файловой системе, а затем найдите эту точную последовательность из 512 байтов в блоках устройств-кандидатов. Если вы можете найти его там, можете поспорить, что это ваш ответ. Или, если вы не хотите писать: возьмите первые 512 байт какого-либо файла в этой файловой системе, а затем найдите его в блоках устройств. Если он найден только на одном из устройств, у вас есть ответ.

2

Каталог /sys (AKA, ядро Linux sysfs) применяется только к объектам ядра.

Упомянутое вами устройство /storage/sdcard1 не монтируется напрямую как драйвер ядра, оно монтируется в пользовательском пространстве, оборачивается с помощью FUSE.

Сопоставление точки монтирования FUSE с конкретным устройством /sys (если таковые имеются, файловые системы, смонтированные FUSE, могут даже не иметь базового устройства ядра) обычно не может быть определено из обычной информации о монтировании, за исключением, может быть, рассуждений, например, если это единственное устройство (этого конкретного типа) монтируется.

Может быть возможно получить информацию о сопоставлении от FUSE, но я понятия не имею, если / как.

1

Некоторые царапины слишком длинные, чтобы быть комментарием:

  1. Нет ничего необычного в том, что одно и то же устройство смонтировано в нескольких местах (возможно, с разными правами чтения / записи ...). mount | grep fuse | grep -v emulated в вашем примере должен помочь выбрать среди эмулируемой точки монтирования.

  2. В android 4.2.2 и более ранних версиях он на самом деле существует vold.fstab , скрипт справки, который выполняет эту работу вместо /etc/fstab (до того, как это был vold.conf [ 1 ]). Возможно, вы сможете разобрать этот скрипт и получить хорошую отправную точку. Синтаксис для Android 4.2.2 и более ранних версий: [ 2 ]:

    dev_mount <label> <mount_point> <partition> <sysfs_path> [flags]
    
    • label: ярлык для тома.
    • mount_point: путь к файловой системе, куда должен быть подключен том.
    • partition: номер раздела (на основе 1) или «auto» для первого используемого раздела.
    • sysfs_path: один или несколько путей sysfs к устройствам, которые могут предоставить эту точку монтирования. Разделенные пробелами, и каждый должен начинаться с / .
    • flags: Необязательный список флагов через запятую, не должен содержать / . Возможные значения включают nonremovable и encryptable .
  3. Для версий Android 4.3 и более поздних

    различные файлы fstab, используемые init, vold и recovery, были объединены в /fstab.<device> file .

    Таким образом, вы должны выделить имя вашего устройства в имени файла .

    Снова сообщается [ 2 ], что для внешних томов хранения, которые управляются vold , вы должны найти следующий формат:

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

    где

    • src: путь под устройством sysfs (обычно смонтированным в /sys) к устройству, которое может предоставить точку монтирования. Путь должен начинаться с / .
    • mount_point: путь к файловой системе, куда должен быть подключен том.
    • type: тип файловой системы на томе. Для внешних карт это обычно vfat .
    • mnt_flags: Vold игнорирует это поле, и оно должно быть установлено по умолчанию
    • fs_mgr_flags: Vold игнорирует все строки в объединенном fstab которые не включают флаг voldmanaged= в этом поле. Этот флаг должен сопровождаться меткой, описывающей карту, и номером раздела или словом auto. Вот пример: voldmanaged=sdcard:auto . Другие возможные флаги: nonremovable , encryptable=sdcard , noemulatedsd и encryptable=userdata .

Рекомендации

  1. Вопросы о vold.conf и vold.fstab.
  2. Код Android Страница конфигурации устройства.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .