Criando um arquivo tar com somas de verificação incluídas

16

Aqui está o meu problema: preciso arquivar para tar arquivos (até 60 TB) de arquivos grandes (geralmente 30 a 40 GB cada). Eu gostaria de criar somas de verificação (md5, sha1, qualquer que seja) desses arquivos antes de arquivar; no entanto, não ler todos os arquivos duas vezes (uma para soma de verificação, duas vezes para tar'ing) é mais ou menos uma necessidade para obter um desempenho de arquivamento muito alto (o LTO-4 quer 120 MB / s sustentados e a janela de backup é limitada).

Então, eu precisaria de alguma maneira de ler um arquivo, alimentando uma ferramenta de soma de verificação de um lado e construindo um alcatrão para fita do outro lado, algo junto:

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

Exceto que eu não quero a soma de verificação de todo o arquivo morto (este exemplo de código de shell faz exatamente isso), mas uma soma de verificação para cada arquivo individual no arquivo morto.

Estudei as opções GNU tar, Pax, Star. Eu olhei para a fonte de Archive :: Tar . Não vejo uma maneira óbvia de conseguir isso. Parece que terei que criar manualmente algo em C ou semelhante para conseguir o que preciso. O Perl / Python / etc simplesmente não diminui o desempenho, e os vários programas tar perdem a "arquitetura de plug-in" necessária. Alguém sabe de alguma solução existente para isso antes de começar a agitar o código?

wazoox
fonte
2
Certamente soa como um complemento útil para tarse você decidir escrevê-lo;) #
1
Não sua pergunta, mas com 7zvocê pode escolher o hash e imprimi-lo de uma forma que sha1sume sha256sumpode entender: 7zip.bugaco.com/7zip/7zip_15_09/MANUAL/cmdline/commands/... (e sami-lehtinen.net/blog/... ) Experimente: 7z h -scrcsha256 mydir/* | sed --regexp-extended 's, +[0-9]+ +, ,g' > mydir.sha256sum ; sha256sum -c mydir.sha256sum(testado com a versão 15.09 beta do p7zip)
Nemo

Respostas:

15

Antes de prosseguir e reescrever o tar, você pode criar um perfil do método rápido e fácil de ler os dados duas vezes, pois pode não ser muito mais lento do que fazê-lo de uma só vez.

O método de duas passagens é implementado aqui:

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

com a linha única:

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

Embora seja verdade que o md5sum está lendo cada arquivo do disco em paralelo com o tar, em vez de obter os dados transmitidos pelo canal, o cache de disco do Linux deve fazer com que este segundo leia uma leitura simples de um buffer de memória, que não deve ser realmente mais lento do que uma leitura stdin. Você só precisa ter espaço suficiente no cache do disco para armazenar o suficiente de cada arquivo que o segundo leitor esteja sempre lendo no cache e não ficando atrás o suficiente para recuperar o disco.

bk.
fonte
3
Na verdade, ele funciona muito bem, parece limitado pela capacidade da CPU de processar o md5 (~ 280 MB / s em um núcleo).
wazoox
4

Aqui está um exemplo de script Python. Ele calcula a soma de verificação do arquivo como sendo adicionada ao arquivo morto. No final do script, o arquivo de soma de verificação é adicionado ao arquivo morto.

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()

Ao desarmar, use o chksum_file para verificar a soma de verificação

user37841
fonte
1
Sim, isso é algo assim que eu pensava, mas normalmente este tipo de bibliotecas carregar o arquivo na RAM antes de manipulá-lo, e os meus arquivos são pelo menos 20 GB ....
wazoox
1

Eu acho que seu problema é uma questão de design do tar, pois o tar não permite acesso / posicionamento aleatório dentro do arquivo morto através de uma tabela de conteúdo, portanto, todos os protocolos serão de arquivo e não baseados em buffer.
Assim, você pode observar diferentes formatos, como PAX ou DAR, que permitem acesso aleatório.

Weismat
fonte
1
Infelizmente, a saída do alcatrão é obrigatória, porque é nisso que o fluxo de trabalho se baseia.
wazoox
0

Os formatos de arquivo recentes geralmente incluem alguns hash para verificação de arquivos, mas eles têm um problema semelhante: nem sempre é possível escolher sua própria função de hash, nem manter uma cópia local dos hashes.

Convém salvar uma cópia local dos hashes, diferente daquela incorporada no próprio arquivo morto: por exemplo, se o arquivo morto estiver armazenado offline (em fitas ou em um datacenter caro para ler) e você desejar verificar uma cópia local de um arquivo / diretório.

O 7zip tem várias opções, como o 7z hhash personalizado e 7z l -slta lista de todos os hashes e outros enfeites, mas e se você quiser uma lista de hashes MD5 ou sha1? Você pode usar -bbe-bs controlar a verbosidade e reutilizar o método George Notaras mencionado na resposta aceita:

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
fonte