11 votes

Comment monter en mode liaison un dossier à l'intérieur de /sdcard avec les autorisations correctes?

Je suis en train d'utiliser un Sony Xperia M4 Aqua. Comme on le sait bien, la mémoire interne est plutôt petite. Surtout, le répertoire Media de WhatsApp utilise beaucoup d'espace précieux, donc j'essaie de le déplacer vers la carte SD. J'utilise Android 6 et j'ai formaté la carte SD pour avoir une partition de stockage adoptée.

Normalement, le stockage adopté serait utilisé pour migrer tout /data dessus, comme discuté ici. Cependant, je suis intéressé à déplacer juste le répertoire unique WhatsApp/Media quelque part d'autre (peut-être dans la partition de stockage adoptée), et ensuite le monter en lien symbolique à son emplacement d'origine.

Pour ce faire, j'ai déplacé le répertoire WhatsApp/Media vers le stockage adopté. Ensuite, en suivant cette discussion, j'ai modifié le script /system/etc/init.qcom.post_boot.sh en ajoutant les commandes suivantes de montage (le téléphone n'a pas de support pour les scripts init.d)

mount -o bind /mnt/expand/4fdb2500-9aa7-44bc-a2c4-80aeae28e764/WhatsAppMedia /storage/emulated/0/WhatsApp/Media
mount -o bind /mnt/expand/4fdb2500-9aa7-44bc-a2c4-80aeae28e764/WhatsAppMedia /mnt/runtime/write/emulated/0/WhatsApp/Media
mount -o bind /mnt/expand/4fdb2500-9aa7-44bc-a2c4-80aeae28e764/WhatsAppMedia /mnt/runtime/read/emulated/0/WhatsApp/Media
mount -o bind /mnt/expand/4fdb2500-9aa7-44bc-a2c4-80aeae28e764/WhatsAppMedia /mnt/runtime/default/emulated/0/WhatsApp/Media
mount -o bind /mnt/expand/4fdb2500-9aa7-44bc-a2c4-80aeae28e764/WhatsAppMedia /data/media/0/WhatsApp/Media

Remarque : /mnt/expand/4fdb25.... pointe vers la partition de stockage adoptée.

Cela semble fonctionner uniquement en apparence : si j'ouvre un shell avec adb, je peux voir correctement que le répertoire WhatsApp/Media contient le répertoire monté. De plus, je ne vois aucune vue supplémentaire qui contient le répertoire WhatsApp, comme on peut le vérifier en faisant, dans un adb shell

find / -type d -name WhatsApp

Cependant, WhatsApp n'est pas capable d'accéder à la galerie Media. Par exemple, dans le chat je ne vois que des images floues (comme un aperçu), et en cliquant dessus je ne vois pas l'image complète. De plus, si quelqu'un m'envoie une image, tout ce que je peux voir est un aperçu flou avec l'icône de téléchargement. Cliquer sur l'icône de téléchargement ne produit rien.

Des permissions incorrectes sont probablement la source des problèmes. Par exemple, certaines permissions/propriétés de groupe semblent incorrectes sur certaines vues :

root@E2303:/ # ls -n /storage/emulated/0/WhatsApp
drwxrwx--x 0        1015              2019-09-04 14:37 Backups
drwxrwx--x 0        1015              2019-10-19 02:00 Databases
drwxrwx--x 0        1015              2019-09-04 20:24 Media
root@E2303:/ # ls -n /mnt/runtime/write/emulated/0/WhatsApp
drwxrwx--- 0        9997              2019-09-04 14:37 Backups
drwxrwx--- 0        9997              2019-10-19 02:00 Databases
drwxrwx--x 0        1015              2019-09-04 20:24 Media
root@E2303:/ # ls -n /mnt/runtime/read/emulated/0/WhatsApp
drwxr-x--- 0        9997              2019-09-04 14:37 Backups
drwxr-x--- 0        9997              2019-10-19 02:00 Databases
drwxrwx--x 0        1015              2019-09-04 20:24 Media
root@E2303:/ # ls -n /mnt/runtime/default/emulated/0/WhatsApp
drwxrwx--x 0        1015              2019-09-04 14:37 Backups
drwxrwx--x 0        1015              2019-10-19 02:00 Databases
drwxrwx--x 0        1015              2019-09-04 20:24 Media
root@E2303:/ # ls -n /data/media/0/WhatsApp/                                   
drwxrwxr-x 1023     1023              2019-09-04 14:37 Backups
drwxrwxr-x 1023     1023              2019-10-19 02:00 Databases
drwxrwx--x 0        1015              2019-09-04 20:24 Media

Les permissions et la propriété de groupe du répertoire Media devraient être les mêmes que les autres répertoires (non montés en lien symbolique) Backups et Databases. De manière étrange, un essai pour remonter les répertoires avec le gid correct

root@E2303:/ # mount -o remount, gid=9997 /mnt/runtime/write/emulated/0/WhatsApp/Media
root@E2303:/ # mount -o remount, gid=9997 /mnt/runtime/read/emulated/0/WhatsApp/Media
root@E2303:/ # mount -o remount, gid=1023 /data/media/0/WhatsApp/Media

ne produit aucun changement dans la propriété du groupe : ls -n comme ci-dessus donne des résultats identiques.

Même plus étrange, mais peut-être sans rapport, le fait d'omettre l'espace entre remount et gid=... donne

mount: Invalid argument

Comment monter en lien symbolique le dossier WhatsApp/Media depuis la carte SD externe avec les permissions correctes?

15voto

Irfan Latif Points 16863

J'ai utilisé deux approches différentes (en fait, plusieurs avec de petites différences) sur mes anciennes versions d'Android pour monter l'ensemble du système. /sdcard/WhatsApp à partir d'une carte SD externe. J'ai testé, cela fonctionne sur Android 9 aussi, mais les choses de stockage ont changé sur Android 10.

Avant d'entrer dans les détails pratiques, nous devons garder à l'esprit quelques points :

  • /sdcard n'est pas un réel mais système de fichiers émulé . Android utilise sdcardfs (ou FUSE ) pour émuler le stockage réel sur /sdcard . Voir Qu'est-ce que /storage/emulated/0/ ?

  • Les deux systèmes de fichiers ci-dessus ont un Correction du contexte SELinux : u:object_r:sdcardfs:s0 (ou u:object_r:fuse:s0 ).

  • Normalement /data/media est émulée sur /sdcard mais dans le cas du stockage adoptif, lorsque les données sont migrées, /mnt/expand/[UUID]/media est émulée. Voir Comment libérer le stockage interne en déplaçant les données ou en utilisant un lien symbolique / un montage lié avec le stockage adoptif ?

  • Fichiers et répertoires sur /sdcard ont propriété et permissions fixes qui dépendent du fait que l'application a android.permission.[READ|WRITE]_EXTERNAL_STORAGE permission accordée ou non. Les fichiers n'ont jamais l'autorisation d'être exécutés. Les répertoires de données des applications dans /sdcard/Android/data/ ont la propriété fixée à l'UID de l'application respective. Pour plus de détails, voir Qu'est-ce que l'UID "u#_everybody" ?

    Nous supposons ici que chaque application est autorisée à écrire sur /sdcard en fixant la propriété 0 / 9997 (utilisateur/groupe) et les permissions 0771 / 0660 (répertoires/fichiers).

  • Pour obtenir le comportement susmentionné, depuis Android 6, chaque application est exécutée dans un fichier de type espace de nom de montage isolé y /storage/emulated est monté sur un autre VIEW : /mnt/runtime/[default|read|write]/emulated avec propagation des montages privés/esclaves. Ainsi, le montage direct sur /storage/emulated n'apparaîtra pas dans les espaces de noms de montage des applications à moins que vous n'entriez explicitement dans l'espace de noms de montage de chaque application. Il en va de même si vous effectuez un montage à partir d'un espace de nom de montage isolé d'une application. Voir La partition est démontée automatiquement dans Android Oreo. .

    Nous allons monter depuis l'espace de nom Root mount vers /mnt/runtime/write/emulated qui est propagé à tous les espaces de noms de montage des applications.

  • read y default ont des autorisations différentes de celles des write ( 1 ) mais le montage sur les deux est généralement inutile. Permissions READ_EXTERNAL_STORAGE y WRITE_EXTERNAL_STORAGE appartiennent au même groupe de permission. Ainsi, accorder l'un à une application via l'interface graphique accorde également l'autre, et toutes les applications avec l'autorisation de stockage verront seulement write vue. default est seulement pour permettre aux applications (qui n'ont pas la permission de lire/écrire le stockage) de traverser /sdcard/Android/data les répertoires. Ainsi, le montage sur default permettra à de telles applications de passer simplement par des sous-répertoires sur /sdcard/ aucun fichier ne sera visible.

    Aussi, au moins avec sdcardfs l'émulation, read y write sont montés en liaison ( 2 ) de default et le montage sur l'un d'eux se fait également sur les deux autres. Il n'est donc pas possible de monter les trois avec des permissions différentes.

  • /sdcard ne prend pas en charge les attributs étendus ( xattr ) et le temps d'accès ( atime ). Les autres options de montage comprennent nosuid , nodev y noexec . Voir monter la page de manuel pour les détails.


Tout d'abord, assurez-vous que vous êtes dans l'espace de nom Root mount comme expliqué dans le lien donné ci-dessus. Ou utilisez nsenter pour obtenir un shell Root dans l'espace de nom global :

~# [ $(readlink /proc/1/ns/mnt) = $(readlink /proc/self/ns/mnt) ] || busybox nsenter -t 1 -m /system/bin/sh

1. MONTEZ LA CARTE SD MANUELLEMENT :

Le moyen le plus simple est de formater la carte SD externe en tant que stockage portable avec exFAT o FAT32 . Comme ces systèmes de fichiers ne sont pas natifs de Linux, leurs implémentations de pilotes dans le noyau prennent en charge les éléments suivants uid , gid , fmask y dmask options de montage. Vous pouvez utiliser exfat o sdfat les conducteurs avec exFAT y vfat con FAT32 . Former a également une implémentation en espace utilisateur mount.exfat-fuse qui ne nécessite que la prise en charge de FUSE par le noyau. Vérifiez avec grep fuse /proc/filesystems .

Disons que /dev/block/sda1 est votre exFAT partition :

~# mount -t exfat -o nosuid,nodev,noexec,noatime,context=u:object_r:sdcardfs:s0,uid=0,gid=9997,fmask=0117,dmask=0006 /dev/block/sda1 /mnt/runtime/write/emulated/0/WhatsApp
~# mv /data/media/0/WhatsApp/* /sdcard/WhatsApp/

* Remplacer u:object_r:sdcardfs:s0 con u:object_r:fuse:s0 ou toute autre étiquette que votre /sdcard a.

Vous pouvez également créer plusieurs partitions sur la carte SD. Ou après le montage avec les options de montage requises, vous pouvez également lier le montage d'un répertoire au lieu de la partition entière. Disons que vous montez d'abord la carte SD à /mnt/my_sdcard puis lier le montage du répertoire WhatsApp :

~# mount -o bind /mnt/my_sdcard/WhatsApp /mnt/runtime/write/emulated/0/WhatsApp

Baisse de régime avec cette approche est que vold monte la carte SD externe au démarrage, vous devez donc la démonter d'abord.
Deuxièmement, les données de la carte SD ne sont pas cryptées, bien qu'il existe plusieurs façons de les crypter manuellement. Voir Décryptage de la carte microSD sur un autre appareil Android ou un ordinateur de bureau .

2. STOCKAGE ADOPTABLE :

Une façon simple de contrer les inconvénients mentionnés ci-dessus est d'utiliser le FDE intégré au noyau en formatant la carte SD en tant que Stockage Adoptable, mais seulement si vous ne voulez pas migrer alle /data/media/ à la carte SD externe. Une fois formatée, la carte SD externe sera montée à l'emplacement suivant /mnt/expand/[UUID] (système de fichiers UUID est un nombre de 16 octets). Mais nous ne pouvons pas simplement lier le montage d'un répertoire à partir de là pour /sdcard parce que le système de fichiers sur le Stockage Adoptable est ext4 qui suit le modèle de permissions UNIX, mais les applications ne peuvent pas les gérer comme expliqué ci-dessus. Même si vous parvenez à le faire fonctionner d'une manière ou d'une autre (en utilisant des fichiers chown , chmod etc.), chaque application créera des fichiers avec son propre UID qui ne sera pas accessible aux autres applications. Par exemple, Gallery ne pourra pas voir les photos téléchargées par WhatsApp.

Pour que cette méthode fonctionne, votre noyau doit supporter sdcardfs (vérifier auprès de grep sdcardfs /proc/filesystems ). Créez un répertoire sur la carte SD adoptée et émulez-la vers /sdcard/WhatsApp :

~# mkdir /mnt/expand/[UUID]/media/0/WhatsApp
~# mv /sdcard/WhatsApp/* /mnt/expand/[UUID]/media/0/WhatsApp/
~# restorecon -rv /mnt/expand/[UUID]/media/
~# mount -t sdcardfs -o nosuid,nodev,noexec,noatime,mask=7,gid=9997 /mnt/expand/[UUID]/media/0/WhatsApp /mnt/runtime/write/emulated/0/Whatsapp

Veuillez noter que nous devons nécessairement utiliser le chemin /mnt/expand/[UUID]/media/ parce qu'il est étiqueté comme media_rw_data_file ( 3 ) (comme /data/media ( 4 ) ) qui est autorisé par la politique SELinux à être accédé par les applications ( 5 ) . Si vous utilisez un chemin différent, vous devez modifier la politique SELinux. Contrairement aux autres systèmes de fichiers sdcardfs lui-même ne modifie pas le contexte SELinux lors de l'accès au système de fichiers sous-jacent.

3. STOCKAGE PORTABLE / ADOPTABLE :

Cette méthode est la plus flexible, elle fonctionne si vous voulez utiliser :

  • Stockage portable mais vous ne voulez pas monter une partition entière, mais un répertoire.
  • Stockage adopté mais votre noyau ne dispose pas de sdcardfs soutien.
  • Stockage adoptif mais ne veut pas l'utiliser /mnt/expand/[UUID]/media/ chemin nécessairement.

Utilisez un outil tiers nommé bindfs (qui utilise FUSE) pour simuler le comportement du système de fichiers émulé. En fait, l'outil intégré d'Android /system/bin/sdcard fait exactement cela sur pré sdcardfs libère mais il a des chemins fixes et d'autres choses inutiles, donc son code source doit être modifié pour obtenir ce que nous voulons. Vous pouvez construire bindfs vous-même ou essayez este este un.

~# DIR=/mnt/media_rw/[UUID]    # for Portable Storage
~# DIR=/mnt/expand/[UUID]      # for Adoptable Storage
~# mkdir $DIR/WhatsApp
~# mv /sdcard/WhatsApp/* $DIR/WhatsApp/
~# bindfs -o nosuid,nodev,noexec,noatime,context=u:object_r:sdcardfs:s0 -u 0 -g 9997 -p a-rwx,ug+rw,ugo+X --create-with-perms=a-rwx,ug+rw,ugo+X --xattr-none --chown-ignore --chgrp-ignore --chmod-ignore $DIR/WhatsApp /mnt/runtime/write/emulated/0/WhatsApp

Notes secondaires :

  • sdcardfs fonctionne aussi partiellement avec cette méthode, sauf qu'il ne supporte pas SELinux context= (jusqu'à présent). Cela dépend donc de l'étiquette SELinux du répertoire de sauvegarde sur la carte SD.
  • D'autres outils comme rclone , encfs , sshfs etc. qui utilisent FUSE peuvent également être montés à l'intérieur de l'appareil. /sdcard de la même manière. Relié : Comment monter rclone sur Android ?
  • -u y -g les options exigent /etc/passwd y /etc/group pour exister sur bindfs < v 1.14.2 .

Vous pouvez donc opter pour la méthode qui vous convient. En général, les pilotes intégrés au noyau sont plus performants que les solutions en espace utilisateur, et les méthodes natives du noyau Linux sont plus robustes et stables. FUSE (sur FUSE) peut parfois entraîner une baisse des performances, par exemple si la carte SD elle-même prend en charge les transferts de données à grande vitesse.

Vous pouvez placer les commandes de montage requises dans un fichier init.d ou définir et init service. Voir Comment lancer un exécutable au démarrage et le maintenir en fonctionnement ?

Note :

  • Les applications qui ne sont pas scannées /sdcard mais s'en remettent au MediaProvider d'Android pour toute modification peuvent avoir besoin d'une analyse forcée des médias pour que les nouveaux fichiers sur le système de fichiers monté apparaissent immédiatement.
  • Si vous utilisez plusieurs utilisateurs ou profils, vous devez monter un nouveau système de fichiers pour chaque utilisateur. User_ID . Pour le propriétaire de l'appareil, c'est 0 .

RELATION :

0 votes

Salut Irfan . En train de parcourir ta réponse méticuleuse... (et merci pour la même) ... Ma situation est une carte multi partitionnée ext4 où même la principale partition est ext4. Mon ROM est un ROM Stock qui contrairement à lineage ne prendra pas en charge montage ext4 par défaut . Je peux monter mes partitions avec une approche similaire à init.d et elles sont visibles par les applications rooted TC mais elles ne sont pas en lecture-écriture. J'aimerais lecture-écriture de partition pour certains apps. Pas seulement des répertoires privés. J'ai essayé vold-posix il n'aime pas mon OS et mon architecture. Fichier nest pas exécutable : fichier ELF 64-bit J'obtiens cette erreur pour bindfs. Des alternatives ?

0 votes

getprop ro.product.cpu.abilist donne armeabi-v7a,armeabi. Toute autre approche pour que je puisse obtenir un partition RW large mount pour des applications rootées et non rootées (l'application non rootée est le gestionnaire de fichiers ROM d'origine qui est invoqué par défaut par toutes les applications pour parcourir les répertoires). Comme je le comprends, Android 'déconseille cela mais j'apprécierais', si vous pouviez donner votre avis!

0 votes

Si cette approche partition large n'est pas réalisable, alors au moment du montage je veux attribuer des ID d'application spécifiques en écriture. Comment puis-je faire cela ?

androidalle.com

AndroidAlle est une communauté de androiders où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X