内核proc文件系统与seq接口(1)---内核proc文件系统简介

1660阅读 0评论2016-07-14 chenmeng11
分类:LINUX

       /proc文件系统是一个特殊的由内核创建的文件系统,她仅存在于内存之中而不在外存(硬盘、flash)上。内核用她来向用户空间进程输出消息,可以说是内核向用户空间打开的一扇窗户。

      最初开发/proc文件系统是为提供一种内核及其模块向进程 (process) 发送信息的机制 (这就是proc名字的由来)。这个虚拟文件系统让你可以和内核内部数据结构进行交互,获取对于进程的有用信息,并可在运行时改变设置内核参数。后来,由于这个文件系统使用方便,内核中其余组件也开始用它来报告信息或实现动态配置。正由于proc文件系统在内核开发者看来有点混乱和失控,已经偏离了创造她的初衷,所以新内核模块代码中建议利用基于Linux设备模型的sysfs文件系统实现内核信息向用户空间的导出。例如模块参数,EXPORT_SYMBOL宏本身就会为你创建sysfs接口文件。

     /proc文件系统中的文件既可读也可写。但是, 大部分/proc 文件是只读的。这些完全看创建接口时使用的是内核API。/proc 下的每个文件的操作函数最后都映射一个内核函数上,当文件被读取的时候此函数负责实时产生文件内容(一般是内核结构体中的数据)返回给procfs,之后由procfs通过VFS返回给用户空间。

    比如平时我们通过lsmod命令列出当前已加载的模块列表,而这个命令就是通过/proc/modules获取信息的,只不过lsmod将信息显示得比较好看罢了:

  1. root@dm816x-evm:/proc# lsmod
  2. Module Size Used by
  3. bufferclass_ti 4950 0
  4. omaplfb 10806 0
  5. pvrsrvkm 155562 2 bufferclass_ti,omaplfb
  6. ti81xxhdmi 15565 0
  7. ti81xxvo 20207 0
  8. ti81xxfb 21979 2
  9. vpss 72562 4 omaplfb,ti81xxhdmi,ti81xxvo,ti81xxfb
  10. syslink 1116043 0
  11. ipv6 209863 12

  12. root@dm816x-evm:/proc# cat modules
  13. bufferclass_ti 4950 0 - Live 0xbf20b000
  14. omaplfb 10806 0 - Live 0xbf202000
  15. pvrsrvkm 155562 2 bufferclass_ti,omaplfb, Live 0xbf1cd000
  16. ti81xxhdmi 15565 0 - Live 0xbf1c3000
  17. ti81xxvo 20207 0 - Live 0xbf1b8000
  18. ti81xxfb 21979 2 - Live 0xbf1ac000
  19. vpss 72562 4 omaplfb,ti81xxhdmi,ti81xxvo,ti81xxfb, Live 0xbf18d000
  20. syslink 1116043 0 - Live 0xbf049000
  21. ipv6 209863 12 - Live 0xbf000000

    而/proc/modules所对应的proc实现函数位于kernel/module.c,其中的原理就是利用内核struct modules结构体的表头遍历内核模块链表,从所有模块的struct module结构体中获取模块的相关信息。从这个例子中我们就可以真实地体会到procfs就是和内核内部数据结构进行交互的窗口。

    除此之外,/proc 在 Linux 系统中还有非常多应用,很多Linux 用户空间工具,如 ps, top, 以及 uptime,都是从 /proc 中获取信息的,一些设备驱动也通过 /proc 输出信息。

下面是一些重要的文件,她们都是用于收集关于系统和运行中的内核的信息:

  1. /proc/cpuinfo - CPU 的信息 (型号, 构架, 缓存大小等)
  2. /proc/mounts - 已加载的文件系统的列表
  3. /proc/devices - 可用设备列表
  4. /proc/filesystems - 被支持的文件系统
  5. /proc/modules - 已加载的模块列表
  6. /proc/version - 内核版本字符串
  7. /proc/cmdline - 系统启动时输入的内核命令行参数
  8. /proc/config.gz - 内核配置压缩文件
  9. /proc/zoneinfo - 内存域信息
  10. /proc/buddyinfo - 伙伴系统信息
  11. /proc/slabinfo - slab分配器信息
  12. /proc/meminfo - 物理内存、交换空间等的信息
  13. /proc/vmstat - 虚拟内存的统计信息
  14. /proc/vmallocinfo - 虚拟地址分配映射信息
  15. /proc/iomem - IO内存映射信息
  16. /proc/ioports - IO端口映射信息
  17. /proc/softirqs - 内核软中断信息
  18. /proc/interrupts - 硬件中断信息
  19. /proc/kallsyms - 内核符号信息,主要用于调试
  20. /proc/kmsg - 内核日志接口文件
  21. /proc/sysrq-trigger - SysRq触发文件
  22. /proc/uptime - 系统上电启动时间和空闲时间统计
  23. /proc/partitions - 系统硬盘或flash分区信息
  24. /proc/stat - 内核和系统的统计信息
  25. /proc/mtd - MTD系统分区信息,主要在嵌入式系统中
  26. /proc/loadavg - 系统负载统计数据
  27. /proc/locks - 被内核锁定的文件
  28. /proc/timer_list - 内核各种计时器信息
  29. /proc/misc - 被注册文misc杂项设备的信息

    出此之外,其中还有一些子系统的目录也记录了一些内核信息,其中比较重要的是/proc/sys 目录。上面讨论的大部分 /proc 文件是只读的。而/proc/sys 目录存放几乎所有可读写的文件,实际上 /proc 文件系统就是通过这些可读写的文件提供了对内核的交互机制,可被用于改变内核行为和行为。

   /proc/sys/kernel - 这个目录包含通用内核行为的信息。如/proc/sys/kernel/{domainname, hostname} 存放着机器的网络域名和主机名,她们可以被修改;再比如其中的printk*文件,用于控制内核日志系统的行为。

   /proc/sys/net - 用于修改内核网络子系统的一些属性。比如让内核不响应其他主机发出的 ping 可以做如下操作:

  1. $ echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

