====== Récupérer l'espace consommé par .thumbnails ====== Cette fiche a un statut particulier car elle ne propose aucune solution. C'est plutôt une fiche d'enquête. ===== 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.)). 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).)). === 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. linux:~$ adb shell kiwi:/ $ su :/ # 130|:/ # whoami root :/ # uname -r 3.10.108-lineageos-g6e87014 :/ # 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) : :/ # df Filesystem 1K-blocks Used Available Use% Mounted on tmpfs 921M 636K 920M 1% /dev tmpfs 921M 0 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 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).)) : :/ # df -ht ext4 Filesystem Size Used Avail Use% Mounted on … /dev/block/mmcblk0p26 11G 7.5G 3.0G 72% /data Ici, la carte SD externe est du type //vfat// : :/ # 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 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…)) : :/ # 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 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 : :/ # 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 À 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. 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 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 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 un autre «fautif» et d'autres moyens d'en libérer. === 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). $ echo > test $ ls -lh test rw-rw---- 1 root sdcard_rw 1 2018-07-01 15:47 test $ du -h test 4.0K test ==== 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**. :/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 . - //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. 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]]. ===== 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 : 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 … 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)