ELECINF344/381

Partie interactive du site pédagogique ELECINF344/ELECINF381 de Télécom ParisTech (occurrence 2011).

Catégories

[CASPER] Choix du système de fichiers

Comme décrit par le précédent post de Thomas, nous avons été amené à faire un choix quant au système de fichiers utilisé sur la carte SD afin de stocker le système d’exploitation.

Le choix en la matière est relativement large, notamment en ce qui concerne les systèmes de fichiers spécialisés pour les périphériques de stockage par blocs (ntfs, fat, extx et autres).

Les mémoires flash ne sont pas des mémoires à blocs tels que les disques durs, et notre attention s’est donc portée dans un premier temps sur les systèmes de fichiers spécialisés tels que JFFS, YAFFS ou encore UBIFS.

Ces systèmes de fichiers prennent en compte la durée de vie limitée des secteurs de la flash et répartissent donc leurs écritures sur toute la mémoire, ce qu’un système de fichiers par blocs ne fait pas, menant ainsi à la rapide destruction des secteurs fréquemment écrits, comme ceux stockant la table d’allocation par exemple.

Cependant une remarque des développeurs du système de fichier UBIFS a retenu notre attention: Étant donné que la plupart des cartes mémoires et clefs usb utilisent à présent le système propriétaire FAT qui ne respecte pas la fragilité de la mémoire et l’use rapidement, les fabricants ont donc décidé d’incorporer des chips FTL (flash translation layer) qui se chargent d’émuler un périphérique par blocs vu de l’extérieur, tout en répartissant les écritures en interne.

Ce faisant, les systèmes de fichiers par blocs de type FAT ou extx ne détruisent plus aussi rapidement la mémoire flash, mais les systèmes de fichiers spécialisés sont devenus inadaptés, bien qu’en principe plus efficaces car ayant une vue plus globale des écritures et lectures à effectuer sur la mémoire que la puce interne à la carte.

Ces systèmes de fichiers sont donc à recommander pour les mémoires flash pures, et déconseillés pour les cartes SD/MMC.

Notre choix s’est donc tourné finalement vers un système de fichiers par blocs.

Étant donné qu’un système de fichiers non journalisé limite le nombre d’écritures sur la carte, prolongeant ainsi sa durée de vie, notre choix final s’est donc porté sur l’ext2.

Sur le même sujet :

  1. [CASPER] Architecture et liste de composants
  2. [CASPER] Reconnaissance et synthèse vocale / Solutions Wi-Fi
  3. [CASPER] Dernières avancées…
  4. MB Led: PCB et algorithmique
  5. [CASPER] Définition de l’architecture

