sysctl系统调用

以前没用过这个系统调用,最近看源码的时候看到了,顺便了解了一下。

它的作用我就不多介绍了,了解linux的同学应该了解linux下有个sysfs,这个就是用来从sysfs中获取或者修改信息的。

 

man 2 sysctl里面给出的函数原型是

int _sysctl(struct __sysctl_args *args);

用起来很不顺手,还带个下划线。。。。

咱不用这个,看下/usr/include/sys/sysctl.h(注意不是man中给出的/usr/include/linux/sysctl.h)

这里面有比较顺手的函数原型

 

extern int sysctl (int *__name, int __nlen, void *__oldval,

                    size_t *__oldlenp, void *__newval, size_t __newlen) __THROW;

参数介绍:

 

__name:一个整形数组,代表了从sysfs根目录开始到目标文件的路径,

__nle:    参数1中数组元素的个数

__oldva: 一个缓冲区,内核将信息保存在这个缓冲区里返回给用户

__oldlenp:传入__oldval缓冲区的大小,返回后被内核用实习返回的信息长度所覆盖。

__newval :如果想要修改该变量,把新值从这里传入。

__newlen:__newval的长度。

后面四个参数都可以为NULL和0.

__name这个参数怎么选择?什么叫路径?

我们可以看下linux/sysctl.h中的枚举值

 

enum

{

        CTL_KERN=1,             /* General kernel info and control */

        CTL_VM=2,               /* VM management */

        CTL_NET=3,              /* Networking */

        CTL_PROC=4,             /* removal breaks strace(1) compilation */

        CTL_FS=5,               /* Filesystems */

        CTL_DEBUG=6,            /* Debugging */

        CTL_DEV=7,              /* Devices */

        CTL_BUS=8,              /* Busses */

        CTL_ABI=9,              /* Binary emulation */

        CTL_CPU=10,             /* CPU stuff (speed scaling, etc) */

        CTL_ARLAN=254,          /* arlan wireless driver */

        CTL_S390DBF=5677,       /* s390 debug */

        CTL_SUNRPC=7249,        /* sunrpc debug */

        CTL_PM=9899,            /* frv power management */

        CTL_FRV=9898,           /* frv specific sysctls */

};

再看下/proc/sys下面的文件
pei@pei-desktop:~$ ls /proc/sys
crypto  debug  dev  fs  kernel  net  vm
上面每个枚举值就代表下面一个目录,有些没有那是因为sysfs是动态的,根你编译内核的选项有关,而这个头文件是静态的,必须包含所有有可能出现的sysfs值,因此头文件中的项目会多一些。
知道了这一点,下面举个例子就很容易懂了
先看下/proc/sys/net/ipv4/tcp_mem这个文件的内容
pei@pei-desktop:~$ cat /proc/sys/net/ipv4/tcp_mem 
45792 61056 91584
记住它的路径,然后我们写下如下程序
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/sysctl.h> int main() { struct { int low, pressure, high; }buf; size_t len = sizeof(buf); int name[]={CTL_NET, NET_IPV4, NET_TCP_MEM}; if( sysctl( name, sizeof(name)/sizeof(int), &buf, &len, NULL, 0) < 0) { perror("sysctl"); exit(EXIT_FAILURE); } printf("tcp_mem: low=%d, pressure=%d, high=%d/n", buf.low, buf.pressure, buf.high); return 0; }  
注意上面name的值
nt name[]={CTL_NET, NET_IPV4, NET_TCP_MEM};
跟/proc/sys/ net/ipv4/tcp_mem路径完全一致。
最后,这个函数是linux特有的,所以要写移植性好的程序还是不要用的好

 

 

 

你可能感兴趣的:(sysctl系统调用)