J'utilise des montages par liaison sans désactiver les espaces de noms de montage sur Android depuis un certain temps - Marshmallow (Android 6) et Nougat (Android 7.1, LineageOS 14.1).
Le montage par liaison n'est pas visible pour les autres applications car /storage/sdcard/
lui-même est également une couche d'indirection. Par exemple, lorsque vous exécutez mount
, vous pouvez voir que la carte SD "interne" émulée ne se trouve pas à l'emplacement /storage/emulated
, mais à /data/media
:
/data/media on /mnt/runtime/default/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,uid=1023,gid=1023,multiuser)
/data/media on /storage/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,uid=1023,gid=1023,multiuser)
/data/media on /mnt/runtime/read/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,uid=1023,gid=1023,multiuser)
/data/media on /mnt/runtime/write/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,uid=1023,gid=1023,multiuser)
Ces trois points de montage dans /mnt/runtime
sont documentés sur Stockage, Permissions d'exécution:
Android 6.0 introduit un nouveau modèle de permissions d'exécution où les applications demandent des capacités lorsque nécessaire à l'exécution. Parce que le nouveau modèle inclut les permissions READ/WRITE_EXTERNAL_STORAGE, la plateforme doit accorder dynamiquement l'accès au stockage sans arrêter ou redémarrer les applications déjà en cours d'exécution. Elle le fait en maintenant trois vues distinctes de tous les périphériques de stockage montés :
/mnt/runtime/default
est affiché aux applications ne disposant d'aucune permission de stockage spéciale, et à l'espace de noms racine où se trouvent adbd et d'autres composants système.
/mnt/runtime/read
est affiché aux applications avec READ_EXTERNAL_STORAGE
/mnt/runtime/write
est affiché aux applications avec WRITE_EXTERNAL_STORAGE
Donc, pour rendre un répertoire visible pour toutes les autres applications, vous devez créer les montages à ces endroits :
mkdir /mnt/runtime/{default,read,write}/dir2
mount -o bind /mnt/runtime/default/sdcard/dir1 /mnt/runtime/default/sdcard/dir2
mount -o bind /mnt/runtime/read/sdcard/dir1 /mnt/runtime/read/sdcard/dir2
mount -o bind /mnt/runtime/write/sdcard/dir1 /mnt/runtime/write/sdcard/dir2
Pour démonter :
umount /mnt/runtime/default/dir2
umount /mnt/runtime/read/dir2
umount /mnt/runtime/write/dir2
rmdir /mnt/runtime/{default,read,write}/dir2
Dans votre question, la source et la cible sont dans le même système de fichiers, donc ce qui précède fonctionnera probablement tel quel et montrera dir2 aux autres applications.
Vous pouvez vérifier que les montages par liaison sont "visibles" comme prévu en recherchant l'identifiant du processus de l'application souhaitée, puis en vérifiant la liste des montages du point de vue de cette application :
# cat /proc/(ID du processus ici)/mountinfo
Conseils de débogage
Si vous ne pouvez pas accéder aux contenus du montage par liaison (c'est-à-dire "Permission refusée" ou quelque chose de similaire), alors vous devriez vérifier si le fichier d'origine a les bonnes permissions/propriétés UNIX ET une étiquette SELinux qui correspond au contexte. Ce dernier peut être débogué en recherchant les erreurs "avc: denied" dans logcat-color (ou simplement adb logcat
). Dans certains cas, cela peut être corrigé en utilisant restorecon
ou chcon
.
Par exemple, j'obtenais l'erreur suivante lorsque j'essayais d'accéder à /sdcard/DCIM
(qui est un montage par liaison vers un répertoire sur la carte SD externe).
avc: denied { write } for comm=... name="Camera" dev="dm-1" ino=3547138 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:mnt_media_rw_file:s0 tclass=dir permissive=0
Et j'ai corrigé cela en observant que l'étiquette SELinux est incorrecte (le tcontext
dans le message d'erreur me l'avait déjà indiqué) :
# ls -Z /mnt/media_rw/myextcard/my_DCIM_directory
drwxrwx--x 4 media_rw media_rw u:object_r:mnt_media_rw_file:s0 4096 2018-06-08 12:34 .
et changé cela (de manière récursive) en une étiquette autorisée par la politique par défaut sur LineageOS :
# chcon -R u:object_r:media_rw_data_file:s0:c512,c768 /mnt/media_rw/myextcard/my_DCIM_directory
Cela a fonctionné pour moi, car /sepolicy
a une règle qui indique que priv_app
peut accéder aux fichiers media_rw_data_file
. Ceux qui ont une situation/ROM différente peuvent utiliser setools-android pour analyser leur fichier /sepolicy
et voir leurs options.
0 votes
Connexe: android.stackexchange.com/questions/217741/…