使用/proc实现内核与用户空间通信
1. 前言
mode_t mode, struct proc_dir_entry *base,
read_proc_t *read_proc, void * data)
{
struct proc_dir_entry *res=create_proc_entry(name,mode,base);
if (res) {
res->read_proc=read_proc;
res->data=data;
}
return res;
}
name:要建立的文件名
mode:文件模式
base:所在的目录
read_proc:这是个函数指针,表示读取文件内容的函数
data:传递给read_proc函数的用户参数指针
mode_t mode, struct proc_dir_entry *base, get_info_t *get_info)
{
struct proc_dir_entry *res=create_proc_entry(name,mode,base);
if (res) res->get_info=get_info;
return res;
}
name:要建立的文件名
mode:文件模式
base:所在的目录
get_info:这是个函数指针,表示读取文件内容的函数,这个函数比上面的read_proc函数少一个用户输入参数
name:要建立的文件名
parent:父目录
mode_t mode, get_info_t *get_info)
{
return create_proc_info_entry(name,mode,proc_net,get_info);
}
{
remove_proc_entry(name,proc_net);
}
...
// 建立/proc/net/netstat文件
proc_net_create ("netstat", 0, netstat_get_info);
...
//start用来返回buffer中起始数据的位置;
//offset指定偏移start所指数据相对buffer起点的偏移,实际start是通过buffer和
//length表示buffer的长度,是由内核自己分配的,编程时要检查向缓冲区写的数据长度
{
int len, i;
// len记录写入缓冲区的数据长度,所有数据长度都要累加
len = sprintf(buffer,
"TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed"
" EmbryonicRsts PruneCalled RcvPruned OfoPruned"
" OutOfWindowIcmps LockDroppedIcmps ArpFilter"
" TW TWRecycled TWKilled"
" PAWSPassive PAWSActive PAWSEstab"
" DelayedACKs DelayedACKLocked DelayedACKLost"
" ListenOverflows ListenDrops"
" TCPPrequeued TCPDirectCopyFromBacklog"
" TCPDirectCopyFromPrequeue TCPPrequeueDropped"
" TCPHPHits TCPHPHitsToUser"
" TCPPureAcks TCPHPAcks"
" TCPRenoRecovery TCPSackRecovery"
" TCPSACKReneging"
" TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder"
" TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo"
" TCPLoss TCPLostRetransmit"
" TCPRenoFailures TCPSackFailures TCPLossFailures"
" TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans"
" TCPTimeouts"
" TCPRenoRecoveryFail TCPSackRecoveryFail"
" TCPSchedulerFailed TCPRcvCollapsed"
" TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv"
" TCPAbortOnSyn TCPAbortOnData TCPAbortOnClose"
" TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger"
" TCPAbortFailed TCPMemoryPressures/n"
"TcpExt:");
for (i=0; i<offsetof(struct linux_mib, __pad)/sizeof(unsigned long); i++)
len += sprintf(buffer+len, " %lu", fold_field((unsigned long*)net_statistics, sizeof(struct linux_mib), i));
{
*start = buffer;
return 0;
}
//计算数据起始指针
*start = buffer + offset;
len -= offset;
if (len > length)
len = length;
if (len < 0)
len = 0;
return len;
}
{
int ctl_name; /* 数值表示的该项的ID */
const char *procname; /* 名称 */
void *data; /* 对于的内核参数 */
int maxlen; /* 该参数所占的存储空间 */
mode_t mode; /* 权限模式:rwxrwxrwx */
ctl_table *child; /* 子目录表 */
proc_handler *proc_handler; /* 读写数据处理的回调函数 */
ctl_handler *strategy; /* 读/写时的回调函数,是对数据的预处理,
该函数是在读或写操作之前执行,该函数返回值
<0表示出错;==0表示正确,继续读或写;>0表
示读/写操作已经在函数中完成,可以直接返回了*/
struct proc_dir_entry *de; /* /proc控制块指针 */
void *extra1; /* 额外参数,常在设置数据范围时用来表示最大最小值 */
void *extra2;
};
extern int proc_dostring(ctl_table *, int, struct file *,
void *, size_t *);
// 处理整数向量
extern int proc_dointvec(ctl_table *, int, struct file *,
void *, size_t *);
// 处理整数向量,但init进程处理时稍有区别
extern int proc_dointvec_bset(ctl_table *, int, struct file *,
void *, size_t *);
// 处理最大最小值形式的整数向量
extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
void *, size_t *);
// 处理最大最小值形式的无符合长整数向量
extern int proc_doulongvec_minmax(ctl_table *, int, struct file *,
void *, size_t *);
// 处理整数向量,但用户数据作为秒数,转化为jiffies值,常用于时间控制
extern int proc_dointvec_jiffies(ctl_table *, int, struct file *,
void *, size_t *);
// 处理无符合长整数向量,用户数据作为为毫秒值,转化为jiffies值,常用于时间控制
extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int,
struct file *, void *, size_t *);
{NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max",
&ip_conntrack_max, sizeof(int), 0644, NULL,
&proc_dointvec},
{NET_IPV4_NF_CONNTRACK_BUCKETS, "ip_conntrack_buckets",
&ip_conntrack_htable_size, sizeof(unsigned int), 0444, NULL,
&proc_dointvec},
{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent",
&ip_ct_tcp_timeout_syn_sent, sizeof(unsigned int), 0644, NULL,
&proc_dointvec_jiffies},
......
{0}
};
{NET_IPV4_NETFILTER, "netfilter", NULL, 0, 0555, ip_ct_sysctl_table, 0, 0, 0, 0, 0},
{NET_IP_CONNTRACK_MAX, "ip_conntrack_max",
&ip_conntrack_max, sizeof(int), 0644, NULL,
&proc_dointvec},
{0}
};
{NET_IPV4, "ipv4", NULL, 0, 0555, ip_ct_netfilter_table, 0, 0, 0, 0, 0},
{0}
};
{CTL_NET, "net", NULL, 0, 0555, ip_ct_ipv4_table, 0, 0, 0, 0, 0},
{0}
};
{
...
ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
...
}
int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp)
{
// 保持当前的forwarding值
int val = ipv4_devconf.forwarding;
int ret;
// 完成/proc/sys的读写操作,如果是写操作,forwarding值已经改为新值
ret = proc_dointvec(ctl, write, filp, buffer, lenp);
if (write && ipv4_devconf.forwarding != val)
inet_forward_change(ipv4_devconf.forwarding);
}
void *oldval, size_t *oldlenp,
void *newval, size_t newlen,
void **context)
{
int new;
if (newlen != sizeof(int))
return -EINVAL;
if (get_user(new,(int *)newval))
return -EFAULT;
if (new != ipv4_devconf.forwarding)
inet_forward_change(new);
// 把forwarding值赋值为新值后应该可以返回>0的数的,现在不赋值只能返回0继续了
// 不过该strategy函数好象不是必要的,上面的proc_handler函数已经可以处理了
return 0; /* caller does change again and handles handles oldval */
}
......
{NET_IPV4_FORWARD, "ip_forward",
&ipv4_devconf.forwarding, sizeof(int), 0644, NULL,
&ipv4_sysctl_forward,&ipv4_sysctl_forward_strategy},
......
使用/proc实现内核与用户空间通信的更多相关文章
- linux 内核与用户空间通信机制netlink初探
1.Linux进程概述 Linux中的进程间通信机制源自于Unix平台上的进程通信机制.Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上各有所不同,前者形成了运行 ...
- linux 内核与用户空间通信之netlink使用方法
转自:http://blog.csdn.net/haomcu/article/details/7371835 Linux中的进程间通信机制源自于Unix平台上的进程通信机制.Unix的两大分支AT&a ...
- Linux内核和用户空间通信之netlink
1. netlink Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口. Netlink 是一种特殊的 socket,它 ...
- Linux内核空间-用户空间通信之debugfs
一.debugfs文件系统简介 debugfs虚拟文件系统是一种内核空间与用户空间的接口,基于libfs库实现,专用于开发人员调试,便于向用户空间导出内核空间数据(当然,反方向也可以).debugfs ...
- Linux内核态用户态相关知识 & 相互通信
http://www.cnblogs.com/bakari/p/5520860.html 内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境. 系统调用是操作系统的最小功能 ...
- Linux 系统内核空间与用户空间通信的实现与分析-NETLINK (转载)
Linux中的进程间通信机制源自于Unix平台上的进程通信机制.Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上的各有所不同,前者形成了运行在单个计算机上的Syste ...
- linux 系统内核空间与用户空间通信的实现与分析<转>
linux 系统内核空间与用户空间通信的实现与分析 2 评论: 陈鑫 (chen.shin@hotmail.com), 自由软件爱好者, 南京邮电学院电子工程系 2004 年 7 月 01 日 内容 ...
- Linux启动时间优化-内核和用户空间启动优化实践
关键词:initcall.bootgraph.py.bootchartd.pybootchart等. 启动时间的优化,分为两大部分,分别是内核部分和用户空间两大部分. 从内核timestamp 0.0 ...
- Linux 系统内核空间与用户空间通信的实现与分析
本文转载自:https://www.ibm.com/developerworks/cn/linux/l-netlink/index.html 多数的 Linux 内核态程序都需要和用户空间的进程交换数 ...
随机推荐
- PLSQL_性能优化工具系列05_SQL Trace/Event 10046 Trace
2014-06-25 Created By BaoXinjian
- c# as
as:用于检查在兼容的引用类型之间执行某些类型的转换. Employee myEmployee = myObject as Employee; if (myEmployee != null) { } ...
- mysql如何给汉字按照首字母顺序排序
select * from 表名 order by convert(列明 USING gbk) COLLATE gbk_chinese_ci asc
- asp.net 自定义文本框
using System;using System.Data;using System.Configuration;using System.Linq;using System.Web;using S ...
- gitlab和Django实现push自动更新
1.设置webhook gitlab->setting->webhook:http://121.143.191.166:7000?token=23028-b396-12e5-9912-ba ...
- ORA-00245: control file backup failed; target is likely on a local file system (转载)
环境:DB VERSION: 11.2.0.4.0RAC 2 nodes 问题:邮件显示rman备份失败,查看rman备份日志 Starting Control File and SPFILE Aut ...
- 通过反射获取父类中的泛型参数对应的Class对象
假设有两个类:Dao 和 PersonDao,它们的代码如下: Dao: public class Dao<T> { private Class<T> clazz; T get ...
- Android双击Back退出应用
前言 在app主界面点击back时,通常有以下几种方式进行退出 单击即退出 弹出确认Dialog 再次点击退出程序 个人最喜欢方式3,相比于方式2,不需要再把手指移动到屏幕中央点击Dialog,相比于 ...
- Fiddler录制jmeter脚本,干货分享
我们知道以前jmeter的脚本来源有三个,手动书写.badboy录制.自带的录制功能(jmeter3.0该功能还比较好),目前我们又多了一个fiddler生成,自上次分享出来fiddler ...
- 基于OpenDaylight和Mininet的试验床平台搭建
##########################################平台架构######################################### 一.虚拟机安装和镜像加载 ...