【文件管理】特殊文件系统/proc

早期的Unix在设备文件目录/dev下设置了一个特殊文件,称为/dev/mem;通过这个文件可以读/写整个屋里内存,而物理内存的地址就用于读/写文件内部的位移量;这个特殊文件同样适用于read,write,lseek等文件操作,从而提供了一个在内核外部动态地读写包括内核映像和内核中各个数据结构以及堆栈内容的手段;采用了虚存以后,Unix又增加了一个特殊文件/dev/kmem,对应于系统的整个虚存空间;在系统中创建一个/proc目录,每当创建一个进程时,就以其pid为文件名在这个目录下建立一个特殊文件,使得通过这个文件就可以读写相应进程的用户空间,而当进程exit()则将文件删去;

(1)/proc中所有的文件都是特殊文件,这些文件的内容不存在与任何设备上,而是读写的时候根据系统中有关的信息生成出来的;现在这个系统的内容已经不局限于进程了,而是覆盖系统的所有方面,大体内容如下:

(1.1)以进程号pid为名的子目录,每个子目录包括关于该进程指向的命令行,所有环境变量,cpu占用时间,内存映射表,已打开文件的文件号,进程状态等特殊文件;

(1.2)系统中各种资源的管理信息,如/proc/slabinfo就是内存管理中关于各个slab缓冲队列的信息,/proc/swaps就是关于系统的swap设备信息,/proc/partitions就是关于各个磁盘分区的信息;

(1.3)系统中各个设备信息,如/proc/pci等;

(1.4)文件系统的信息,如/proc/mounts就是系统中已经安装的各个文件系统设备的清单,而/proc/filesystems则是系统中已经登记的每种文件系统类型的清单;

(1.5)中断的使用,/proc/interrupts是一份关于中断源和它们的中断向量编号的清单;

(1.6)与动态安装模块有关的信息,/proc/modules是一份系统中已安装动态模块的清单,而/proc/ksyms则是内核中供可安装模块动态连接的符号及其地址的清单;

(1.7)与前述/dev/mem类似的内存访问手段,如/proc/kcore;

(1.8)系统的版本号以及其他各种统计与状态信息;

(2)由于proc文件系统并不物理的存在于任何设备上,它的安装过程是特殊的,对/proc文件系统是不能直接通过mount()来安装的,而要先有系统内核在内核初始化时自动的通过kern_mount()安装一次,然后再由处理系统初始化的进程通过mount()安装,实际上“重安装”;

(3)在init_proc_fs()中,通过register_filesystem()向系统登记proc这么一种文件系统;然后通过kern_mount()将一个具体的proc文件系统安装到系统中的/proc节点上;

(3.1)在kern_mount()中,每一个已安装的文件系统都有一个super_block,尽管proc不实际存在于任何设备上,但也要有个设备号,因为super_block需要有个设备号唯一的标识,这是通过get_unnamed_dev()完成的,先通过read_super()分配一个空白的super_block,然后通过具体的文件系统的file_system_type()中函数指针read_super调用具体的函数来读入超级块;对于proc文件提供,这个函数就是proc_read_super()(实际是生成超级块,设置超级块的操作proc_sops),在proc文件系统中,inode结构也像super_block一样,在设备上并没有对应物,而仅仅是在内存中生成的,dentry在设备上也是没有对应物的,内存中是以proc_dir_entry代替;

(3.2)对于proc的文件系统的根节点,即/proc的目录项proc_root,是静态定义的,proc_iops指向proc_root_inode_operations,proc_fops指向proc_root_operations,parent指向其自己&proc_root;在proc_read_super()中,通过proc_get_inode()创建一个inode结构,根据union的部分,然后通过d_alloc_root()创建其dentry结构;然后通过add_vfsmnt()来增加安装点;

(3.3)在调用sys_mount()的主体do_mount()通过get_sb_single(),file_system_type中FS_SINGLE为1;在get_sb_single()中,代码通过file_system_type结构的指针kern_mnt取得文件系统vfsmount,从而可以对super_block访问;取得proc文件系统的super_block以后,此后的操作就与普通文件系统安装一样了,将proc文件爱你系统安装到/proc上;

(4)整个proc文件系统都不存在与设备上,所以不光是它的根节点在内存中创造出来,自根节点一下的所有节点都需要在运行时加以创建,这是由内核初始化时proc_root_init()完成的;

(4.1)在proc_root_init()中,首先调用proc_misc_init()来创建叶节点,即文件节点,即version,cpuinfo等细腻系,节点名都与一个函数挂钩,如节点/proc/cpuinfo就与cpuinfo_read_proc挂钩,当一个进程访问这个节点,要读出这个特殊文件的内容时,就由cpuinfo_read_proc()从内核中收集有关的信息并临时生成该文件的内容;所有的这样的函数都要通过create_proc_read_entry()为之建立起proc_dir_entry结构和inode结构,并且与节点/proc挂钩;在create_proc_read_entry()中,首先通过create_proc_entry()建立起有关的数据结构并创建proc_dir_entry结构中函数指针read_proc设置成相应的函数;

(4.1.1)在create_proc_entry()中,由于进入的parent为NULL,那就调用xlate_proc_name(),将传下来的节点名,如cpuinfo转换成/proc/cpuinfo,并且将指向节点proc的proc_dir_entry变为它的parent;使用proc_register将一个新的节点的proc_dir_entry登记到父节点的proc_dir_entry中(包括inode,索引节点不必在整个系统中保持唯一,只要在同一设备中唯一即可),它有proc_dir_operations,proc_file_operations,proc_dir_inode_operations,proc_link_inode_operations;

(4.2)proc_root_init()中,还要在目录/proc目录中创建一些子目录,如net,fs等,这些目录都是通过proc_mkdir完成的;

(4.3)proc_root_init()中,由于/proc/tty确实一棵树,在这个节点下面还有其他目录节点,所以有个proc_tty_init()用来创建这个子树;

(5)对/proc文件系统的操作,对/proc/loadavg的访问,这个文件提供有关系统在过去1分钟,5分钟,15分钟内的平均负荷统计信息;这个文件是只读的操作,其proc_dir_entry结构是在proc_misc_init()中通过create_proc_read_entry()创建的;首先要通过系统调用open()来打开,read()来读,最终调用是节点/proc/loadavg指向的loadavg_read_proc();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值