Existe uma ferramenta como diff -r que compara uma árvore de diretórios contra um arquivo de manifesto usando hashes?

-1

Aqui está minha situação. Eu tenho dois volumes de arquivo de armazenamento a frio que (devem) conter conjuntos idênticos de dados. Esses volumes contêm backups acessados com pouca frequência. Estou preocupado que, eventualmente, o bitrot chegue a um ou a ambos e sutilmente corrompa os dados contidos nele. Eu sei que posso diff -r os dois volumes e encontrar arquivos que foram alterados ou desapareceram entre os dois, mas não obtenho nenhuma indicação útil sobre qual volume tem a cópia "boa". Estes são discos USB, e convertê-los em algo como o ZFS parece ... oneroso.

O que eu gostaria é de uma ferramenta que percorra recursivamente a árvore de diretórios e escreva um arquivo de manifesto contendo o caminho e o nome do arquivo junto com um hash do conteúdo do arquivo. Eu executaria essa ferramenta imediatamente depois de gravar os dados em cada volume e armazenaria o arquivo de manifesto resultante no armazenamento quente, talvez sob algum tipo de controle de revisão.

Nesse arquivo, eu gostaria de poder executar algo que funciona exatamente como diff -r - ele me diria se arquivos foram adicionados, removidos ou seus conteúdos alterados. Somente em vez de comparar um volume com outro, ele compara um volume com o arquivo de manifesto em bom estado. Usando esse método, eu deveria saber se os dados que estou lendo no disco meses / anos no futuro são idênticos aos dados que eu coloquei originalmente.

Eu teria que pensar que algo assim já existe. Eu posso conseguir algo aproximando um arquivo de manifesto usando:

find /mnt/my-volume -type f -exec md5sum {} + > manifest.txt

mas até agora não encontrei uma boa maneira de analisar esse arquivo e verificar cada hash de forma recursiva. Além disso, um pouco menos importante, isso não vai me dizer se um diretório vazio apareceu ou desapareceu. (Não consigo pensar em por que isso importaria, mas seria bom saber que isso ocorreu.)

Estou no caminho certo com isso, ou existe uma ferramenta mais apropriada que possa fazer esse tipo de coisa?

    
por smitelli 15.06.2016 / 01:36

2 respostas

2

O md5sum -c manifest.txt honraria os caminhos armazenados em manifest.txt . O programa find substitui {} o caminho completo para o arquivo encontrado, incluindo qualquer local de pesquisa especificado na linha de comando find , ou seja, para o arquivo ./a/b/c/d/e ele substituirá o mesmo comando ./a/b/c/d/e for find ./a -type f -exec md5sum {} \;

O possível problema são caminhos absolutos, então o mais apropriado 'comando de criação de manifesto' é:

cd /mnt/my-volume; find  -type f -exec md5sum {} + > manifest.txt

no entanto, você sempre pode corrigir os caminhos com sed dentro de mainfest.txt

    
por 15.06.2016 / 04:08
2

Você está certo, essa ferramenta já existe. Enquanto eu vejo que seu post está marcado como 'linux', talvez uma solução orientada ao BSD seja edificante.

O utilitário mtree (8) do FreeBSD pode fazer exatamente o que você está pedindo.

Suponha que:

$ find .
.
./c
./c/file3
./b
./b/file2
./a
./a/file1

Para criar um manifesto dessa hierarquia de arquivos, incluindo um hash sha256 de cada arquivo, um seria:

$ mtree -c -K sha256 > /tmp/manifest.txt
$ cat /tmp/manifest.txt
#          user: diego
#       machine: myhost.example.com
#          tree: /data/home/diego/foo
#          date: Wed Mar 28 10:31:17 2018

# .
/set type=file uid=1001 gid=1001 mode=0710 nlink=1 flags=uarch
.               type=dir nlink=5 time=1522257963.738221000

# ./a
/set type=file uid=1001 gid=1001 mode=0600 nlink=1 flags=uarch
a               type=dir mode=0710 nlink=2 time=1522257932.680802000
    file1       size=29 time=1522257932.682389000 \
                sha256digest=6b4114c4f12e63c0ca44073de5ca0a2b39fedaceaa533af3dfdc89f00039c973
# ./a
..


# ./b
b               type=dir mode=0710 nlink=2 time=1522257937.929131000
    file2       size=29 time=1522257937.930666000 \
                sha256digest=9f7a0a49475bb6f98e609a4e057f0bc702c5e4706be5bd656a676fd8d15da7ef
# ./b
..


# ./c
c               type=dir mode=0710 nlink=2 time=1522257942.064315000
    file3       size=29 time=1522257942.065882000 \
                sha256digest=bd617f47217ef0605d3aff036778d10bf18cb2f415c45e8e362e2c091df19491
# ./c
..

Pode-se então verificar a hierarquia do arquivo em relação ao manifesto, colocando o manifesto no mtree:

$ mtree < /tmp/manifest.txt || echo fail

Arquivos adicionados, excluídos, renomeados ou modificados farão com que a verificação falhe:

$ touch foo
$ mtree < /tmp/manifest.txt || echo fail
.:      modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:37:01 2018)
extra: foo
fail
$ rm foo; touch b/file2; mtree < /tmp/manifest.txt || echo fail
.:      modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:39:39 2018)
b/file2: 
        modification time (Wed Mar 28 10:25:37 2018, Wed Mar 28 10:39:39 2018)
fail
$ mv c/file3 c/FILE3; rm a/file1; date >> b/file2; mtree < /tmp/manifest.txt || echo fail
.:      modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:39:39 2018)
c:      modification time (Wed Mar 28 10:25:42 2018, Wed Mar 28 10:41:59 2018)
extra: c/FILE3
b/file2:
        size (29, 58)
        modification time (Wed Mar 28 10:25:37 2018, Wed Mar 28 10:47:31 2018)
        sha256digest (0x9f7a0a49475bb6f98e609a4e057f0bc702c5e4706be5bd656a676fd8d15da7ef, 0x569c17bd1a1ca2447fd8167f103531bf3a7b7b4268f0f68b18506e586e7eea94)
a:      modification time (Wed Mar 28 10:25:32 2018, Wed Mar 28 10:41:59 2018)
./a/file1 missing
./c/file3 missing
fail
    
por 28.03.2018 / 19:54