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");

猜你喜欢

转载自blog.csdn.net/yldfree/article/details/84566818