创建包含校验和的 tar 文件

创建包含校验和的 tar 文件

这是我的问题:我需要将大量(最多 60 TB)大文件(通常每个 30 到 40 GB)归档到 tar 文件中。我想在归档之前对这些文件进行校验(md5、sha1 等);但是不是读取每个文件两次(一次用于计算校验和,两次用于打包)或多或少是实现非常高的归档性能的必要条件(LTO-4 需要持续 120 MB/s,并且备份窗口是有限的)。

因此,我需要某种方式来读取文件,一方面提供校验和工具,另一方面构建 tar 到磁带,如下所示:

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

除了我不想要整个档案的校验和(此示例 shell 代码仅执行此操作)而是想要档案中每个单独文件的校验和之外。

我研究过 GNU tar、Pax、Star 选项。我查看了存档::Tar。我看不出有什么明显的方法可以实现这一点。看来我必须用 C 或类似语言手动构建一些东西才能实现我需要的东西。Perl/Python/etc 根本无法在性能方面胜任,而且各种 tar 程序都缺少必要的“插件架构”。在我开始编写代码之前,有人知道任何现有的解决方案吗?

答案1

在继续重写 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 磁盘缓存应该使第二次读取成为从内存缓冲区进行的简单读取,这实际上不应该比 stdin 读取慢。您只需确保磁盘缓存中有足够的空间来存储每个文件的足够内容,以便第二个读取器始终从缓存中读取,而不会落后太多而不得不从磁盘检索

答案2

这是一个示例 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 来验证校验和

答案3

我认为您的问题是 tar 的设计问题,因为 tar 不允许通过内容表在存档文件内进行随机访问/定位,因此所有协议都将基于文件而不是缓冲区。
因此,您可以查看允许随机访问的不同格式,如 PAX 或 DAR。

答案4

最近的档案格式通常包含一些用于文件验证的哈希值,但它们有一个类似的问题:您不能总是选择自己的哈希函数,也不能保留哈希值的本地副本。

您可能想要保存哈希值的本地副本,不同于档案本身中嵌入的哈希值:例如,如果档案是离线存储的(在磁带或数据中心,读取成本很高),并且您想要验证文件/目录的本地副本。

7zip有多种选择,例如7z h使用自定义哈希7z l -slt列出所有哈希值和其他东西,但如果你想要一个 md5 或 sha1 哈希值列表怎么办?你可以使用-bb-bs控制详细程度并重用接受答案中提到的 George Notaras 方法:

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

相关内容