Создание файла tar с включенными контрольными суммами

16

Вот моя проблема: мне нужно архивировать в tar-файлы много (до 60 ТБ) больших файлов (обычно от 30 до 40 ГБ каждый). Я хотел бы сделать контрольные суммы (md5, sha1, что угодно) из этих файлов перед архивированием; однако, не считывание каждого файла дважды (один раз для контрольной суммы, два раза для tar'ing) более или менее необходимо для достижения очень высокой производительности архивирования (LTO-4 хочет поддерживать 120 МБ / с, а окно резервного копирования ограничено).

Поэтому мне понадобится какой-нибудь способ прочитать файл, подать инструмент проверки контрольных сумм с одной стороны и создать tar-ленту на другой стороне, что-то вроде:

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

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

Я изучал GNU tar, Pax, Star варианты. Я посмотрел на источник из архива :: Tar . Я не вижу очевидного способа добиться этого. Похоже, мне придется собрать что-то вручную в C или подобном, чтобы достичь того, что мне нужно. Perl / Python / etc просто не снизит производительность, а различные программы tar пропустят необходимую «архитектуру плагинов». Кто-нибудь знает какое-либо существующее решение этой проблемы, прежде чем я начну использовать код?

wazoox
источник
3
Конечно, звучит как полезное дополнение, tarесли вы решите написать это;)
1
Не ваш вопрос, но 7zвы можете выбрать хэш и напечатать его таким образом , что sha1sumи sha256sumможно понять: 7zip.bugaco.com/7zip/7zip_15_09/MANUAL/cmdline/commands/...sami-lehtinen.net/blog/... ) Попробуйте: 7z h -scrcsha256 mydir/* | sed --regexp-extended 's, +[0-9]+ +, ,g' > mydir.sha256sum ; sha256sum -c mydir.sha256sum(протестировано с версией 15.09 p7zip)
Nemo

Ответы:

15

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

Здесь используется двухпроходный метод:

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

с однострочником:

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

Хотя верно, что md5sum читает каждый файл с диска параллельно с tar, вместо того, чтобы передавать данные через канал, кэширование диска Linux должно сделать это второе чтение простым чтением из буфера памяти, которое на самом деле не должно быть медленнее, чем стандартное чтение. Вам просто нужно убедиться, что в вашем дисковом кеше достаточно места для хранения достаточного количества каждого файла, который 2-й читатель всегда читает из кеша и не отстает достаточно далеко, чтобы его можно было извлечь с диска.

кн.
источник
3
На самом деле он работает довольно хорошо, он выглядит ограниченным из-за способности процессора обрабатывать md5 (~ 280 МБ / с на одно ядро).
wazoox
4

Вот пример скрипта Python. Он вычисляет контрольную сумму файла по мере его добавления в архив. В конце скрипта файл контрольной суммы добавляется в архив.

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

Когда вы распаковываете файл, используйте chksum_file для проверки контрольной суммы.

user37841
источник
1
Да, я думал об этом примерно так, но обычно библиотеки такого типа загружают файл в ОЗУ, прежде чем манипулировать им, и мои файлы имеют
размер
1

Я думаю, что ваша проблема - это проблема разработки tar, так как tar не допускает произвольного доступа / позиционирования внутри файла архива через таблицу содержимого, поэтому все протоколы будут файловыми, а не на основе буфера.
Таким образом, вы можете посмотреть на различные форматы, такие как PAX или DAR, которые разрешают произвольный доступ.

weismat
источник
1
К сожалению, вывод tar является обязательным, потому что это то, на чем основан рабочий процесс.
wazoox
0

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

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

В 7zip есть несколько опций, например, 7z hс пользовательским хешем и 7z l -sltсписком всех хешей и еще много чего, но что, если вы хотите получить список хешей md5 или sha1? Вы можете использовать -bbи-bs для контроля многословия и повторно использовать метод Джорджа Нотараса, упомянутый в принятом ответе:

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
источник