Назад | Перейти на главную страницу

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

Вот моя проблема: мне нужно заархивировать в 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 не имеют необходимой «архитектуры плагинов». Кто-нибудь знает о каком-либо существующем решении этой проблемы, прежде чем я начну взбивать код?

Перед тем, как продолжить и переписывать 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 должно сделать это второе чтение простым чтением из буфера памяти, что на самом деле не должно быть медленнее, чем чтение стандартного ввода. Вам просто нужно убедиться, что у вас достаточно места в кеше диска для хранения достаточного количества каждого файла, который второй читатель всегда читает из кеша и не отстает достаточно далеко, чтобы его нужно было извлекать с диска.

Вот пример скрипта 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 для проверки контрольной суммы

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

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

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

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