linux 2.6.32下sysctl的使用
struct ctl_table
{
int ctl_name; /* 結點標識,同一層的結點用不同的數字來標識
此處設定的意義可以看do_sysctl()->parse_table()
*/
const char *procname; /* /proc/sys/ 下使用的檔名*/
void *data; /*核心變數的地址*/
int maxlen; /*核心變數的尺寸大小*/
mode_t mode; /*檔案訪問許可權*/
struct ctl_table *child; /*建立檔案與目錄的父子關係*/
struct ctl_table *parent; /* Automatically set */
proc_handler *proc_handler; /* 當對檔案讀取或寫入的時候 呼叫此函式
根據值的型別 初始化為不同的函式如字串 proc_dostring()
*/
ctl_handler *strategy; /* 用sysctl系統呼叫的時候 此函式被呼叫 sysctl_string()*/
void *extra1;
void *extra2; /*extra1 extra2可選引數 通常定義變數的最小值 或最大值*/
};
struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
fun:註冊sysctl(/proc/sys)下的操作項
標頭檔案:#include <linux/sysctl.h>
void unregister_sysctl_table(struct ctl_table_header * header)
fun:登出sysctl(/proc/sys)下的操作項
標頭檔案:#include <linux/sysctl.h>
初始化ctl_table{}->proc_handler的函式
proc_dostring()
讀寫一個字串
proc_dointvec()
讀寫包含一個或多個整數的陣列
proc_dointvec_minmax()
類似 proc_dointvec() 但是要確定輸入資料是在 min/max範圍內
proc_dointvec_jiffies ()
讀寫整形陣列 此核心變數以jiffies為單位表示,返回給使用者前先轉為秒數
proc_doulongvec_minmax()
類似proc_dointvec_minmax()但讀取的是長整形
proc_doulongvec_ms_jiffies_minmax()
讀寫長整形陣列 此核心變數以jiffies為單位 返回給使用者前先轉換為毫秒數
初始化ctl_table{}-> strategy的函式
sysctl_string()
讀寫一個字串
sysctl_intvec()
讀寫一個整形陣列 而且確定其值符合min/max
sysctl_jiffies()
讀寫一個以jiffies表示的值,然後將其轉化為秒
sysctl_ms_jiffies()
讀寫一個以jiffies表示的值,然後把它裝化為毫秒
舉個栗子
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sysctl.h>
int g_catsize=20;
int g_catcolor = 10;
char g_catname[258] = {"miaomiao"};
enum{
KERNEL_CAT_SIZE=1,//不要從0開始
KERNEL_CAT_COLOR,
KERNEL_CAT_NAME
};
enum{
KERNEL_CAT = CTL_CPU + 11,//不要從0開始 不要和系統已有的ctl_name重複 why?看do_sysctl()->parse_table()
};
int my_proc_dointvec(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int ret = 0;
//用來處理整型資料或整型陣列
ret = proc_dointvec(table,write,buffer,lenp,ppos);
printk("*********************catsize=%d catcolor=%d\n",g_catsize,g_catcolor);
return ret;
}
int my_proc_dostring(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int ret;
//用來處理字串
ret = proc_dostring(table,write,buffer,lenp,ppos);
printk("**************************catname=%s\n",g_catname);
return ret;
}
/*對應的檔案項
* /proc/sys/mycat1/catsize
/proc/sys/mycat1/catcolor
/proc/sys/mycat1/catname
* */
static ctl_table cat_attr_table[]={
{
.ctl_name = KERNEL_CAT_SIZE,
.procname = "catsize",
.data = &g_catsize,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &my_proc_dointvec //處理整型
},
{
.ctl_name = KERNEL_CAT_COLOR,
.procname = "catcolor",
.data = &g_catcolor,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &my_proc_dointvec //處理整型
},
{
.ctl_name = KERNEL_CAT_NAME,
.procname = "catname",
.data = g_catname,
.maxlen = 256,
.mode = 0644,
.proc_handler = &my_proc_dostring//處理字串
},
{} //最後一項必須為空
};
/*
對應的目錄項:
/proc/sys/mycalt1/
*/
static ctl_table mycat[]={
{
.ctl_name = KERNEL_CAT,
.procname = "mycat1",
.mode = 0555, //建立目錄許可權
.child = cat_attr_table //設定子檔案項
},
{} //最後一項必須為空
};
static struct ctl_table_header *cat_table_header;
static int __init test_init(void)
{
//註冊sysctl操作項
cat_table_header = register_sysctl_table(mycat);
if(NULL == cat_table_header)
{
printk("register error\n");
return -1;
}
return 0;
}
static void __exit test_exit(void)
{
//登出syscatl操作項
unregister_sysctl_table(cat_table_header);
return;
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");