判断路径是否存在 - 创建目录c++




解析/ proc/file是否安全? (5)

我想解析/proc/net/tcp/ ,但是安全吗?

我应该如何从/proc/打开和读取文件,而不用担心,某个其他进程(或操作系统本身)会在同一时间更改它?


/ proc是一个虚拟文件系统:实际上,它只是给出了内核内部的便捷视图。 阅读它是绝对安全的(这就是为什么它在这里),但从长远来看这是有风险的,因为这些虚拟文件的内部可能会随着更新版本的内核而发展。

编辑

在Linux内核文档的第1.4章的proc文档中提供了更多信息。网络我找不到信息是如何随着时间的推移而发展的。 我认为它是公开冻结的,但不能有明确的答案。

EDIT2

根据Sco文档 (不是Linux,但我很确定* nix的所有风格都是这样的)

尽管进程状态和/ proc文件的内容可以从瞬间变为瞬时,但是/ proc文件的单个读(2)保证返回一个“健全”的状态表示,也就是读取进程状态的原子快照。 没有这样的保证适用于应用于正在运行的进程的/ proc文件的连续读取。 另外,对于应用于as(地址空间)文件的任何I / O,原子性并不能保证; 任何进程的地址空间的内容可能会由该进程的LWP或系统中的任何其他进程同时修改。


Linux内核中的procfs API提供了一个接口来确保读取返回一致的数据。 阅读__proc_file_read的注释。 项目1)在大注释块中解释了这个接口。

这就是说,当然要执行特定的proc文件才能正确使用该接口,以确保其返回的数据是一致的。 所以,要回答你的问题:不,内核不保证读取过程中proc文件的一致性,但它提供了实现这些文件以提供一致性的手段。


因为我在嵌入式ARM目标上进行驱动程序开发,所以我有Linux 2.6.27.8的源代码。

例如,第934行的文件linux-2.6.27.8-lpc32xx/net/ipv4/raw.c包含例如

    seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
            " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
            i, src, srcp, dest, destp, sp->sk_state,
            atomic_read(&sp->sk_wmem_alloc),
            atomic_read(&sp->sk_rmem_alloc),
            0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
            atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));

哪个输出

[[email protected] ~]$ cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 017AA8C0:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 15160 1 f552de00 299
   1: 00000000:C775 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13237 1 f552ca00 299
...

在函数raw_sock_seq_show() ,它是procfs处理函数层次结构的一部分。 只有在/proc/net/tcp文件发出read()请求之后才会生成文本,这是一种合理的机制,因为procfs读取肯定比更新信息要少得多。

一些驱动程序(例如我的)使用一个sprintf()实现proc_read函数。 核心驱动程序实现中的额外复杂因素是处理可能非常长的输出,这可能不适合在单次读取期间的中间内核空间缓冲区。

我用一个使用64K读取缓冲区的程序测试了它,但是它在我的系统中产生了3072字节的内核空间缓冲区,以便proc_read返回数据。 需要带前进指针的多个调用才能获得更多的返回文本。 我不知道在需要多个I / O时使返回的数据保持一致的正确方法。 当然, /proc/net/tcp每个条目都是自我一致的。 在不同的时间,并排线有可能是快照。


当你从/ proc文件中读取内核时,内核正在调用一个预先注册的函数,作为该proc文件的“读取”函数。 请参阅fs / proc / generic.c中的__proc_file_read函数。

因此,proc读取的安全性与内核调用以满足读取请求的函数一样安全。 如果该函数正确地锁定了所有接触到的数据并返回给缓冲区,那么使用该函数进行读取是完全安全的。 由于用于满足对/ proc / net / tcp的读取请求所使用的proc文件已经存在了一段时间,并且经过了严格的审查,所以它们的安全性可以满足您的要求。 实际上,许多常见的Linux实用程序都依赖从proc文件系统读取数据,并以不同的方式格式化输出。 (关于我的头顶,我认为'ps'和'netstat'会这样做)。

与往常一样,你不必为此而接受我的话; 你可以看看消息来源来平息你的恐惧。 以下来自proc_net_tcp.txt的文档告诉你/ proc / net / tcp的“读取”功能在哪里,因此您可以查看从该proc文件读取时运行的实际代码,并确认自己没有锁定危险。

本文档描述了interfaces / proc / net / tcp和/ proc / net / tcp6。
请注意,这些接口已弃用,以支持tcp_diag。 这些/ proc接口提供有关当前活动TCP连接的信息,并分别通过net / ipv4 / tcp_ipv4.c中的tcp4_seq_show()和net / ipv6 / tcp_ipv6.c中的tcp6_seq_show()实现。


虽然/proc文件在用户空间中显示为常规文件,但它们不是真正的文件,而是支持用户空间( openreadclose )的标准文件操作的实体。 请注意,这与在内核中更改磁盘上的普通文件完全不同。

所有内核都使用类似sprintf的函数将其内部状态打印到其自己的内存中,并且只要发出read(2)系统调用,该内存就会复制到用户空间中。

内核以与普通文件完全不同的方式处理这些调用,这可能意味着在open(2)它时,您将读取的数据的整个快照可能已准备就绪,而内核确保并发调用是一致和原子。 我没有在任何地方阅读过,但其他地方没有任何意义。

我的建议是看看你的特定Unix风格中的proc文件的实现。 这实际上是一个实施问题(如输出的格式和内容)不受标准支配。

最简单的例子就是在Linux中执行uptime proc文件。 请注意整个缓冲区是如何在提供给single_open的回调函数中生成的。







procfs