Como posso descobrir a entrada / sys / class ou / sys / devices para um sistema de arquivos montado?

3

O que eu tenho: Eu sei o lugar no sistema de arquivos onde um cartão microSD é montado, por exemplo /storage/sdcard1

O que preciso: para descobrir a qual pasta de dispositivo corresponde, por exemplo /sys/class/mmc_host/mmc0 (que é um link para /sys/devices/msm_sdcc.1/mmc_host/mmc0 ) vs. /sys/class/mmc_host/mmc1 (que é um link para /sys/devices/msm_sdcc.2/mmc_host/mmc1 ).

Eu preciso encontrar o diretório correto para que eu possa pegar o conteúdo dos arquivos, como cid , serial , oemid e assim por diante.

Eu poderia supor que /sys/class/mmc_host/mmc1 corresponde ao cartão microSD montado em /storage/sdcard1 , mas em alguns dispositivos Android é mmc0 .

Como estamos no Android, temos algumas limitações em relação ao Linux mais típico:

  • não existem arquivos /etc/mtab ou /etc/fstab
  • não há hwinfo ou hdparm comandos
  • dmesg não é executado (klogctl: operação não permitida)
  • df não produz a coluna "montado em"
  • sem acesso a stat() ou outras chamadas de baixo nível; pelo menos não sem algum desenvolvimento NDK, que é uma piscina profunda para mergulhar, exigindo construções específicas da arquitetura

Aqui está a saída de df relacionada ao cartão microSD:

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

(o que é confuso porque pensei, e mount indica que /storage/sdcard é o ponto de montagem em vez do sistema de arquivos ).

E a saída relevante de 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

O exemplo acima mostra que o sistema de arquivos montado em /storage/sdcard1 é /dev/fuse . Mas /dev/fuse é montado em três lugares:

$ 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

e, de qualquer forma, ainda não vejo como descobrir qual diretório /sys/class/ ... ou /sys/devices/ ... corresponde a /storage/sdcard1 .

Assim, uma maneira de responder a pergunta inicial provavelmente seria responder à sub-questão, Como posso descobrir a entrada / sys / class ou / sys / devices para um sistema de arquivos montado por FUSE ? Isso deve responder a pergunta para este caso, pelo menos (mas eu não sei se todos os dispositivos Android montam cartões microSD da mesma forma).

Todas as sugestões são bem-vindas.

    
por LarsH 23.10.2015 / 22:22

3 respostas

4

Como explicado por Dan, este sistema de arquivos é fornecido pelo FUSE, o que significa que ele é implementado no espaço do usuário e a linha de montagem que você cita não diz qual sistema de arquivos do espaço do usuário está em uso. Então, para todos nós sabemos que poderia ser qualquer programa e poderia fazer qualquer coisa aleatória. Por exemplo. pode fornecer os blocos de dados combinando blocos de vários dispositivos e / ou da rede e / ou qualquer outra forma que possa ter cruzado a mente do programador.

É claro que, na prática, você provavelmente pode esperar, com base no conhecimento contextual, que os dados vêm de um desses dispositivos mmc. Mas mesmo isso pode ser difícil de descobrir porque ele poderia obter seus dados daquele dispositivo mmc através do device-mapper (como parece ser o caso aqui onde eu ficaria tentado a supor que / storage / sdcard1 é fornecido via FUSE de / mnt / media_rw / sdcard1 que vem de / dev / block / vold / 179: 65 que é definido no device-mapper para vir de um dos dispositivos mmc (embora também possa ser uma combinação de dispositivos, uma vez que device-mapper pode fazer RAID-0/1).

Então, em teoria, você poderia tentar descobrir (não sei como) qual processo está associado (como um daemon FUSE) a este ponto de montagem, então veja esse processo em / proc / para ver quais arquivos ele possui abrir e adivinhar a partir desses arquivos abertos onde ele pega seus dados (ou seja, descobrir que ele vem de / mnt / media_rw / sdcard1), então olhe para / proc / mounts novamente para descobrir que isso vem de / dev / block / vold / 179: 65, então, de alguma forma, descobrir a configuração deste volume lógico (não consegui encontrar a informação em / sys ou / proc, mas pode estar lá em algum lugar) para finalmente encontrar o dispositivo que você está procurando.

Tenho certeza de que, em teoria, você não pode escrever um programa que garanta a sua resposta. Na prática, você provavelmente pode remendar algo que funcione para seus casos de uso, com motivação, tempo e hacks feios suficientes.

Dependendo dos detalhes dos recursos aos quais você tem acesso, uma solução mais fácil pode ser fazer mais "holisticamente": não prestar atenção ao caminho que os dados levam do dispositivo para o ponto de montagem (e back), mas, em vez disso, observe os dados nesse ponto de montagem, observe os dados nos vários dispositivos e decida em qual dispositivo eles se baseiam em como eles se correlacionam.

Por exemplo escreva um arquivo que contenha 512 bytes de dados aleatórios nesse sistema de arquivos e, em seguida, procure a sequência exata de 512 bytes nos blocos dos dispositivos candidatos. Se você puder encontrá-lo lá, você pode apostar que esta é sua resposta. Ou se você não quer escrever: pegue os primeiros 512 bytes de algum arquivo no sistema de arquivos, então procure nos blocos dos dispositivos. Se for encontrado apenas em um dos dispositivos, você terá sua resposta.

    
por 28.10.2015 / 14:52
2

O diretório /sys (AKA o sysfs do kernel Linux ) só se aplica aos objetos do kernel .

O dispositivo /storage/sdcard1 que você mencionou é não montado diretamente como um driver de kernel, ele é montado no espaço do usuário, encapsulado usando FUSE .

O mapeamento de um ponto de montagem do FUSE para um determinado dispositivo /sys (se algum, sistemas de arquivos montados pelo FUSE podem nem ter um dispositivo de kernel subjacente) geralmente não pode ser determinado a partir de informações de montagem regulares, exceto talvez por raciocínio, por exemplo se é o único dispositivo (desse tipo específico) a ser montado.

pode ser possível obter as informações de mapeamento do FUSE, mas não tenho idéia se / como.

    
por 26.10.2015 / 05:44
1

Alguns riscos são muito longos para serem um comentário:

  1. Não é incomum ter o mesmo dispositivo montado em mais de um lugar (talvez com direitos de leitura / gravação diferentes ...). Um mount | grep fuse | grep -v emulated no seu exemplo deve ajudar a selecionar entre o ponto de montagem emulado.

  2. No Android 4.2.2 e versões anteriores, existe vold.fstab , um script de ajuda que faz o trabalho em vez de /etc/fstab (antes era vold.conf [ 1 ]). Provavelmente você pode analisar esse script e obter um bom ponto de partida. A sintaxe do Android 4.2.2 e versões anteriores é [ 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. Para Android, versões 4.3 e posteriores

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

    Então, você deve ter o nome do seu dispositivo destacado no nome do arquivo .

    Novamente, é relatado [ 2 ] que, para os volumes de armazenamento externos gerenciados por vold , você deve encontrar o seguinte formato:

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

    onde

    • 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.

Referências

  1. Perguntas sobre vold.conf e vold.fstab .
  2. Página Configuração do dispositivo do código do Android
por 02.11.2015 / 09:39