分类: LINUX
2012-11-14 22:33:56
内核通过不同的接口将信息输出到用户空间,除了用于请求特定信息的系统调用(system call)外,还有三个特殊接口:
Procfs与sysctl
procfs和sysctl都输出内核内部信息,但procfs主要是输出只读数据,而大多数sysctl信息是可写入的,但只要超级用户能写入。与一个简单的内核变量或数据结构相关联的一些文件,可以用sysctl输出。其他涉及更为复杂的数据结构而需要特殊格式时,就以procfs输出,如缓存和统计数据。
Procfs
大多数网络功能会在引导时或在模块加载时其初始化期间在/proc中注册一个或多个文件。当用户读取该文件时,会引起内核间接运行一组内核函数,返回某种输出内容。网络代码所注册的文件位于/proc/net。
/proc中的目录可以使用proc_mkdir创建。/proc/net中的文件可以使用定义在include/linux/proc_fs.h中的proc_net_fops_create和proc_net_remove予以注册和注销。
还有两个通用的API函数create_proc_entry和remove_proc_entry。proc_net_fops_create负责调用proc_net_create创建文档,然后初始化器文件操作处理函数。
如ARP协议在/proc/net中注册其arp文件:
static const struct file_operations arp_seq_fops = {
.owner =
THIS_MODULE,
.open = arp_seq_open,
.read =
seq_read,
.llseek = seq_lseek,
.release =
seq_release_net,
};
static int __net_init arp_net_init(struct net *net)
{
if
(!proc_net_fops_create(net, "arp", S_IRUGO, &arp_seq_fops))
return -ENOMEM;
return 0;
}
static void __net_exit arp_net_exit(struct net *net)
{
proc_net_remove(net, "arp");
}
proc_net_fops_create参数中权限必须指定为只读。当用户读取该文件时,使用file_operations数据结构,返回数据给用户。open所初始化的例程如前例中的qrp_seq_open会做另一次重要的初始化:注册一个函数指针数组,包括procfs用于变量要传回给用户数据的所有例程:一个例程启动dump复制数据,另一个索引到下一条记录,在dump该条记录,继续后移。这些例程的内部保存必要的环境信息,就是已经dump了多少信息。这些信息是dump点已经到正确位置继续dump所必需的。
static const struct seq_operations arp_seq_ops = {
.start =
arp_seq_start,
.next = neigh_seq_next,
.stop =
neigh_seq_stop,
.show = arp_seq_show,
};
static int arp_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &arp_seq_ops,
sizeof(struct neigh_seq_state));
}
1.
4.