找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 1114|回复: 1

[【原创】] 如何用sysctl来控制内核变量

[复制链接]
发表于 2008-1-26 10:29:56 | 显示全部楼层 |阅读模式
在FreeBSD系统中,很多功能我们可以用sysctl来打开,比如加载网桥功能模块和防火墙。

下面我来说说如何使用sysctl来和内核模块进行通信.

如何用sysctl 来和内核进行通信。

在BSD中,你有所有的源代码,因此可以尝试修改内核来进一步理解它。使用BSD中的sysc
tl方法,可以很方面的在一个运行的系统中来修改和设置你在内核中的变量。下面来说明
如何在系统中运用sysctl来和内核通信。
当然,你首先要明白如何编译BSD操作系统。如果不知道的话,我会在下面的FreeBSD入门
中进行说明。

找到你所感兴趣的内核文件,比如:/usr/src/sys/i386/isa/random_machdep.c
在这个文件中,添加如下:
#include <sys/kernel.h>
#include <sys/sysctrl.h>
/*宣称你想控制的变量*/
static int my_var=0;
SYSCTL_INT( _net, OID_AUTO, my_var, CTLFLAG_RW, &my_var, 0, \"\");
/*注:_net是系统定义好的节点,你也可以宣称自己的节点*/
编译内核并且重新启动,你就可以通过sysctl来控制my_var这个内核变量了。
比如:在shell里输入: sysctl net.my_var=1
内核中的my_var将变为1.

如果你想到宣称自己的节点,在/usr/src/sys/sys/sysctl.h中,修改如下:
#define CTL_UNSPEC   0        /* unused */
#define CTL_KERN    1        /* \"high kernel\": proc, limits */
#define CTL_VM     2        /* virtual memory */
#define CTL_VFS     3        /* file system, mount type is next */

#define CTL_NET     4        /* network, see socket.h */
#define CTL_DEBUG    5        /* debugging parameters */
#define CTL_HW     6        /* generic cpu/io */
#define CTL_MACHDEP   7        /* machine dependent */
#define CTL_USER    8        /* user-level */
#define CTL_P1003_1B  9        /* POSIX 1003.1B */
#define CTL_EXPER 10     /*添加自己要定义的节点 */
#define CTL_MAXID   11       /* number of valid top-level ids */
/* DAH MODIFIED TO INCLUDE \"EXPER\" NODE *******/
#define CTL_NAMES { \\
    { 0, 0 }, \\
    { \"kern\", CTLTYPE_NODE }, \\
    { \"vm\", CTLTYPE_NODE }, \\
    { \"vfs\", CTLTYPE_NODE }, \\
    { \"net\", CTLTYPE_NODE }, \\
    { \"debug\", CTLTYPE_NODE }, \\
    { \"hw\", CTLTYPE_NODE }, \\
    { \"machdep\", CTLTYPE_NODE }, \\
    { \"user\", CTLTYPE_NODE }, \\
    { \"p1003_1b\", CTLTYPE_NODE }, \\
    { \"exper\", CTLTYPE_NODE }, \\ /* 自己需要添加的部分 */
}

在/usr/src/syc/kern/kern_mib.c中添加:
SYSCTL_NODE( , CTL_EXPER, exper, CTLFLAG_RW, 0, \"description\");

这样,重新编译完内核后并且重新启动,你就可以有节点exper了。

还有一些细节进行补充:
在节点已经定义或者存在的时候,
比如evwind节点存在了(按上面的方法在sysctl.h和kern_mib.c中定义了)
扩展节点可以这样来定义:
SYSCTL_DECL(_evwind);
SYSCTL_NODE(_evwind, OID_AUTO, bdg, CTLFLAG_RW, 0, “my number!”);
SYSCTL_INT(_evwind_bdg, OID_AUTO, bridge_on, CTLFLAG_RW, &bridge_on, “”);
这样就可以对整数类型的内核变量bridge_on控制了。
他在节点evwind.bdg.brdge_on中.  

如果是其他类型的变量,如字符串等,就用SYSCTL_STRING等,这些可以在sysctl.h中找到。

如果需要对输入进行控制,可以调用SYSCTL_PROC。
如:SYSCTL_PROC(_evwind_bdg, OID_AUTO, bridge_on, CTLTYPE_INT|CTLFLAG_RW,
   &bridge_on, 0, &sysctl_bridge_on, “”, “”);
第三个参数表示名称,第四个是操作类型,第五个是参数的地址,第七个是要调用的函数
,8,9是说明,可以为空。
对于 string(其他类型) 型,第6个是字符串(其他类型)的长度。

当然了,如果你只想通过sysctl来调用内核中定义的函数,当然也是可行的。如:
SYSCTL_PROC(_net_link_ether, OID_AUTO, bridge_refresh, CTLTYPE_INT|CTLFLAG_RW,
NULL, 0, &sysctl_refresh, “”, “”);
输入sysctl net.link.ether.sysctl_refresh, 则调用sysctl_refresh函数。

好了,这个问题不再多写了,我想已经把sysctl 的用法说的够具体了。以后有时间再补充
一些。此文参考了sysctl的一些英文文献,大部分是自己编程心得。
回复

使用道具 举报

发表于 2008-1-26 15:29:27 | 显示全部楼层
这么辛苦的写了洋洋洒洒一大篇,还是赞一个吧。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-6-6 22:15 , Processed in 0.318030 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表