它是安全的解析的/ proc /文件? [英] Is it safe to parse a /proc/ file?

查看:150
本文介绍了它是安全的解析的/ proc /文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要解析的/ proc /净/ TCP / ,但它的安全?

I want to parse /proc/net/tcp/, but is it safe?

我应该如何打开和从的/ proc / 阅读文件,而不是害怕,是一些其他进程(或者操作系统本身)将在同一时间更改它?

How should I open and read files from /proc/ and not be afraid, that some other process (or the OS itself) will be changing it in the same time?

推荐答案

一般情况下,没有。(所以大部分的答案在这里是错误的)。它的可能的是安全,取决于你想要什么财产。但它很容易在你的code错误结束,如果你承担了太多有关文件的一致性的/ proc 。例如,请参见其中来自假设的/ proc /坐骑这个bug 是一个一致的快照

In general, no. (So most of the answers here are wrong.) It might be safe, depending on what property you want. But it's easy to end up with bugs in your code if you assume too much about the consistency of a file in /proc. For example, see this bug which came from assuming that /proc/mounts was a consistent snapshot.

例如:


  • 的/ proc /运行时间 完全原子,作为另一个答复中提到的人 - 但的只因为Linux 2.6.30 的,这是不到两岁。因此,即使这个小小的,微不足道的文件就规定了比赛状态,直到那时,仍然是大多数企业的内核。请参见 FS的/ proc / uptime.c 的电流源,或<一个href=\"http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=a9caa3de249a6c43bc9c6aec87881f09276677e3\">the提交,使得它的原子。在pre-2.6.30内核,可以打开文件,一点点吧,那么,如果你以后回来再次,这块你将与第一块不一致。 (我只是证明了这一点 - 尝试一下自己的乐趣。)

  • /proc/uptime is totally atomic, as someone mentioned in another answer -- but only since Linux 2.6.30, which is less than two years old. So even this tiny, trivial file was subject to a race condition until then, and still is in most enterprise kernels. See fs/proc/uptime.c for the current source, or the commit that made it atomic. On a pre-2.6.30 kernel, you can open the file, read a bit of it, then if you later come back and read again, the piece you get will be inconsistent with the first piece. (I just demonstrated this -- try it yourself for fun.)

的/ proc /坐骑 中单个原子系统调用。所以,如果你整个文件全部一次,你在系统上安装点的单一,一致的快照。但是,如果使用多个系统调用 - 如果文件很大,这正是会发生什么,如果你使用普通的I / O库和不支付特别注意这个问题 - 你将受到竞争条件。你不仅不会得到一致的快照,但安装该是present你开始之前,从来没有停止为present可能会去你所看到的失分。要看到,它的原子一阅读(),看的 M_START() FS / namespace.c 并把它抢信号灯守卫挂载点的列表,其中它保持直到 M_STOP(),这就是所谓的当阅读()已经完成了。看看有什么可以去错了,请参阅去年这个错误(同一台我联系以上),另有高品质的软件,它轻率地读的/ proc /坐骑

/proc/mounts is atomic within a single read system call. So if you read the whole file all at once, you get a single consistent snapshot of the mount points on the system. However, if you use several read system calls -- and if the file is big, this is exactly what will happen if you use normal I/O libraries and don't pay special attention to this issue -- you will be subject to a race condition. Not only will you not get a consistent snapshot, but mount points which were present before you started and never stopped being present might go missing in what you see. To see that it's atomic for one read(), look at m_start() in fs/namespace.c and see it grab a semaphore that guards the list of mountpoints, which it keeps until m_stop(), which is called when the read() is done. To see what can go wrong, see this bug from last year (same one I linked above) in otherwise high-quality software that blithely read /proc/mounts.

的/ proc /净/ TCP ,这是你实际上问的人,甚至比不太一致。它的的原子仅在表的每一行即可。看到这一点,看看 listening_get_next()网​​/支持IPv4 / tcp_ipv4.c established_get_next()只是在下方相同的文件,看他们拿出上依次每个条目的锁。我没有摄制code得心应手证明缺乏行与行的一致性,但没有锁存在(或其他任何东西),这将使它保持一致。这是有道理的,如果你仔细想想 - 网络往往是系统的一个超级繁忙的一部分,所以它是不值得的开销为present在这个诊断工具的一致视图

/proc/net/tcp, which is the one you're actually asking about, is even less consistent than that. It's atomic only within each row of the table. To see this, look at listening_get_next() in net/ipv4/tcp_ipv4.c and established_get_next() just below in the same file, and see the locks they take out on each entry in turn. I don't have repro code handy to demonstrate the lack of consistency from row to row, but there are no locks there (or anything else) that would make it consistent. Which makes sense if you think about it -- networking is often a super-busy part of the system, so it's not worth the overhead to present a consistent view in this diagnostic tool.

这保持了另一片的/ proc /净/ TCP 每一行中的原子在缓冲seq_read(),您可以在 FS / seq_file.c code> 。这样可以确保一旦阅读()一行的一部分,全行的文本保存在一个缓冲区,这样下一个阅读() 将开始一个新的人之前获得该行的其余部分。同样的机制在用的/ proc /坐骑,以保持各行,即使你做多的阅读()通话原子,并且它也是的/ proc /运行时间在新的内核使用留原子的机制。这种机制确实的的缓冲整个文件,因为内核是谨慎的内存使用。

The other piece that keeps /proc/net/tcp atomic within each row is the buffering in seq_read(), which you can read in fs/seq_file.c. This ensures that once you read() part of one row, the text of the whole row is kept in a buffer so that the next read() will get the rest of that row before starting a new one. The same mechanism is used in /proc/mounts to keep each row atomic even if you do multiple read() calls, and it's also the mechanism that /proc/uptime in newer kernels uses to stay atomic. That mechanism does not buffer the whole file, because the kernel is cautious about memory use.

的/ proc 大多数文件将至少为的/ proc /净/ TCP保持一致,每个排在他们提供的任何信息的一个条目的一致的画面,因为他们大多使用相同的 seq_file 抽象。由于的/ proc /运行时间的例子说明,虽然一些文件仍然被迁移到使用 seq_file ,最近在2009年;我打赌仍然有一些使用旧机制,并没有原子,甚至这一水平。这些警告很少记载。对于给定的文件,则只能保证阅读源。

Most files in /proc will be at least as consistent as /proc/net/tcp, with each row a consistent picture of one entry in whatever information they're providing, because most of them use the same seq_file abstraction. As the /proc/uptime example illustrates, though, some files were still being migrated to use seq_file as recently as 2009; I bet there are still some that use older mechanisms and don't have even that level of atomicity. These caveats are rarely documented. For a given file, your only guarantee is to read the source.

的/ proc /净/ TCP 的情况下,你可以阅读并分析每一行没有恐惧。但是,如果你尝试同时借鉴多行任何结论 - 当心,其他进程和内核的的改变它,而你读它,你可能创建一个错误

In the case of /proc/net/tcp, you can read it and parse each line without fear. But if you try to draw any conclusions from multiple lines at once -- beware, other processes and the kernel are changing it while you read it, and you are probably creating a bug.

这篇关于它是安全的解析的/ proc /文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