Linux proc虚拟文件系统
文章目录
- 简介
- proc常用节点
- pid节点
- procfs接口
- 参考
简介
测试环境:Linux dev-PC 5.18.17-amd64-desktop-hwe #20.01.00.10 SMP PREEMPT_DYNAMIC Thu Jun 15 16:17:50 CST 2023 x86_64 GNU/Linux
proc虚拟文件系统是linux内核提供的一种让用户和内核内部数据结构进行交互的机制。
proc文件系统并不是真正意义上的文件系统,它存在于内存中,并不占用磁盘空间。它包含一些结构化的目录和虚拟文件,向用户呈现内核中的一些信息,也可以作为一种从用户空间向内核发送信息的手段。许多shell命令如ps、top等都是从proc文件系统中读取信息。
在测试环境中,proc文件系统挂载信息如下
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
proc下面的内容:
$ ls /proc
1 1150 1272 1801 25 2708 2855 3257 3489 41 5242 6236 7594 87 acpi fb loadavg slabinfo
10 1151 13 1895 2507 2710 2871 3293 3492 42 5247 6454 76 88 asound filesystems locks softirqs
100 116 14 19 2508 2726 2874 3295 3493 43 5258 6504 7615 89 buddyinfo fs mdstat stat
101 1160 1408 2 2511 275 2898 33 3524 44 5261 6560 7642 9 bus interrupts meminfo swaps
1016 1184 1428 20 2512 276 2904 3331 353 45 5262 6625 7692 90 cgroups iomem misc sys
102 12 1471 2080 2515 2794 3 3346 3534 46 5277 7 77 91 cmdline ioports modules sysrq-trigger
103 1203 1476 21 2581 2796 30 3390 3540 48 53 7035 78 92 consoles irq mounts sysvipc
107 1209 15 22 26 2798 31 3397 3547 49 54 7053 79 93 cpuinfo kallsyms mtrr thread-self
108 1213 1516 229 2632 28 3104 34 36 5 55 72 80 94 crypto kcore net timer_list
11 1218 1595 2395 2673 2803 3125 340 37 50 558 73 81 95 devices keys pagetypeinfo tty
110 122 16 24 2674 2810 32 3419 38 5099 56 74 82 96 diskstats key-users partitions uptime
111 1222 1601 2460 2687 2821 3233 3476 386 51 57 7475 83 97 dma kmsg pressure version
1124 1227 169 2461 2696 2833 3244 3478 39 516 59 7478 84 978 driver kpagecgroup schedstat vmallocinfo
1132 1229 170 2477 2697 2847 3249 3484 4 517 60 7484 85 98 dynamic_debug kpagecount scsi vmstat
1143 123 18 2488 27 2854 3253 3485 40 52 61 75 86 99 execdomains kpageflags self zoneinfo
proc常用节点
- cpuinfo:CPU信息
- meminfo:内存信息
- mounts:加载的文件系统
- filesystems:支持的文件系统
- modules:已加载的模块
- cmdline:系统启动的内核命令行参数
<pid>
:提供pid进程的信息- interrupts:中断使用情况
- kmsg:内核日志信息
- devices:可用的设备
- slabinfo:slab系统统计信息
- uptime:系统正常运行时间
pid节点
sudo ls /proc/5261 -lh
总用量 0
-r--r--r-- 1 root root 0 2月 9 11:57 arch_status
dr-xr-xr-x 2 dev dev 0 2月 9 11:57 attr
-r-------- 1 root root 0 2月 9 11:57 auxv
-r--r--r-- 1 root root 0 2月 9 11:57 cgroup
--w------- 1 root root 0 2月 9 11:57 clear_refs
-r--r--r-- 1 root root 0 2月 9 11:39 cmdline
-rw-r--r-- 1 root root 0 2月 9 11:57 comm
-rw-r--r-- 1 root root 0 2月 9 11:57 coredump_filter
-r--r--r-- 1 root root 0 2月 9 11:57 cpu_resctrl_groups
lrwxrwxrwx 1 root root 0 2月 9 11:57 cwd -> /
-r-------- 1 root root 0 2月 9 11:57 environ
lrwxrwxrwx 1 root root 0 2月 9 11:38 exe -> /usr/sbin/sshd
dr-x------ 2 root root 0 2月 9 11:57 fd
dr-xr-xr-x 2 dev dev 0 2月 9 11:57 fdinfo
-rw-r--r-- 1 root root 0 2月 9 11:57 gid_map
-r-------- 1 root root 0 2月 9 11:57 io
-r--r--r-- 1 root root 0 2月 9 11:57 limits
-rw-r--r-- 1 root root 0 2月 9 11:57 loginuid
dr-x------ 2 root root 0 2月 9 11:57 map_files
-r--r--r-- 1 root root 0 2月 9 11:57 maps
-rw------- 1 root root 0 2月 9 11:57 mem
-r--r--r-- 1 root root 0 2月 9 11:57 mountinfo
-r--r--r-- 1 root root 0 2月 9 11:57 mounts
-r-------- 1 root root 0 2月 9 11:57 mountstats
dr-xr-xr-x 60 dev dev 0 2月 9 11:57 net
dr-x--x--x 2 root root 0 2月 9 11:57 ns
-r--r--r-- 1 root root 0 2月 9 11:57 numa_maps
-rw-r--r-- 1 root root 0 2月 9 11:57 oom_adj
-r--r--r-- 1 root root 0 2月 9 11:57 oom_score
-rw-r--r-- 1 root root 0 2月 9 11:57 oom_score_adj
-r-------- 1 root root 0 2月 9 11:57 pagemap
-r-------- 1 root root 0 2月 9 11:57 patch_state
-r-------- 1 root root 0 2月 9 11:57 personality
-rw-r--r-- 1 root root 0 2月 9 11:57 projid_map
lrwxrwxrwx 1 root root 0 2月 9 11:57 root -> /
-rw-r--r-- 1 root root 0 2月 9 11:57 sched
-r--r--r-- 1 root root 0 2月 9 11:57 schedstat
-r--r--r-- 1 root root 0 2月 9 11:57 sessionid
-rw-r--r-- 1 root root 0 2月 9 11:57 setgroups
-r--r--r-- 1 root root 0 2月 9 11:57 smaps
-r--r--r-- 1 root root 0 2月 9 11:57 smaps_rollup
-r-------- 1 root root 0 2月 9 11:57 stack
-r--r--r-- 1 root root 0 2月 9 11:40 stat
-r--r--r-- 1 root root 0 2月 9 11:57 statm
-r--r--r-- 1 root root 0 2月 9 11:39 status
-r-------- 1 root root 0 2月 9 11:57 syscall
dr-xr-xr-x 3 dev dev 0 2月 9 11:57 task
-rw-r--r-- 1 root root 0 2月 9 11:57 timens_offsets
-r--r--r-- 1 root root 0 2月 9 11:57 timers
-rw-rw-rw- 1 root root 0 2月 9 11:57 timerslack_ns
-rw-r--r-- 1 root root 0 2月 9 11:57 uid_map
-r--r--r-- 1 root root 0 2月 9 11:57 wchan
常用信息:
- attr:安全相关属性
- cgroups:进程所属控制组
- cmdline:进程命令行参数
- environ:进程环境变量
- fd:一个包含所有进程打开的文件描述符目录
- mem:进程内存被使用情况
- stat:进程状态
- status:进程当前状态
- cwd:进程当前工作目录的链接
- exe:指向该进程的执行命令文件
- maps:内存映射信息
- statm:进程内存使用信息
- root:链接次进程的root目录
- oom_adj、oom_score、oom_score_adj:用于OOM killer
procfs接口
procfs文件系统提供了一些API供内核中其他模块使用,这些接口或定义在头文件中或通过EXPORT_SYMBOL直接导出,代码位置在fs/proc
文件夹下。
下面看下内核中misc驱动是如何使用procfs接口在proc文件系统下面创建和管理自己的节点的。
misc驱动代码位置在drivers/char/misc.c
直接看其的初始化入口:
static int __init misc_init(void)
{
int err;
struct proc_dir_entry *ret;
ret = proc_create_seq("misc", 0, NULL, &misc_seq_ops);
err = class_register(&misc_class);
if (err)
goto fail_remove;
err = -EIO;
if (register_chrdev(MISC_MAJOR, "misc", &misc_fops))
goto fail_printk;
return 0;
fail_printk:
pr_err("unable to get major %d for misc devices\n", MISC_MAJOR);
class_unregister(&misc_class);
fail_remove:
if (ret)
remove_proc_entry("misc", NULL);
return err;
}
一开始其就使用了proc_create_seq创建了一个名为misc的节点。
#define proc_create_seq(name, mode, parent, ops) \
proc_create_seq_private(name, mode, parent, ops, 0, NULL)
struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
struct proc_dir_entry *parent, const struct seq_operations *ops,
unsigned int state_size, void *data)
{
struct proc_dir_entry *p;
p = proc_create_reg(name, mode, &parent, data);
if (!p)
return NULL;
p->proc_ops = &proc_seq_ops;
p->seq_ops = ops;
p->state_size = state_size;
return proc_register(parent, p);
}
EXPORT_SYMBOL(proc_create_seq_private);
其中misc_seq_ops
是该文件节点的操作函数集,目前统一为seq_file机制:
static const struct seq_operations misc_seq_ops = {
.start = misc_seq_start,
.next = misc_seq_next,
.stop = misc_seq_stop,
.show = misc_seq_show,
};
关于seq_file机制,可以参考相关文档:The seq_file Interface、内核 seq_file 操作函数、linux内核seq_file接口
下面是读取misc节点:
$ cat /proc/misc
119 simple_virtualchardev
232 kvm
130 watchdog
235 autofs
234 btrfs-control
120 cpu_dma_latency
227 mcelog
121 vndbinder
122 hwbinder
123 binder
124 ashmem
236 device-mapper
223 uinput
1 psaux
196 vfio
200 tun
125 udmabuf
237 loop-control
228 hpet
229 fuse
126 ecryptfs
231 snapshot
183 hw_random
127 vga_arbiter
242 rfkill
参考
The /proc Filesystem
T H E /proc F I L E S Y S T E M
The seq_file Interface
内核 seq_file 操作函数
linux内核seq_file接口