3 comments to [CASPER] Choix du système de fichiers

  • Daniel

    Bonjour,

    Serait-il possible d’approfondir l’explication de votre choix de trade-off d’un système de fichier non journalisé (ext2) plutôt qu’un système de fichier journalisé comme ext3 par exemple ? Quel est la durée de vie dans les deux cas ? La taille du système d’exploitation et des donnés que vous y stockerez ? Allez vous créer différentes partitions par exemple etc ?

    Belle explication pour le reste :)

    Merci.

  • Phh

    Mouais alors tout ça c’est une description assez approximative.
    (Et oui j’arrive un train en retard.)
    Un jour il faudra que quelqu’un fasse un vrai article complet et détaillé à ce propos, mais ça sera pour un autre jour.
    Bon, donc une mémoire flash (aussi bien ce que certains appellent abusivement une ROM, qu’une clé usb, carte SD, SSD, ou ami), est à la base une mémoire NAND, son principe est qu’on peut facilement mettre un bit quelconque à 0 (opération d’écriture), mais c’est plus compliqué de le mettre à 1 (opération d’effaçage).
    En pratique, on a classiquement des blocs de 2048 octets pour pouvoir les passer à 0 un à un (ie on est pas obligé de tous les mettre à 0), et des blocs d’entre 128ko et 512ko (plus ?) pour les mettre à 1, et c’est obligatoirement tous d’un coup.
    C’est une « philosophie » radicalement différente des systèmes normaux, sur lesquels on écrit/lit toujours un bloc sans broncher.
    Maintenant, la différence entre une mémoire flash et {une clé usb, une carte SD}, c’est la présence ou non d’abstraction.
    Pour la mémoire flash, le système d’exploitation est obligé de prendre ce problème en considération, les seules opérations qu’il a à disposition sont celles mentionnées au dessus (à savoir mettre à 0 par ci par là, et tout mettre à 1). C’est ici que les systèmes de fichier yaffs2, jffs2, logfs, ubifs (et peut être d’autres) arrivent: ils sont prévus pour ce type de mémoire. Leur principe de base est assez simple et le même, c’est celui de la journalisation, la vraie, où absolument tout est journalisé, et pas juste les métadonnée.
    C’est à dire que l’initialisation du système de fichier se résume à effacer tous les blocs alloués à la partition (c’est particulièrement vrai pour le jffs2, l’initialisation est effectivement uniquement ça, et c’est au seulement au mount qu’il se passe des choses), et l’ajout de fichier/écriture de donnée/modification d’un fichier/changement d’attribut, est rajouté à la fin de ce qui a déjà été écris: on ne fait que des opérations d’écriture, et aucune opération d’effaçage. Durée de vie maximisée de la flash. Évidement il faudra effacer de temps en temps les trucs qui sont considérés inutiles, donc c’est pas aussi simple.
    Si jamais on voulait mettre un système de fichier normal sur une telle mémoire, par un mapping simple des fonctionnalités nécessaire par raport à celles disponibles, on obtient: à chaque fois qu’on écrirait un octet, il faudra lire un bloc d’effacemenet (128ko/512ko ou dans ces eaux là), changer en mémoire le bloc d’écriture qui vient de changer, et réécrire le bloc d’effacement. Avec cette méthode, pour réécrire dans un bloc il faut 512ko/2048o = 256 effaçage. Autant dire que la carte ne va pas faire long feu, et on aurait des performances catastrophiques ! (débit divisé par le nombre d’effaçage quasiment.)

    Maintenant, j’ai dit qu’une clé usb, c’est effectivement de la NAND, et les constructeurs ne sont pas cons, ni totalement malhonnetes (ahum.), ils ont donc différentes méthodes pour apparaitre comme étant effectivement un périphérique de type bloc « standard » sans avoir des destructions quasi-immédiate de la carte.
    À ma connaissance, les constructeurs ne publient pas leur méthodes (mais je ne me suis pas vraiment renseigné là dessus), mais ils doivent utiliser différentes techniques comme avoir des blocs utiles non pas de 512ko, mais de 384ko (valeur complétement prise au pif, et dont je n’ai aucune idée de l’ordre de grandeur de sa validité.), si bien que lorsqu’un kilo-octet est modifié, on le rajoute au 384°ko, et on marque le 5°ko (celui qu’on vient d’écrire.) comme étant invalide (dans une table qui doit aussi arriver à respecter la structure de la NAND, ça fait mal non?).
    Il y a aussi la méthode du buffer, on attend 1s (en vrai je doute que ce soit compté en seconde, mais plutot en nombre d’instructions ou quelque chose du genre et mon ordre de grandeur est complétement folklorique) après la première écriture, et on agrège les écritures, en priant pour écrire plus que 2048octet dans un bloc d’effacement.
    Ils sont aussi censés avoir des algorithmes pour éviter que ce soit toujours les même blocs qui se fassent effacer (typiquement le bloc qui gère /etc/mtab est réécrit à chaque boot, et même plus), et là ils travaillent sur des blocs de l’ordre de 4MB. C’est à dire que le-dit /etc/mtab (s’il n’est pas réalloué par le FS à un autre bloc logique.), sera toujours quelque part dans ces 4MB, mais à position plus ou moins aléatoire pour éviter que ce soit toujours le même bloc qui prenne cher. Néanmoins, 4MB/512kB, ça fait que 8 blocs gérés à la fois par zone…

    Pour résumer tout ça, c’est un gros hack pour éviter de devoir coder un driver et un système de fichier pour windows. (en tout cas c’est comme ça que je le vois)

    À noter que cette manie du « on cache tout à l’OS », a commencé à un peu disparaître (mais ça devrait s’arrêter là): la plupart des SSDs, les prochaines normes de cartes SD, les eMMC ont une nouvelle catégorie d’instruction, les « TRIM ». Derrière ce nom bizarre (‘fin je le trouve bizarre.), se cache le retour de l’instruction d’effacement ! Un système de fichier peut maintenant signaler au périphérique sous-jacent qu’une zone disque lui est inutilee, et que le périphérique peut l’effacer. À noter que c’est devenu ici une possibilité uniquement. Le système de fichier n’est pas obligé de signaler ce fait au périphérique sous-jacent, et le-dit périphérique n’est pas obligé d’effacer ces données (si les FS lui annonce un trou de 256kB et que le périph travaille sur des blocs d’effacement de 512kB, ça lui fait une belle jambe.).

    Voilà. Maintenant la question c’est de savoir quel système de fichier utiliser sur des systèmes avec FTL de mauvaise qualité (genre clé usb, carte SD) (je dis de mauvaise qualité pour mettre les SSD de côté. À ma connaissance, les SSD ont des performantes remarquables sur des FSs normaux sans devoir magouiller, avec une bonne durée de vie, donc je suppose qu’un FS adapté est inutile. Mais si quelqu’un veut m’acheter un SSD pour que je teste *ahum*), mauvaise qualité signifiant principalement qu’il travaille sur des gros blocs physiques de 4MB, donc que 8 blocs par zone pour le wear-leveling.
    La FTL étant considérée comme plutôt stupide, on suppose qu’on a un système à peu près équivalent à être sans FTL, mais avec un buffer quand même.
    Dans ces conditions, le FS « idéal », suit encore les même règles: journalisation totale ! Sauf que là on ne peut plus utiliser les systèmes de fichiers comme yaffs2, jffs2, ubifs, & cie, parce qu’ils ont besoin de connaître et contrôler exactement la structure sous-jacente du périphérique, et c’est pas le TRIM qui ira les aider.
    Un système de fichier normal effacera beaucoup trop souvent les blocs, et devra les réécrire à chaque fois. Perte énorme de vitesse (à moins qu’il ne réécrive 512ko d’un coup. Mais sur un FS normal, c’est assez rare.), et de durée de vie (plein d’effacements inutiles.)
    Il faut donc un FS totalement journalisé sur périphérique bloc « normal ».
    À noter qu’un FS totalement journalisé sans la fonction TRIM n’est pas encore génial: de nombreuses opérations ne se font que sur quelques ko, et pour ces opérations la FTL devra réécrire tout le bloc, même s’il n’y a rien d’intéressant pour le FS derrière (il journalise, donc toutes ses données sont avant), mais comme le FS n’a aucun moyen de dire au périphérique que ce bloc est inutile, le périphérique se comporte pareil que pour un autre FS. Donc un FS qui gère le TRIM ça aide, mais bon la plupart des cartes SD ou clé USB ne le gèrent pas, donc ça sera pas d’un grand secours.
    Je ne connais que deux tels systèmes de fichiers sous linux, c’est nilfs2 et logfs. Je n’ai jamais testé logfs (et wikipedia dit qu’il ne gère les périphériques blocs normaux (ie carte SD/clé usb) que partiellement), mais j’ai pu tester nilfs2.

    Je n’ai pas pu faire de tests de durée de vie (si quelqu’un a deux lecteurs de carte SD, et deux cartes SD pour tests je suis prenneur :D ), néanmoins j’ai pu faire des tests de performance (si vous avez bien suivi ce que j’ai dit précedement, les pertes des performances des systèmes normaux sont synonymes de perte en durée de vie).

    Alors bon, j’ai pas fait de vrai tests de perf (bon si, quand même un.), mais globalement, le changement du système de fichier d’une racine debian, de ext3 en nilfs2 change radicalement la vie, et toutes les personnes qui ont une racine en carte SD (bon eMMC en vrai, donc ça a du TRIM) à qui j’ai fait ce conseil sont d’accord avec moi. Pour commencer avec le seul vrai test que j’ai fait: extraction d’un noyau linux (ce que je pensais être le test qui montrerait le plus de différences: énormement de petits fichiers, pleins de petits blocs à écrire un peu partout sur le disque, une catastrophe pour les cartes SD&co). L’ext3 était trois fois plus lent que le nilfs2. Bon, vous allez me dire c’est déjà assez pour être convaincu, non ?
    Et bah j’ai encore mieux ! Sur un apt-get (parce que bon on a assez de place pour s’installer une debian ou une ubuntu, pas besoin de se taper une openembedded), install ou update, la différence est encore plus grande. L’opération d’ouverture de la base de données (dont je n’ai absolument aucune idée de ce qu’elle fait précisement.) qui prend une éternité en ext3, est quasi instantannée en nilfs2. L’installation des paquets est radicalement plus rapide (mais ça, ça revient au test d’extraction du noyau linux). Le système est plus réactif (le noyau est moins souvent bloqué comme un con à attendre que la carte SD fasse son petit nettoyage).
    À noter que nilfs2 n’est pas encore idéal, il souffre d’un défaut que certain pourront considérer comme assez génant: il a besoin d’un garbage collector (vu que sinon un jour le journal dépasse la taille de la partition. Même si c’est une partition de 4Go et un fichier de 1Mo, s’il est réécrit 4000 fois, boum.), il faut bien nettoyer les morceaux qui servent à rien. Et donc ce garbage collector appelle la fonction TRIM, qui est incroyablement lente et bloquante, donc quand le GC décide de tourner, la machine est autant dire inutilisable. Si vous n’effacez pas un gros stock de fichier d’un coup, il n’y a pas de problème, le gc ne travaillera que sur quelques petits fichiers, et ça sera très rapide. À noter que lorsque vous aurez besoin d’une réactivité parfaite (un hélico avec 1s de lag c’est pas très bon), vous pouvez tuer le GC, c’est un processus en userland tout à fait normal. D’ailleurs il faut penser à l’installer (nilfs2-tools ou utils), sous peine de se faire sanctionner assez rapidement d’un not enough space available.

    PS: J’ai fait l’équivalent de 1/3 de mon PACE avec ce post, c’est quand même triste …
    PPS: J’espère qu’il va un tant soit peu garder mes retours à la ligne, sinon ce pavé sera totalement illisible, et d’ailleurs il est où le bouton prévisualiser ?

  • Daniel

    Classiquement les pages d’une mémoire NAND font effectivement 2ko (+64o oob) pour des blocs de 128ko, mais bon maintenant ça monte aussi à des tailles de pages de 8ko et plus.

    Je ne connais pas trop nilfs2 qui, d’après ton post, a l’air d’être plutôt performant :)
    Par contre, il est vrai qu’un GC peut être assez gênant si on compte faire du temps réel j’imagine !

    Merci pour ce post.