-1

Вот моя ситуация. У меня есть два архивных тома холодного хранения, которые (должны) содержать идентичные наборы данных. Эти тома содержат редко используемые резервные копии. Я обеспокоен тем, что, в конечном счете, bitrot попадет к одному или обоим из них и слегка испортит данные, содержащиеся в них. Я знаю, что могу diff -r два тома и находить файлы, которые изменились или исчезли между ними, но я не получаю никаких полезных указаний о том, на каком томе есть "хорошая" копия. Это USB-диски, и преобразование их в нечто вроде ZFS кажется ... обременительным.

Что мне нужно, так это инструмент, который будет рекурсивно обходить дерево каталогов и писать файл манифеста, содержащий путь и имя файла вместе с хэшем содержимого файла. Я запускал этот инструмент сразу после записи данных на каждый том и сохранял полученный файл манифеста в теплом хранилище, возможно, под каким-то контролем версий.

Из этого файла я хотел бы иметь возможность запускать что-то, что работает точно так же, как diff -r - оно сообщит мне, были ли файлы добавлены, удалены или их содержимое изменилось. Только вместо того, чтобы сравнивать один том с другим, он сравнил бы один том с файлом заведомо исправного манифеста. Используя этот метод, я смогу определить, совпадают ли данные, которые я читаю с диска, месяцы / годы в будущем, с данными, которые я изначально положил на него.

Я должен был бы думать, что что-то подобное уже существует. Я могу получить что-то приближенное к файлу манифеста, используя:

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

но до сих пор я не нашел хорошего способа проанализировать этот файл и рекурсивно проверить каждый хеш. Также, что несколько менее важно, это не скажет мне, появился ли пустой каталог или исчез. (Я не могу понять, почему это имеет значение, но было бы приятно узнать, что это произошло.)

Я на правильном пути с этим, или есть более подходящий инструмент, который может делать такие вещи?

2 ответа2

2

md5sum -c manifest.txt будет учитывать пути, хранящиеся в manifest.txt . Программа find заменяет {} полный путь к найденному файлу, включая любое местоположение поиска, указанное в командной строке find , т. Е. Для файла ./a/b/c/d/e оно будет заменять его ./a/b/c/d/e для команды find ./a -type f -exec md5sum {} \;

Возможная проблема - абсолютные пути, поэтому более подходящей «командой создания манифеста» является:

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

однако вы всегда можете исправить пути с помощью sed внутри mainfest.txt

2

Вы правы, такой инструмент уже существует. Хотя я вижу, что ваш пост помечен как «linux», возможно, BSD-ориентированное решение будет назидательным.

Утилита FreeBSD mtree(8) может делать именно то, что вы просите.

Предположим, что:

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

Чтобы создать манифест этой иерархии файлов, включая хэш sha256 для каждого файла, нужно:

$ 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
..

Затем можно проверить иерархию файлов в манифесте, отправив манифест в mtree:

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

Добавленные, удаленные, переименованные или измененные файлы приведут к сбою проверки:

$ 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .