内核proc文件系统与seq接口(6)----分析sysctl函数接口与procfs之间的内部关系

之前在研究内核的procfs时,疏漏了一个与之相关的知识点,在之后的阅读《深入Linux内核构架》的相关知识时才注意到,这就是用户空间使用sysctl函数(系统控制机制)时的内核实现原理。

 

    系统控制机制可以在Linux内核运行时控制内核的行为,控制参数从用户空间传输到内核中,且无须reboot。早期实现这种机制的方法是用户空间使用sysctl函数,glibc将调用sysctl系统调用来实现,然后通过传递过来的二进制码(在中的枚举定义)来找到相关的struct ctl_table:

(早期结构体定义)

struct ctl_table 
{
int ctl_name;
const char *procname; /* Text ID for /proc/sys, or zero */
void *data;
int maxlen;
mode_t mode;
struct ctl_table *child;
struct ctl_table *parent; /* Automatically set */
proc_handler *proc_handler; /* Callback for text formatting */
ctl_handler *strategy;
struct proc_dir_entry *de;
void *extra1;
void *extra2;
};

并使用其中的ctl_handler *strategy;函数来实现对内核配置的修改。

由于原来的方案不是最优雅的方案(必须编写一个程序读取参数并使用sysctl将将要修改的参数传递给内核),并且这个系统调用非POSIX标准,所以sysctl是过时的,迟早会被抛弃。为了应对这种情况,Linux借procfs,重排了所有的sysctl,建立了一个层次结构,最终导出到了/proc/sys/目录下。这样就可以用简单的用户空间工具来访问这些内核参数了。

    这时内核对于同一个参数的操作既有sysctl接口,也有procfs接口,可以说是冗余了。

    现在的内核中,这种机制已经改变了,即使是《深入Linux内核构架》中的描诉也已经过时了。可以说是为了对原有的sysctl系统调用兼容,内核现在对于原有的sysctl系统调用的实现做了修改,首先struct ctl_table删除了一些无用的成员:

struct ctl_table 
{
const char *procname; /* Text ID for /proc/sys, or zero */
void *data;
int maxlen;
mode_t mode;
struct ctl_table *child;
struct ctl_table *parent; /* Automatically set */
proc_handler *proc_handler; /* Callback for text formatting */
void *extra1;
void *extra2;
};

其次,内核将通过sysctl系统调用(in kernel/sysctl_binary.c)传递进来二进制码通过sysctl_getname函数并利用一堆的struct bin_table结构体提供的信息转换为/proc/sys目录下的文件名路径,最终通过操作相应的procfs文件实现sysctl源码都在 kernel/sysctl_binary.c文件中,有兴趣的读者可以自己RTFSC。 

综上所述,为了软件兼容性,现在的sysctl被保留,底层通过procfs实现原来的系统控制机制,如下图所示:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值