“一切皆是文件”。
Linux的基本哲学之一。它是指linux系统中的所有一切都可以通过文件的方式访问、管理,即便不是文件,也以文件的形式来管理。例如硬件设备、进程、套接字等都抽象成文件,使用统一的用户接口,虽然文件类型各不相同,但是对其提供的确是同一套操作。
问:一台机器可以使用的端口是什么情况?
答:linux系统下,能够使用的端口号范围受内核参数ip_local_port_range
控制,可以通过文件/proc/sys/net/ipv4/ip_local_port_range
查看,并且可以通过echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
方式进行修改。
实际上,端口范围参数只是操作系统内核参数的一个,内核参数非常多,大致如下:
这些文件中有些是可以修改的,有些是不能修改的。
正常情况下,我们都认为其实这些proc文件的读写和普通文件的读写是一样的,但是实际上有一样的地方也有不一样的地方。
从实现上来看,所有类型的文件,在vfs这一层的抽象逻辑都是一样,但是在文件自身的实际类型上是不一样的。
就拿普通的文件为例,普通文件都是存储在磁盘上的数据,读写可以用的方法还是一样的,但是proc文件,每个文件在内核代码中实际上都是不同的变量,这些变量甚至有不同的数据类型和结构,显然在proc文件的读写上,用同样的读写方法不适用了。
proc文件系统介绍
Linux系统上的/proc目录是一种文件系统,即proc文件系统。与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件【准确的讲,proc文件是存储在内存中的一种文件,本质的讲,实际上就是内核代码中的变量;用户所看到的只不过以文件的形式展示出来,并且可以操作这些文件的读写】,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。
通俗的说,proc文件系统也是用户与内核的通信方式之一,通过proc文件系统可以修改内核的相关参数,并且实时生效。
实际的proc文件读写过程
proc文件系统可以说比其他文件系统确实要复杂的多,我们以echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
为例来分析其内核的写逻辑是什么。
通过使用linux内核的debug工具,我们可以得到以下函数的调用过程:
通过该调用链可以发现对/proc/sys/net/ipv4/ip_local_port_range
文件的写操作最后经过vfs文件系统的层层调用,最后来到了proc文件系统的写操作函数proc_sys_write
上,最后传给了ipv4_local_port_range
函数
为什么ip_local_port_range
文件的写操作由ip_local_port_range
函数来完成了
我们可以看如下代码
可以看到ip_local_port_range变量和ip_local_port_range函数的关系在这里进行了定义
我们可以看到这些变量或者proc文件在注册的时候是一个树状结构,当proc_sys_call_handler
这一步在要对目标文件进行处理的时候,会进行一下操作
我们可以看到这里会先通过do_proc_sys_lookup
找到对应的table,然后再使用table对应的pro_handler来执行读写操作。
现在我们再看一下最后操作ip_local_port_range
的具体内容
通过该实现可以发现,我们所看到的端口范围其实就是sysctl_local_port_range变量的值,读写实际上都是针对该变量进行操作,如果write标志位为真,就通过set_local_port_range
对该变量进行设置。
总结
通过本文章,我们可以了解到proc文件系统的本质是什么,以及实际工作中如何受其影响,另外当我们对这些proc文件操作,最后实际上操作了什么。