【问题标题】:Detecting Modified Files from Linux User Space从 Linux 用户空间检测修改的文件
【发布时间】:2011-11-10 01:44:21
【问题描述】:

我需要在 Linux 系统上生成自上次列表生成以来修改文件的列表。我需要在用户空间执行此操作,因此 FAM 之类的解决方案不适合我。为此,我有以下一些限制:

  1. 目标解决方案可用于ext2ext3 文件系统。
  2. 必须在用户空间实现,不允许修改内核或模块。
  3. 不得依赖于文件修改时间。它应该至少使用文件大小,或者更好的校验和算法来生成delta
  4. 不必是实时的,它会定期运行(例如每 10 分钟)。

有人知道这个任务已经实施的解决方案吗?为此,我尝试使用rsync,但似乎rsync 需要所有文件的副本来计算差异。

编辑

基本上,我需要一种机制,可以在给定目录下递归生成文件列表及其增量,并与之前的文件进行比较。它可以使用文件大小来产生差异,或者更好地使用差异算法(类似于rsync algorithm)。但是,像 MD5 和 SHA1 这样的加密哈希算法不适合我,因为它们的性能。请不要说我有成千上万的文件,这不是加密案例。

实时解决方案或需要更改内核的解决方案(如inotifykqueueFAMFuse)也不适合我。

谢谢。

【问题讨论】:

  • rsync 有-n 切换到假运行命令
  • @sputnick 即使使用-n 开关,它是否也会为未来的运行存储差异?
  • 我添加了一个可以帮助你的 Python 脚本。它也该死的快。如果您有挂载点,您可能希望将它们过滤掉以避免遍历 f.e. /proc.
  • @hochl 我正在尝试您的脚本并将提供反馈。非常感谢您的努力。

标签: linux filesystems rsync


【解决方案1】:
  • 您可以使用inotify 工具来监控文件系统。没有把握 如果有工具已经可以做到这一点,但快速搜索会提供很多结果,例如https://github.com/rvoicilas/inotify-tools/wiki/
  • 你可以使用md5sum来做 这个:

    find / -xdev -type f -print0 | xargs -0 md5sum -b >> /tmp/sums.txt

    现在您可以对这些文件进行排序并比较它们以检测 区别:

    sort -k 2 < /tmp/sums.txt > /tmp/sums.sorted.txt

    我想你明白了,但是这当然需要很多时间,因为你正在校验所有数据。

编辑:我编写了一个快速脚本,用于转储文件系统树,将文件大小附加到文件名。您可以使用diff 比较两次运行的输出以确定发生了什么变化。当然这只是一个草图,可以改进。

#!/usr/bin/env python

import os
import sys

# initialize variables.
entries=[]
if len(sys.argv) > 1:
        rootdir=os.path.normpath(sys.argv[1])
else:
        rootdir=os.curdir

# walk filesystem tree.
for root, dirs, files in os.walk(rootdir):
        for name in sorted(files):
                fullname=os.path.normpath(os.path.join(root, name))
                if os.path.islink(fullname) or not os.path.isfile(fullname):
                        entries.append(fullname)
                else:
                        st=os.stat(fullname)
                        entries.append("%s %d" % (fullname, st.st_size))
        for name in sorted(dirs):
                entries.append(os.path.normpath(os.path.join(root, name)))

# print sorted list of found filesystem entries.
for entry in sorted(entries):
        print entry

这对你有帮助吗?

建议的改进:

  • 检查目录是否为挂载点,并将其排除在遍历之外。
  • 在转储前添加类型字母,例如 f blub 6d test,以查找更改的文件类型。
  • st_mtime/st_atime/st_ctime 附加到文件以根据时间检测文件更改。
  • 附加文件的第一个和最后 1024 个字节的 md5 和,以检测最常见的更改(例如,如果文件获得附加数据)。
  • 在文件内容上附加完整的校验和,例如 CRC32。

我希望这些建议可以帮助您创建一个很酷的工具 ;-)

【讨论】:

  • 亲爱的 hochl, 像 inotify(和其他一些)这样的事件队列算法可能不适合我,因为出于性能原因我不需要实时解决方案。至于校验和,基本上我需要类似的,但更有效的方式。对大量文件和文件夹使用 MD5 可能不合适,因为 MD5 是一种加密哈希算法。虽然对于他们自己的工作来说速度非常快,但对于文件差异来说却是缓慢的一面。
  • 亲爱的 hoch,感谢您的努力,但这只是在目录下递归生成文件列表及其大小。我需要一个完整且高效的系统来生成和维护(存储、比较、区分等)更改。这对于生成列表来说很快,因为这些命令已经由操作系统提供。存储简单的原始文件列表并将它们与diff 进行比较可能不够快。可能需要使用正确索引的文件来存储文件信息。但是,我将使用您的解决方案并接受您的答案,直到其他人提供更好的答案。谢谢。
  • @EmreYazıcı:不幸的是,您不能再更改接受的答案(5 分钟是确定接受的时间窗口)
  • 是和否,如果我编辑我的回复,我认为他可以......所以如果你找到更好的答案,我可以修改一些东西。
【解决方案2】:

如果您对每次运行都重新计算每个文件的校验和感到满意,您可以使用简单的解决方案:

 find / ( -not -path '/tmp/*' -and -type f ) -print0 | xargs -0 md5sum > /tmp/current-listing
 diff /tmp/old-listing /tmp/current-listing
 mv /tmp/current-listing /tmp/old-listing

【讨论】:

  • 亲爱的 thiton,我不能接受为每次运行生成校验和,因为我有很多文件和文件夹。此外,在这种情况下(非加密)使用 MD5 作为校验和算法可能不合适,因为它对于文件差异算法来说相对较慢。您的解决方案绝对适用于其他一些情况。谢谢。
【解决方案3】:

你可以看看

  • 绊线
  • 猎手
  • rsync(但您必须有参考副本)

rdiffbackup 和 rsnapshot 是基于 rsync 的成熟增量(增量)备份解决方案。

你可能在 zfs-fuse 或zfsonlinux 中也有很多用处。这些文件系统支持连续快照:

 SNAPID=$RANDOM # something unique, please
 zfs snapshot tank/volume_of_mount@$SNAPID
 zfs send -i tank/volume_or_mount@previous tank/volume_of_mount@$SNAPID |
     pbzip2 > dumpfile.$SNAPID.bz2

接收端:

 zfs receive -vFdn tank2/into_this@$SNAPID < dumpfile.$SNAPID.bz2

这种快照可以即时、实时地完成并且性能非常好,因为 ZFS 是一个日志结构的文件系统,具有内置的基于 merkel-tree 的完整性检查。

【讨论】:

  • 亲爱的 sehe,我不是在寻找备份解决方案。类似 Fuse 的解决方案需要修改内核,这违反了我的一些限制。
  • @EmreYazıcı:我希望这并不意味着你忽略了tripwire 和rkhunter。阅读您的额外 cmets,我得到强烈的印象,即tripwire 正是您正在寻找的东西。 (ZFS 只是 碰巧 有我的偏好 - 但我的回答很笼统,并提到了许多适合不同目标的好工具,而不仅仅是备份。你会发现我什至没有提到备份,直到在项目符号列表之后。)
  • 如果你放弃 ext2/3 的要求,你可以使用 btrfs 的版本控制功能 ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 2017-04-17
  • 1970-01-01
  • 2011-11-15
  • 2011-12-14
  • 2017-03-30
  • 1970-01-01
相关资源
最近更新 更多