如何在文件系统中找到循环?

时间:2009-03-22 19:28:34

标签: c linux

如何在Linux中找到文件系统中的循环?我正在为快速搜索所有文件编制索引(O(1))...我正在使用c编程语言来实现dir.h中的库函数....我可以扫描整个文件系统但它进入一个循环,如果文件系统中有循环(示例循环安装)...如何在文件系统中找到循环..我已经看到当文件系统中有循环时updatedb命令报告...我不明白逻辑......任何人都可以帮忙找到解决方案吗?

7 个答案:

答案 0 :(得分:5)

阻止在图中重新扫描节点的一般方法是在传递节点时标记节点,然后忽略标记的节点。如果您不想修改要扫描的图形,这不是非常实用,因此您需要一种在外部标记节点的方法。我能想到在linux下执行此操作的最简单方法是为您访问的每个目录存储device / inode。然后,当您查看目录时,首先检查您是否还没有看到具有相同设备/ inode的任何目录。这不仅可以处理循环,还可以处理彼此合并的树。

要获取设备/ inode编号,请查看stat / fstat函数以及stat结构的st_dev和st_ino成员。

为了存储数据,您可能想要查看hash-table或二叉树。

答案 1 :(得分:2)

顺便说一下。您不需要在文件系统中搜索循环。

您正在索引整个磁盘。所以你不需要遵循符号链接,因为每个文件必须以正常方式访问(没有符号链接)。如果某个磁盘安装了多次,你只需要检查挂载点,只需忽略挂载的其余点即可。

答案 2 :(得分:1)

我在这里找到了关于finding loops in a DAG的有趣评论:

  

Steinar H. Gunderson写道:

     
    

2004年2月26日星期四00:28:32 +0100,Orlondow写道:

         
      

...也在Cormen-Leiserson-Rivest,IIC上复制。这是       最简单的       找到。

    
         

是的,我实际上有Cormen等人,但它从来没有让我感到震惊     当我想要循环检测时,“强连接组件”。谢谢,我会的     看看它。 : - )

  
     

在有向图中查找循环   (你不关心哪个周期)   因为存在一个,你不需要   与SCC一起过火。平原旧的深度   首先搜索DFS(在同一章节中   (CLRS)就足够了。

因此,粗略地说,当您遍历目录树时,创建一个DAG,它表示树的结构,节点处的数据引用文件的inode。然后,您只需检查以确保您不会多次访问节点。

答案 3 :(得分:1)

也许我在这里有点昏暗但不是你创造一个循环的两种方式:

  • 创建符号链接
  • 装两次

要处理这些问题,您可以在开始编制索引之前获取一个安装列表,并且除了第一个相同的f之外的所有内容都可以获得,并且您可以在索引过程中忽略链接。

答案 4 :(得分:1)

简单的方法。只需对目录树进行深度优先的树遍历,随时随地保留一堆节点。在您访问的每个节点上,如果该节点已经在堆栈中,则您有一个循环。

 // here's a stack of nodes
node stack[1000];

walk(node, level){
    if (node in stack[0..level-1]) then there is a cycle
    else
        stack[level] = node
        for each subnode x of node
            walk(x, level+1)
}

答案 5 :(得分:1)

正如其他人所说,如果你意识到路径是文件名的一部分,除非它是一个循环的符号链接,否则文件系统中没有循环这样的东西。

例如,如果你将一些发行版(比如Debian)引导到循环设备,甚至引导到一个目录,并在Debian机器上执行此操作,那么你现在已经复制了很多东西。

例如,假设你正在运行Debian Lenny,并将它的最小副本引导到/ lenny。

/ lenny / usr / *将与/ usr / *相同。没有“廉价”的方法来避免这种情况。

由于你已经在每个节点上调用了stat()(我假设你正在使用ftw()/ ftw64(),你也可以这样做:

  • 让ftw()的回调将节点的名称插入到数组中,该数组具有可以存储不太可能发生冲突的文件的哈希的结构成员。 md5不会为此而削减它。
  • 根据摘要和文件名(不是路径)更新哈希表。

这没有加快扫描速度的危险,但它会大大减少搜索所需的时间。

如果正确使用线程并设置了亲和性,则散列和索引可以在一个核心上发生,而另一个核心是i / o绑定(当多个核心可用时)。

然而,'只是'检查重复的安装是不可能的,另外我确定你的程序会想要返回所有名为'foo'的文件的位置,即使有四个相同的副本要提及

答案 6 :(得分:0)

这通常被称为“循环”。所以你想实现“循环检测”。有很多方法可以做到这一点;我不知道这是否适合家庭工作但是一个简单的,不一定是最优的方法是通过指针追逐。