10 points par xguru 2022-07-25 | 1 commentaires | Partager sur WhatsApp
  • L’enquête a commencé en constatant un ralentissement énorme lors de l’extraction d’un tar.gz de 518GiB
  • Explication du format tar et présentation, en parallèle, d’un code d’extracteur tar rapide

Format de fichier Tar original

  • Tar est très atypique pour un fichier d’archive
    → Il n’y a pas d’en-tête d’archive, pas d’index de fichiers pour la recherche, pas de magic bytes permettant d’identifier qu’il s’agit d’un tar, pas de footer, ni de métadonnées
    → Dans un tar, il n’existe qu’un seul type d’objet : le fichier
  • Types de fichiers : 0 (fichier ordinaire), 1 (lien physique), 2 (lien symbolique)
  • Explication de la structure de l’en-tête d’objet fichier de 512 octets
    → La plus grande limite est que le chemin de fichier ne peut faire que 100 caractères. De plus, la taille maximale d’un fichier est de 8GiB

Fichier étendu UStar

  • La longueur maximale du chemin de fichier passe à 256 et de nouveaux types de fichiers sont ajoutés
  • Extension de l’en-tête avec ajout de magic bytes et d’un champ prefix
  • Types de fichiers ajoutés : 3 (périphérique caractère), 4 (périphérique bloc), 5 (répertoire), 6 (fichier FIFO), 7 (fichier contigu)
  • Mais la limite de 8GiB reste inchangée

Format de fichier Pax

  • Le format tar est étendu via la CLI pax dans la norme POSIX.1-2001
  • Identique à UStar, mais avec ajout des formats de fichiers x et g
    → En tant qu’enregistrements d’en-tête étendus, x ne s’applique qu’au fichier suivant, tandis que g s’applique à tous les fichiers qui suivent

Format de fichier GNU Tar

  • Son format propre est gnu, différent de pax
  • Comme pax, il repose sur UStar, mais utilise une autre méthode pour encoder les chemins et les gros fichiers
    → Type L : la charge utile de l’objet fichier suivant représente "file_path"
    → Type K : la charge utile de l’objet fichier suivant représente "link_path"
    → Il est possible d’appliquer les deux à la suite
    → Si un fichier dépasse 8GiB, le bit de poids fort du premier caractère de file_size est activé. Le reste de la chaîne est alors analysé en base 256 (entier sur 95 bits)

Pourquoi GNU tar est-il lent à décompresser ?

  • Si l’on place dans l’en-tête d’un fichier une valeur comme file_path="../hello.txt", cela crée un problème de sécurité. Mais il n’est pas simple de l’empêcher
  • GNU tar crée un placeholder lorsqu’il rencontre ".." dans link_path, puis traite cela en différé
  • Cependant, dans le cas d’un lien physique sans "..", il voudrait le créer directement, mais c’est impossible car un placeholder existe déjà
  • Autrement dit, pour créer un lien physique, il faut d’abord vérifier s’il correspond à un lien différé ; et si c’est le cas, le nouveau lien doit lui aussi être traité en différé
    → GNU tar doit donc rechercher les liens différés pour tous les liens physiques. Pour une raison inconnue, il effectue en pratique cette recherche deux fois
  • Dans le fichier tar de l’auteur, il y avait plus de 800 000 liens contenant ".." et plus de 5,4 millions de liens physiques, ce qui a ralenti l’extraction
  • Pour éviter cela, il faut ajouter à tar l’option --absolute-paths ou -P
    → Cette option enregistre des chemins absolus et refuse ".."
    → En d’autres termes, l’option -P désactive le mécanisme de liens différés