proc文件系统是一种无存储的文件系统,当读其中的文件时,其内容动态生成,当写文件时,文件所关联的写函数被调用。每个proc文件都关联的字节特定的读写函数,因而它提供了另外的一种和内核通信的机制:内核部件可以通过该文件系统向用户空间提供接口来提供查询信息、修改软件行为,因而它是一种比较重要的特殊文件系统。
由于proc文件系统以文件的形式向用户空间提供了访问接口,这些接口可以用于在运行时获取相关部件的信息或者修改部件的行为,因而它是非常方便的一个接口。内核中大量使用了该文件系统。proc文件系统就是一个文件系统,它可以挂载在目录树的任意位置,不过通常挂载在/proc下,它大致包含了如下信息:
内存管理
每个进程的相关信息
文件系统
设备驱动程序
系统总线
电源管理
终端
系统控制参数
网络
使用proc文件系统之前必须将其初始化并且挂载到系统中。proc文件系统的的初始化主要完成:
调用proc_init_inodecache创建proc文件系统所使用的专用缓冲区
调用register_filesystem注册proc文件系统,这里会提供proc文件系统自己的file_system_type,其中包括了用于mount的函数指针。在执行mount的时候会用到这些信息,并最终找到mount函数进行挂载操作
调用proc_mkdir创建一些proc文件目录
在sys文件系统下注册proc文件系统的相关信息
在proc的mount函数中会调用proc_fill_super,它会给出proc文件系统超级块所需要的信息(比如文件系统的超级块操作函数指针,超级块大小等),并且会创建proc文件系统的根目录,在创建根目录时也会指定与之对应的inode_operations和file_operations,有了这些信息后,VFS就可以在该文件系统上进行各种操作了(创建、删除、查找文件)。
文件操作的过程基本都是类似的,首先VFS会找到文件对应的inode,然后调用inode上的相关函数完成对应的操作,比如当读写一个文件时,要执行的步骤:
首先要打开文件,对于proc文件系统来说,它要做的是:找到文件的,在找到文件后文件数据结构的的file_operations会被初始化为文件的inode中的file_operations(参考路径do_filp_open->path_openat->do_last->nameidata_to_filp->__dentry_open->fops_get)。之后就可以调用文件的打开操作了。
写文件,这一步也很简单, 文件数据结构中的写操作即可。
这个过程也很好理解, 因为对于任何文件系统,它们都存在inode,inode被用来表示一个文件,它包含了很多有用的信息,它用于维护文件自身而不涉及文件的内容。对于存储在存储器上的文件系统,其inode的有些信息是保存在存储器上的,但是仍有一部分是动态生成的;对于无存储器的文件系统,比如proc文件系统,其inode都是动态生成的。再使用一个文件时,其inode就会被加载到内存中以供使用,如果还不存在相关的inode,则就会创建一个新的。每个文件系统的超级块的super_operations包含了为本文件系统创建和删除inode节点的函数指针,在inode的操作函数集中包含了操作inode节点的函数指针,其中包括了查找inode节点的函数。打开一个文件时,如果inode缓冲中还没有该文件的inode,则经VFS处理后最终会调用lookup_real,它会调用inode操作函数集中的lookup函数用于查找所要打开的文件的inode;如果该文件的inode已经存在则会从缓存中得到该文件对应的inode,这部分工作由do_lookup完成。
简单的说,文件操作第一步时找到inode信息(如果没有就创建并初始化),然后用inode信息初始化文件的file结构。再用file结构对文件进行操作。
加载 proc 文件系统
如果系统中还没有加载 proc 文件系统,可以通过如下命令加载 proc 文件系统:
mount -t proc proc /proc
上述命令将成功加载你的 proc 文件系统。更多细节请阅读 mount 命令的 man page。
察看 /proc 的文件
/proc 的文件可以用于访问有关内核的状态、计算机的属性、正在运行的进程的 状态等信息。大部分 /proc 中的文件和目录提供系统物理环境最新的信息。尽管 /proc 中的文件是虚拟的,但它们仍可以使用任何文件编辑器或像’more’, ‘less’或 ‘cat’这样的程序来查看。当编辑程序试图打开一个虚拟文件时,这个文件就通过内核 中的信息被凭空地 (on the fly) 创建了。这是一些我从我的系统中得到的一些有趣 结果:
$ ls -l /proc/cpuinfo
-r–r–r– 1 root root 0 Dec 25 11:01 /proc/cpuinfo
得到有用的系统/内核信息
proc 文件系统可以被用于收集有用的关于系统和运行中的内核的信息。下面是一些重要 的文件:
/proc/cpuinfo - CPU 的信息 (型号, 家族, 缓存大小等)
/proc/meminfo - 物理内存、交换空间等的信息
/proc/mounts - 已加载的文件系统的列表
/proc/devices - 可用设备的列表
/proc/filesystems - 被支持的文件系统
/proc/modules - 已加载的模块
/proc/version - 内核版本
/proc/cmdline - 系统启动时输入的内核命令行参数
proc 中的文件远不止上面列出的这么多。想要进一步了解的读者可以对 /proc 的每一个 文件都’more’一下或读参考文献[1]获取更多的有关 /proc 目录中的文件的信息。我建议 使用’more’而不是’cat’,除非你知道这个文件很小,因为有些文件 (比如 kcore) 可能 会非常长。
有关运行中的进程的信息
/proc 文件系统可以用于获取运行中的进程的信息。在 /proc 中有一些编号的子目录。每个编号的目录对应一个进程 id (PID)。这样,每一个运行中的进程 /proc 中都有一个用它的 PID 命名的目录。这些子目录中包含可以提供有关进程的状态和环境的重要细节信息的文件。让我们试着查找一个运行中的进程。
$ ps -aef | grep mozilla
root 32558 32425 8 22:53 pts/1 00:01:23 /usr/bin/mozilla
上述命令显示有一个正在运行的 mozilla 进程的 PID 是 32558。相对应的,/proc 中应该有一个名叫 32558 的目录
通过 /proc 与内核交互
上面讨论的大部分 /proc 的文件是只读的。而实际上 /proc 文件系统通过 /proc 中可读写的文件提供了对内核的交互机制。写这些文件可以改变内核 的状态,因而要慎重改动这些文件。/proc/sys 目录存放所有可读写的文件 的目录,可以被用于改变内核行为。
/proc/sys/kernel - 这个目录包含反通用内核行为的信息。 /proc/sys/kernel/{domainname, hostname} 存放着机器/网络的域名和主机名。 这些文件可以用于修改这些名字。
$ hostname
machinename.domainname.com