使用/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 内核态程序都需要和用户空间的进程交换数 ...
随机推荐
- CE_现金账户转账汇入汇出交易(案例)(未完成)
2014-07-15 BaoXinjian 一.摘要 二.案例 通过 Oracle Payments 结算事务处理 通过付款模板 事物处理子类型 已验证 -> 正在结算中 ->
- OAF_EO系列7 - OAException异常处理及实现(案例)
2014-06-12 Created By BaoXinjian
- cf 605B B. Lazy Student 构造 好题
题意: 一个n个节点的图,有m条边,已知这个图的一个mst 现在如果我们知道这个图的m条边,和知道mst的n-1条边是哪些,问能不能构造出一个满足条件的图 思路:排序+构造 数组deg[i]表示节点i ...
- POJ 4047 Garden 线段树 区间更新
给出一个n个元素的序列,序列有正数也有负数 支持3个操作: p x y 0.p=0时,把第x个的值改为y 1.p=1时,交换第x个和第y个的值 2.p=2时,问区间[x,y]里面连续k个的子序列的最大 ...
- [实变函数]2.5 Cantor 三分集
1 Cantor 三分集的构造: $$\bex P=\cap_{n=1}^\infty F_n. \eex$$ 2 Cantor 三分 ...
- php 防止sql注入
Q:如果把用户输入的没有任何改动的放到SQL的查询语句中,很有可能会导致SQL注入,比如说下面的例子: $unsafe_variable = $_POST['user_input']; mysql_q ...
- Win7允许被ping
我们可以通过命令行方式来执行入站 Ping 的规则是启用还是禁用,命令行如下: netsh firewall set icmpsetting 8 netsh firewall set icmpsett ...
- ASPxGridView中DetailRow的使用
ASPxGridView是一个方便的数据显示控件,可是自动的绑定我们所需要的数据,但是有时,当数据属性过多时,我们并不一定要把所有的信息提供给所有的人,当有人需要这些数据时可以自动的进行查看,这时就可 ...
- "自定义事件"的优点在哪里?
事实上我们可以通过bind绑定一个自定义事件,然后再通过trigger来触发这个事件.例如给element绑定一个hello事件,再通过trigger来触发这个事件: //给element绑定hell ...
- MongoDB 多条件组合查询
组合条件查询json格式语法 { "$and": [ { "Date": { $gt: ISODate("2015-06-05T00:45:00.00 ...