Création d'un fichier tar avec des sommes de contrôle incluses

16

Voici mon problème: j'ai besoin d'archiver dans des fichiers tar beaucoup (jusqu'à 60 To) de gros fichiers (généralement de 30 à 40 Go chacun). Je voudrais faire des sommes de contrôle (md5, sha1, peu importe) de ces fichiers avant l'archivage; cependant, ne pas lire chaque fichier deux fois (une fois pour la somme de contrôle, deux fois pour le tarage) est plus ou moins une nécessité pour atteindre des performances d'archivage très élevées (LTO-4 veut 120 Mo / s soutenus et la fenêtre de sauvegarde est limitée).

J'aurais donc besoin d'un moyen de lire un fichier, d'alimenter un outil de somme de contrôle d'un côté et de construire un tar sur bande de l'autre côté, quelque chose le long:

tar cf - files | tee tarfile.tar | md5sum -

Sauf que je ne veux pas la somme de contrôle de l'archive entière (cet exemple de code shell fait exactement cela), mais une somme de contrôle pour chaque fichier individuel dans l'archive.

J'ai étudié les options GNU tar, Pax, Star. J'ai regardé la source d' Archive :: Tar . Je ne vois aucun moyen évident d'y parvenir. Il semble que je devrai construire quelque chose à la main en C ou similaire pour obtenir ce dont j'ai besoin. Perl / Python / etc ne le réduira tout simplement pas en termes de performances, et les différents programmes tar manquent "l'architecture de plug-in" nécessaire. Quelqu'un connaît-il une solution à ce problème avant de commencer le barattage de code?

wazoox
la source
3
Sonne certainement comme un ajout utile tarsi vous décidez de l'écrire;)
1
Pas votre question, mais 7zvous pouvez choisir le hachage et l' imprimer d'une manière sha1sumet sha256sumpeut comprendre: 7zip.bugaco.com/7zip/7zip_15_09/MANUAL/cmdline/commands/... (et sami-lehtinen.net/blog/... ) Essayez-le: 7z h -scrcsha256 mydir/* | sed --regexp-extended 's, +[0-9]+ +, ,g' > mydir.sha256sum ; sha256sum -c mydir.sha256sum(testé avec p7zip version 15.09 bêta)
Nemo

Réponses:

15

Avant d'aller de l'avant et de réécrire tar, vous souhaiterez peut-être profiler la méthode rapide et facile de lecture des données deux fois, car cela peut ne pas être beaucoup plus lent que de le faire en un seul passage.

La méthode à deux passes est impliquée ici:

http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/

avec le one-liner:

  tar -cvpf mybackup.tar myfiles/| xargs -I '{}' sh -c "test -f '{}' && 
  md5sum '{}'" | tee mybackup.md5

Bien qu'il soit vrai que md5sum lit chaque fichier du disque en parallèle avec tar, au lieu d'obtenir les données diffusées via le canal, le cache de disque Linux devrait faire de cette seconde lecture une lecture simple à partir d'un tampon de mémoire, qui ne devrait pas vraiment être plus lent que une lecture stdin. Vous avez juste besoin de vous assurer que vous disposez de suffisamment d'espace dans votre cache disque pour stocker suffisamment de chaque fichier que le 2ème lecteur lit toujours à partir du cache et ne se trouve pas assez loin pour avoir à récupérer à partir du disque

bk.
la source
3
Cela fonctionne en fait assez bien, il semble limité par la capacité du processeur à crunch md5 (~ 280 Mo / s sur un cœur).
wazoox
4

Voici un exemple de script Python. Il calcule la somme de contrôle du fichier lors de son ajout à l'archive. À la fin du script, le fichier de somme de contrôle est ajouté à l'archive.

import hashlib,os
import tarfile
def md5(filename):
    ''' function to get md5 of file '''
    d = hashlib.md5()
    try:
        d.update(open(filename).read())
    except Exception,e:
        print e
    else:
        return d.hexdigest()

root="/home"
outtar=os.path.join(root,"path1","output.tar")
path = os.path.join(root,"path1")
chksum_file=os.path.join(root,"path","chksum.txt")
tar = tarfile.open(outtar, "w")
o_chksum=open(chksum_file,"w")
for r,d,f in os.walk(path):
    for files in f:
        filename=os.path.join(r,files)
        digest="%s:%s"%(md5(filename) , filename)
        o_chksum.write(digest+"\n")
        tar.add(os.path.join(r,files))

tar.add(chksum_file)
tar.close()
o_chksum.close()

Lorsque vous décompressez, utilisez le chksum_file pour vérifier la somme de contrôle

user37841
la source
1
Oui, c'est quelque chose comme ça auquel j'ai pensé, mais généralement ce type de bibliothèques charge le fichier en RAM avant de le manipuler, et mes fichiers font au moins 20 Go ....
wazoox
1

Je pense que votre problème est un problème de conception de tar car tar ne permet pas un accès / positionnement aléatoire à l'intérieur du fichier d'archive via une table de contenu, donc tous les protocoles seront basés sur un fichier et non sur un tampon.
Ainsi, vous pouvez regarder différents formats comme PAX ou DAR qui permettent un accès aléatoire.

weismat
la source
1
Malheureusement, la sortie tar est obligatoire, car c'est sur cette base que le workflow est basé.
wazoox
0

Les formats d'archives récents incluent généralement un hachage pour la vérification des fichiers, mais ils ont un problème similaire: vous ne pouvez pas toujours choisir votre propre fonction de hachage, ni conserver une copie locale des hachages.

Vous voudrez peut-être enregistrer une copie locale des hachages, distincte de celle incorporée dans l'archive elle-même: par exemple, si l'archive est stockée hors ligne (sur des bandes ou un centre de données dont la lecture coûte cher) et que vous souhaitez vérifier une copie locale d'un fichier / répertoire.

7zip a plusieurs options comme 7z havec un hachage personnalisé et 7z l -sltpour lister tous les hachages et ainsi de suite, mais que faire si vous voulez une liste de hachages md5 ou sha1? Vous pouvez utiliser -bbet-bs contrôler la verbosité et réutiliser la méthode George Notaras mentionnée dans la réponse acceptée:

7z a -bsp1 -bb3 dir.7z dir 2>&1 \
| grep "^+" | sed 's,^+ ,,g' | xargs -d "\n" -I § -P 1 sh -c "test -f '§' && sha1sum '§'" \
| tee dir.sha1
Nemo
la source