作者:Younger Liu,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。
Sysctl是一种用户应用来设置和获得运行时内核的配置参数的一种有效方式,通过这种方式,用户应用可以在内核运行的任何时刻来改变内核的配置参数,也可以在任何时候获得内核的配置参数。
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; };
void *data; /* 表示对应于内核中的变量名称 */
int maxlen; /* 表示条目允许的最大长度 */
mode_t mode; /* 条目在proc文件系统下的访问权限 */
struct ctl_table *child;
struct ctl_table *parent; /* Automatically set */
proc_handler *proc_handler; /*回调函数&proc_dointvec/&proc_dostring */
void *extra1;
void *extra2;
字段maxlen,它主要用于字符串内核变量,以便在对该条目设置时,对超过该最大长度的字符串截掉后面超长的部分.
字段proc_handler,表示回调函数,对于整型内核变量,应当设置为&proc_dointvec,而对于字符串内核变量,则设置为 &proc_dostring。
Sysctl 条目也可以是目录,此时 mode 字段应当设置为 0555,否则通过 sysctl 系统调用将无法访问它下面的 sysctl 条目,child 则指向该目录条目下面的所有条目,对于在同一目录下的多个条目,不必一一注册,用户可以把它们组织成一个 struct ctl_table 类型的数组,然后一次注册就可以。
/********************************************** * Author: lewiyon@hotmail.com * File name: sysctl_example.c * Description: sysctl example * Date: 2013-04-24 *********************************************/ #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/sysctl.h> static int sysctl_kernusr_data = 1024; static int kernusr_callback(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int rc; int *data = table->data; printk(KERN_INFO "original value = %d\n", *data); rc = proc_dointvec(table, write, buffer, lenp, ppos); if (write) printk(KERN_INFO "this is write operation, current value = %d\n", * data); return rc; } static struct ctl_table kernusr_ctl_table[] = { { .procname = "kernusr", .data = &sysctl_kernusr_data, .maxlen = sizeof(int), .mode = 0644, .proc_handler = kernusr_callback, }, { /* sentinel */ }, }; static struct ctl_table_header *sysctl_header; static int __init sysctl_example_init(void) { sysctl_header = register_sysctl_table(kernusr_ctl_table); if (sysctl_header == NULL) { printk(KERN_INFO "ERR: register_sysctl_table!"); return -1; } printk(KERN_INFO "sysctl register success.\n"); return 0; } static void __exit sysctl_example_exit(void) { unregister_sysctl_table(sysctl_header); printk(KERN_INFO "sysctl unregister success.\n"); } module_init(sysctl_example_init); module_exit(sysctl_example_exit); MODULE_LICENSE("GPL");
作者:Younger Liu,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。