/proc/sys/vm
- 用于修改内核内存管理子系统的相关配置

/proc/sys 下还有许多其它可以用于改变内核属性的文件。

    介绍了这么多的proc的文件用途,而创造她的初衷:用于获取对于进程的有用信息,这点还没有介绍。如果你执行ls /proc命令,你可以看到很多数字编号的目录。每个编号的目录都对应一个进程 id (PID),而每一个运行中的进程 在/proc 中都有一个用其 PID 命名的目录。这些子目录中包含可以提供有关进程的状态和环境的重要细节信息的文件。例如我们看看系统中都有的init进程(PID为1)的信息。
  1. root@dm816x-evm:/proc# cd 1
  2. root@dm816x-evm:/proc/1# ls -l
  3. dr-xr-xr-x 2 root root 0 Dec 9 16:38 attr
  4. -r-------- 1 root root 0 Dec 9 16:38 auxv
  5. --w------- 1 root root 0 Dec 9 16:38 clear_refs
  6. -r--r--r-- 1 root root 0 Dec 9 16:38 cmdline
  7. -rw-r--r-- 1 root root 0 Dec 9 16:38 comm
  8. -rw-r--r-- 1 root root 0 Dec 9 16:38 coredump_filter
  9. lrwxrwxrwx 1 root root 0 Dec 9 16:38 cwd -> /
  10. -r-------- 1 root root 0 Dec 9 16:38 environ
  11. lrwxrwxrwx 1 root root 0 Dec 9 16:38 exe -> /sbin/init.sysvinit
  12. dr-x------ 2 root root 0 Dec 9 16:38 fd
  13. dr-x------ 2 root root 0 Dec 9 16:38 fdinfo
  14. -r--r--r-- 1 root root 0 Dec 9 16:38 limits
  15. -r--r--r-- 1 root root 0 Dec 9 16:38 maps
  16. -rw------- 1 root root 0 Dec 9 16:38 mem
  17. -r--r--r-- 1 root root 0 Dec 9 16:38 mountinfo
  18. -r--r--r-- 1 root root 0 Dec 9 16:38 mounts
  19. -r-------- 1 root root 0 Dec 9 16:38 mountstats
  20. dr-xr-xr-x 7 root root 0 Dec 9 16:38 net
  21. -rw-r--r-- 1 root root 0 Dec 9 16:38 oom_adj
  22. -r--r--r-- 1 root root 0 Dec 9 16:38 oom_score
  23. -rw-r--r-- 1 root root 0 Dec 9 16:38 oom_score_adj
  24. -r-------- 1 root root 0 Dec 9 16:38 pagemap
  25. -r-------- 1 root root 0 Dec 9 16:38 personality
  26. lrwxrwxrwx 1 root root 0 Dec 9 16:38 root -> /
  27. -r--r--r-- 1 root root 0 Dec 9 16:38 smaps
  28. -r--r--r-- 1 root root 0 Dec 9 16:38 stat
  29. -r--r--r-- 1 root root 0 Dec 9 16:38 statm
  30. -r--r--r-- 1 root root 0 Dec 9 16:38 status
  31. dr-xr-xr-x 3 root root 0 Dec 9 16:38 task
  32. -r--r--r-- 1 root root 0 Dec 9 16:38 wchan
"cmdline" 包含启动进程时调用的命令行。
"envir" 进程的环境变量。
"status" 是进程的状态信息,包括启动进程的用户ID (UID) 和组ID(GID) 、父进程ID (PPID),以及进程当前的状态,比如"Sleelping"和"Running"。

每个进程的目录都有几个符号链接:
"cwd"是指向进程当前工作目录的符号链接,
"exe"指向运行的进程的可执行程序,
"root"指向被这个进程看作是根目录的目录 (通常是"/")。
目录"fd"包含指向进程使用的文件描述符的链接。

     而proc中还有一个子目录/proc/self ,它保存当前访问这个目录的进程自身的信息。/proc/self 是一个链接到 /proc 中访问 /proc 的进程所对应的 PID 的目录的符号链接。其实这个self目录中获取信息的procfs接口函数就是通过“current”宏来实现的。
上一篇:LVS原理详解及部署之二:LVS原理详解(3种工作方式8种调度算法)
下一篇:Linux内核中的seq操作