|
在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的一些英文文献,大部分是自己编程心得。 |
|