Outils pour utilisateurs

Outils du site


phone:thumbnails-casse-tete

Différences

Ci-dessous, les différences entre deux révisions de la page.


phone:thumbnails-casse-tete [2020/08/28 19:31] (Version actuelle) – créée - modification externe 127.0.0.1
Ligne 1: Ligne 1:
 +====== Récupérer l'espace consommé par .thumbnails ======
 +<note important>Cette fiche a un statut particulier car elle ne propose aucune solution. C'est plutôt une fiche d'enquête.</note>
 +===== Le problème tel qu'il est énoncé =====
 +Un androphone signale qu'il manque de mémoire de stockage (sdcard). L'analyse de l'occupation de la mémoire fait apparaître qu'un fichier appelé ".thumbnails" occupe plusieurs Go((Dans le cas étudié, il occupe 8,9 Go sur une mémoire de stockage totale de 11 Go !)). De nombreuses utilisatrices rapportent ce problème.
 +
 +Le nom du fichier laisse entendre qu'il est dédié au stockage de vignettes pour des médias. Le cas le plus simple est celui de la vignette d'une image qui sera affichée dans plusieurs applications, particulièrement dans la galerie d'image. Or la taille de .thumbnails semble totalement décorrélée de la taille des médias réellement stockés sur l'androphone. La taille de .thumbnails peut même dépasser la taille des médias (en plein format) enregistrés dans la mémoire interne et la carte SD externe !
 +==== Localisation ====
 +Selon les version d'Android et les applications utilisées, le nom et la localisation de ce conteneur encombrant peut varier. Dans le cas étudié, le fichier fautif est situé dans le répertoire "/sdcard/DCIM/.thumbnails/". Le fichier lui-même s'appelle "[[https://fileinfo.com/extension/thumbdata4-1967290299|.thumbdata4-1967290299]]".
 +===== Récupérer l'espace indûment consommé =====
 +Comme indiqué dans l'énoncé du problème, l'objectif poursuivi est de récupérer de l'espace de stockage.
 +==== Les solutions qui n'en sont pas ====
 +Internet regorge de propositions pour résoudre ce problème. Toutes passent par la suppression du fichier fautif. Mais cette opération semble vaine car le fichier est recréé par l'application. Certaines variantes proposent des astuces pour bloquer cette recréation. Mais aucune de ces "solutions" ne permet de récupérer l'espace considérable consommé par le fichier fautif.
 +==== Hypothèses explicatives ====
 +Plusieurs explications peuvent être apportées à la non récupération de l'espace de stockage utilisé par le fichier fautif :
 +  - en vrai, le fichier n'est pas effacé, comme cela peut se produire sur un système complexe tel Linux
 +  - il n'est pas effacé proprement et l'espace qu'il occupait est dans un état bizarre qui empêche qu'il soit allouer à de nouveaux fichiers
 +  - la taille annoncée par le fichier est trompeuse si bien qu'en effaçant ce dernier on ne récupère pas l'espace qu'on lui croyait alloué.
 +===== Analyse des hypothèses =====
 +==== Une taille de fichier trompeuse ====
 +Commençons par la dernière hypothèse. Elle peut sembler la plus loufoque mais il n'en est rien. Certains types de fichiers peuvent avoir une taille déclarée bien supérieure à l'espace de stockage qu'ils consomment réellement. Ce type de fichier n'existe pas dans tous les systèmes de fichiers mais on le trouve dans les systèmes de fichiers courants sur Linux et donc Android (ext2, ext2, ext4…). On parle de fichiers "[[https://en.wikipedia.org/wiki/Sparse_file|sparse]]".
 +
 +L'apparition d'un tel fichier n'est pas un signe de compromission de votre androphone. L'utilisation d'un [[https://android.stackexchange.com/questions/66221/android-huge-thumbdata4-file-in-dcim-folder/71674#71674|fichier sparse unique pour y stocker des centaines de vignettes]] est l'un des cas où une telle implémentation peut se justifier((Comparaison n'est pas raison, mais c'est un peu comme l'utilisation des sprites conjointement à CSS sur certaines applications Web.)).
 +<note tip>Dans les cas extrêmes, une application telle que [[https://play.google.com/store/apps/details?id=com.jzap.memorymap&hl=fr|Memory Mapp]] donne un indice sérieux d'écart entre les tailles déclarée et allouée. Durant "l'analyse du disque", {{:phone:screenshot_memory_map.png?linkonly|le pourcentage de progression dépasse 100%}}((En effet, cette application s'appuie sur la taille réelle du "disque" et sur la taille déclarée des fichiers. Supposons que le disque fasse 10 Go, que les fichiers //non sparse// occupent 6 Go et qu'un fichier //sparse// soit déclaré à 8 Go, //Memory Map// affichera une analyse à 140% du disque (8+6)/10).)).</note>
 +=== Préparatifs ===
 +Le cas traité est celui d'un téléphone rooté. Le principe est d'ouvrir un shell sur l'androphone en cours d'utilisation sous Android et d'utiliser les commandes classiques pour analyser le contenu des systèmes de fichiers présents. Des applications permettent d'ouvrir un terminal sur l'androphone mais il est beaucoup plus confortable de connecter l'androphone à un ordi. C'est la voie qui sera suivie dans ce qui suit.
 +<code>
 +linux:~$ adb shell
 +kiwi:/ $ su
 +:/ # 
 +130|:/ # whoami
 +root
 +:/ # uname -r
 +3.10.108-lineageos-g6e87014
 +:/ # 
 +</code>
 +Après la connexion, on fait en sorte de devenir "root" et l'on constate que l'on est bien sur système Android (ici LineageOS). Pour une vue d'ensemble de l'espace disponible, on utilise la commande //df// (disk free) :
 +<code>
 +:/ # df
 +Filesystem                    1K-blocks     Used Available Use% Mounted on
 +tmpfs                         921M  636K  920M   1% /dev
 +tmpfs                         921M      921M   0% /mnt
 +/dev/block/mmcblk0p24         2.4G  1.5G  894M  65% /system
 +/dev/block/mmcblk0p17          63M  3.7M   59M   6% /log
 +/dev/block/mmcblk0p23         496M  477M   19M  97% /cust
 +/dev/block/mmcblk0p22         248M  196K  248M   1% /cache
 +/dev/block/mmcblk0p18          59M  344K   59M   1% /persist
 +/dev/block/mmcblk0p14         200M   53M  146M  27% /firmware
 +/dev/block/mmcblk0p26          7.5G  3.0G  72% /data
 +/data/media                    7.5G  3.0G  72% /mnt/runtime/default/emulated
 +/dev/block/vold/public:179,65  30G   19G   11G  64% /mnt/media_rw/4B7E-1AC3
 +/mnt/media_rw/4B7E-1AC3        30G   19G   11G  64% /mnt/runtime/default/4B7E-1AC3
 +</code>
 +En se laissant guider par les noms et les tailles, on identifie rapidement la carte SD interne "/data/media" (émulée) et la carte SD externe "/mnt/media_rw/4B7E-1AC3". Sans entrer dans les détails, il est normal que le même espace de stockage apparaisse deux fois, avec des noms de système de fichier différent, montés en des points différents. Les noms de référence sont ceux qui commencent par "/dev…" ; considérez les autres comme des alias. Soit :
 +  * espace de stockage interne (carte SD émulée) : /dev/block/mmcblk0p26
 +  * espace de stockage externe (carte SD physique) : /dev/block/vold/public:179,65
 +On vérifie que le système de fichiers utilisé par le stockage interne est bien du type //ext4//((Ça semble un peu magique car il faut avoir la prescience du type de système de fichiers. En effet, la version de //df// disponible sur cette version de LOS (toybox 0.7.6-android) ne reconnaît pas l'option "-T" qui permettrait d'afficher le type de tous les systèmes de fichiers affichés. Heureusement, on peut obtenir cette information avec la commande //mount// sans aucun paramètre (âmes sensibles à l'overdose de code s'abstenir).)) :
 +<code>
 +:/ # df -ht ext4                                                               
 +Filesystem            Size  Used Avail Use% Mounted on
 +
 +/dev/block/mmcblk0p26  11G  7.5G  3.0G  72% /data
 +</code>
 +Ici, la carte SD externe est du type //vfat// :
 +<code>
 +:/ # df -ht vfat                                                               
 +Filesystem                    Size  Used Avail Use% Mounted on
 +
 +/dev/block/vold/public:179,65  30G   19G   11G  64% /mnt/media_rw/4B7E-1AC3
 +</code>
 +
 +Avant de foncer tête baissée pour éradiquer un fichier fautif, il n'est pas inutile d'avoir une vue d'ensemble de la consommation de l'espace de stockage interne((On combine //du// qui calcule l'utilisation effective de mémoire dique avec //sort// qui trie la liste des fichiers-répertoires et //head// qui ne retient que les première lignes…)) :
 +<code>
 +:/ # du -a -d1 /data | sort -n -r | head -n 20                                 
 +7922948 /data
 +3413868 /data/app
 +2133432 /data/data
 +1730308 /data/media
 +462580  /data/user_de
 +147700  /data/dalvik-cache
 +18744   /data/system
 +9660    /data/misc
 +2452    /data/system_ce
 +2328    /data/tombstones
 +880     /data/backup
 +380     /data/system_de
 +164     /data/misc_ce
 +72      /data/resource-cache
 +60      /data/vendor
 +60      /data/time
 +28      /data/mediadrm
 +28      /data/cache
 +20      /data/drm
 +20      /data/anr
 +</code>
 +La carte SD émulée sur la mémoire interne de l'androphone se trouve à l'intérieur du répertoire ///data/media//. Dans l'exemple, on constate qu'elle n'est qu'au troisième rang et __consomme__ 1,65 Go.
 +
 +Dans la suite, afin de simplifier l'affichage, on utilise le raccourci mis en place par Android qui associe le répertoire ///sdcard// à un sous-répertoire de ///data/media// (/data/media/0).
 +
 +On affine la recherche en se focalisant sur ce répertoire :
 +<code>
 +:/ # cd sdcard
 +:/sdcard # du -a -d1 | sort -n -r | head -n 10
 +1730288 .
 +637324  ./Android
 +372916  ./Music
 +368800  ./DCIM
 +243156  ./DictionariesNGHS
 +26684   ./.estrongs
 +22292   ./Download
 +12280   ./osmdroid
 +10224   ./HWThemes
 +9368    ./data
 +</code>
 +
 +À ce stade, on dispose d'une photographie réaliste de l'utilisation de l'espace de stockage mis à notre disposition sous forme de carte SD émulée en mémoire interne.
 +=== Validation de l'hypothèse ===
 +La différence entre la taille déclarée et taille allouée est vérifiable à travers des commandes standard. Typiquement, la commande "ls"((//List//.)) indiquera la taille déclarée tandis que la commande "du"((//Disk Usage//.)) indiquera l'espace de stockage utilisé.
 +
 +Poussons l'exercice jusqu'au bout et assurons nous que le répertoire //.thumbails// et le fichier //.thumbdata4--1967290299// qui nous préoccupaient sont rentrés dans le rang.
 +<code>
 +kiwi:/ $ cd sdcard/DCIM/.thumbnails/
 +kiwi:/sdcard/DCIM/.thumbnails $ ls -lh .thumbdata4--1967290299
 +-rw-rw---- 1 root sdcard_rw 8.9G 2020-08-02 13:35 .thumbdata4--1967290299
 +kiwi:/sdcard/DCIM/.thumbnails $ du -h .thumbdata4--1967290299
 +56K     .thumbdata4--1967290299
 +/dev/block/mmcblk0p26    11G  7.6G  2.7G  74% /data
 +</code>
 +Dans le cas étudié, la démonstration est frappante :
 +  * la taille déclarée du fichier est de 8.9 Go
 +  * alors que l'espace disque réellement occupé par ce fichier n'est que de 56 Ko
 +  * et de toutes manières, l'espace occupé par tous les fichiers et répertoire du système de fichier auquel il appartient n'est que 7.6 Go
 +<note tip>Autrement dit, la suppression de ce fichier permettrait de gagner 56K. Pas un octet de plus ! Dans ces conditions, si votre androphone manque de mémoire de stockage interne disponible, il faut trouver d'autres moyens d'en libérer.</note>
 +
 +=== Cas inverse ===
 +Ne soyez pas surprise si vous observez le cas inverse à celui qui nous préoccupe ici. Oui, il est possible que la taille déclarée d'un fichier soit inférieure à la taille utilisée pour le conserver. Cela est particulièrement visible si on crée un fichier texte de 1 caractère. La commande ls indiquera que sa taille est de 1 octet alors qu'il occupera au minimum la taille d'un bloc d'allocation sur disque (par exemple, 4.0 Ko).
 +<code>
 +$ echo > test
 +$ ls -lh test                                                 
 +rw-rw---- 1 root sdcard_rw 1 2018-07-01 15:47 test
 +$ du -h test
 +4.0K    test
 +</code>
 +
 +==== Le fichier survit à une tentative d'effacement ====
 +La première hypothèse est que la demande de suppression de fichier serait bien enregistrée mais qu'elle serait mise en attente ou simplement ignorée, de manière non visible. Cette incertitude vient notamment du fait que le système (ici Android) est en cours d'exécution et qu'en conséquences, certains programmes (app ou système) peuvent être en train de lire ou d'écrire dans le fichier.
 +=== S'assurer de la suppression ===
 +Sur internet, on trouvera plusieurs propositions d'apps permettant de supprimer un fichier de manière fiable. La manière la plus fiable est encore de ne pas le faire depuis une application ni même depuis Android.
 +
 +La solution consiste à démarrer l'androphone sur le recovery((Un système dédié à la maintenance, alternatif à l'Android qui motorise votre androphone.)) et à utiliser le navigateur de fichier du //recovery// pour supprimer le fichier fautif. Dans ce cas, la mémoire interne de stockage est traitée comme un vulgaire "disque externe", sans lien avec le système (recovery) en cours d'exécution.
 +
 +Sur l'androphone utilisé au cours de cette analyse, la suppression a porté sur tout le répertoire //.thumbnails//. Après redémarrage sous Android((Ici LOS16)), le répertoire a été recréé automatiquement, ainsi que le fichier "fautif", mais **avec une taille nulle**.
 +<code>
 +:/sdcard # cd DCIM/.thumbnails
 +:/sdcard/DCIM/.thumbnails # ls -alh
 +total 4.0K
 +drwxrwx--x 2 root sdcard_rw 4.0K 2020-07-26 13:05 .
 +drwxrwx--x 5 root sdcard_rw 4.0K 2020-08-01 16:00 ..
 +-rw-rw---- 1 root sdcard_rw    0 2020-07-26 13:05 .thumbdata4--1967290299
 +:/sdcard/DCIM/.thumbnails # du -ah                                             
 +0       ./.thumbdata4--1967290299
 +4.0K    .
 +</code>
 +  - //ls// nous informe que la taille déclarée du fichier est de 0 octet
 +  - //du// nous affirme que l'espace réellement utilisé est également de 0 octet.
 +Ces valeurs étant constantes après plusieurs jours d'utilisation de l'androphone((Navigation dans la gallerie d'images, prises de photos, envoi et réception d'images via différentes applications…)), on peut raisonnablement en conclure que l'opération de nettoyage a porté ses fruits.
 +<note>L'utilisation d'autres applications manipulant les images a entraîné l'insertion d'images dans le répertoire //.thumbnails// et un début de remplissage du fichier .thumbdata4--1967290299. On est alors ramenée à la [[#une_taille_de_fichier_trompeuse|situation décrite précédemment]]. </note>
 +
 +===== Quelques sources =====
 +==== Pages du manuel des commandes Linux ====
 +Dans cet fiche, on utilise peu de commandes : //ls//, //du//, //df//. Il est toujours intéressant de consulter les pages du manuel mais l'implémentation de ces commandes n'est pas uniforme d'un système à l'autre. La recommandation "lisez le manuel" s'applique à la documentation installée sur le système où vous utilisez cette commande. Dans le cas d'espèce, il n'y a pas de documentation installée sur l'androphone. Heureusement, les commandes sont auto-documentées de manière minimale. Pour obtenir l'information on exécute la commande avec l'option "--help", par exemple :
 +<code>
 +kiwi:/ $ df --help
 +usage: df [-HPkhi] [-t type] [FILESYSTEM ...]
 +
 +The "disk free" command shows total/used/available disk space for
 +each filesystem listed on the command line, or all currently mounted
 +filesystems.
 +
 +-a      Show all (including /proc and friends)
 +-P      The SUSv3 "Pedantic" option
 +
 +</code>
 +Les versions des commandes disponibles sur LineageOS 16 offrent bien moins d'options que celles que l'on trouve sur un système GNU-Linux courant.
 +==== Sur le ouèbe ====
 +  * [[https://android.stackexchange.com/questions/66221/android-huge-thumbdata4-file-in-dcim-folder|Android: huge thumbdata4 file in DCIM folder]] (en) (stackexchange.com)
 +  * [[https://superuser.com/questions/940376/how-to-make-a-sparse-file-on-android-with-terminal|How To Make A Sparse File On Android With Terminal]] (en) (superuser.com)
 +  * [[https://unix.stackexchange.com/a/371247|What is the difference between file size in ls -l and du-sh?]] (en) (stackexchange.com)
 +  * [[https://serverfault.com/a/232526|df in linux not showing correct free space after file removal]] (en) (serverfault.com) "//Deleting the filename doesn't actually delete the file…//"
 +  * [[https://en.wikipedia.org/wiki/Sparse_file|Sparse file]] (en) (wikipedia.org)
 +    * [[https://www.lisenet.com/2014/so-what-is-the-size-of-that-file/|So what is the size of that file? Sparse Files on Linux]] (en)
 +    * [[https://wiki.archlinux.org/index.php/Sparse_file|Sparse file]] (en) (archlinux.org)
 +  * [[https://www.tecmint.com/find-top-large-directories-and-files-sizes-in-linux/|How to Find Out Top Directories and Files (Disk Space) in Linux]] (en) (tecmint.com)
 +  * [[https://www.tecmint.com/check-linux-disk-usage-of-files-and-directories/|10 Useful du (Disk Usage) Commands to Find Disk Usage of Files and Directories]] (en) (tecmint.com)
 +  * [[https://unix.stackexchange.com/questions/4681/how-do-you-sort-du-output-by-size|How do you sort du output by size ?]] (en) (stackexchange.com)
 +  * [[https://www.tecmint.com/find-linux-filesystem-type/|7 Ways to Determine the File System Type in Linux]] (en) (tecmint.com)
 +  * [[https://www.xda-developers.com/diving-into-sdcardfs-how-googles-fuse-replacement-will-reduce-io-overhead/|Diving into SDCardFS]] (en) (xda-developers.com)
 +  * [[https://www.androidauthority.com/android-customization-transfer-files-adb-push-adb-pull-601015/|Android customization – how to transfer files using ADB push and pull commands]] (en)
 +