在linux系统中实现各项监控的关键技术(2)--内核态与用户态进程之间的通信netlink
Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来使用netlink。如果需要在用户态捕捉到一些内核的信息,就可以通过netlink的机制,将消息从内核发送给用户态。比如,在ext3文件系统处理的ext3_handle_error,以及ext3_abort处挂个函数,函数中实现netlink机制,那么当文件系统异常后,走入ext3_abort,以及ext3_handle_error函数时,就会进入钩子函数,再将信息通过netlink发送到用户态。
Netlink 相对于系统调用,ioctl 以及 /proc 文件系统而言具有以下优点:
1,为了使用 netlink,用户仅需要在 include/linux/netlink.h 中增加一个新类型的 netlink 协议定义即可, 如 #define NETLINK_MYTEST 17 然后,内核和用户态应用就可以立即通过 socket API 使用该 netlink 协议类型进行数据交换。但系统调用需要增加新的系统调用,ioctl 则需要增加设备或文件, 那需要不少代码,proc文件系统则需要在/proc下添加新的文件或目录,那将使本来就混乱的/proc更加混乱。
2. netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接 收队列,而不需要等待接收者收到消息,但系统调用与ioctl 则是同步通信机制,如果传递的数据太长,将影响调度粒度。
3.使用 netlink 的内核部分可以采用模块的方式实现,使用 netlink 的应用部分和内核部分没有编译时依赖,但系统调用就有依赖,而且新的系统调用的实现必须静态地连接到内核中,它无法在模块中实现,使用新系统调用的应用在编译时需要依赖内核。
4.netlink支持多播,内核模块或应用可以把消息多播给一个netlink组,属于该neilink组的任何内核模块或应用都能接收到该消息,内核事件向用户态的通知机制就使用了这一特性,任何对内核事件感兴趣的应用都能收到该子系统发送的内核事件,在后面的文章中将介绍这一机制的使用。
5.内核可以使用netlink首先发起会话,但系统调用和 ioctl 只能由用户应用发起调用。
6.netlink使用标准的 socket API,因此很容易使用,但系统调用和 ioctl则需要专门的培训才能使用。
用户态使用 netlink
用户态应用使用标准的socket APIs, socket(), bind(), sendmsg(), recvmsg() 和 close() 就能很容易地使用 netlink socket,查询手册页可以了解这些函数的使用细节,本文只是讲解使用 netlink 的用户应该如何使用这些函数。注意,使用 netlink 的应用必须包含头文件 linux/netlink.h。当然 socket 需要的头文件也必不可少,sys/socket.h。
struct nlmsghdr *nlh = NULL;
struct sockaddr_nl local;
struct msghdr msg;
struct iovec iov;
struct test_msg *testmsg = NULL; sockfd = socket(PF_NETLINK, (int)SOCK_RAW | SOCK_CLOEXEC, NETLINK_MYTEST);
if (sockfd < ) {
} memset(&local, , sizeof(local));
local.nl_family = PF_NETLINK;
local.nl_pid = getpid();
local.nl_groups = FS_ERROR_GRP_EXT3; if (bind(sockfd, (struct sockaddr*)&local, sizeof(local))) {
} nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(sizeof(struct test_msg)));
if (!nlh) {
} memset(nlh, , NLMSG_SPACE(sizeof(struct test_msg)));
nlh->nlmsg_len = NLMSG_SPACE(sizeof(struct test_msg));
nlh->nlmsg_pid = pthread_self() << | getpid();
nlh->nlmsg_flags = ; memset(&iov, , sizeof(iov));
iov.iov_base = (void*)nlh;
iov.iov_len = nlh->nlmsg_len; memset(&msg, , sizeof(msg));
msg.msg_iov = &iov;
msg.msg_iovlen = ; if (recvmsg(sockfd, &msg, ) < ) {
} testmsg = (struct test_msg *)NLMSG_DATA(nlh);
具体解释可以参见:
https://www.cnblogs.com/iceocean/articles/1594195.html
在linux系统中实现各项监控的关键技术(2)--内核态与用户态进程之间的通信netlink的更多相关文章
- 在linux系统中实现各项监控的关键技术(1)--cpu使用率的计算
转载自 Linux中通过/proc/stat等文件计算Cpu使用率 http://www.blogjava.net/fjzag/articles/317773.html proc文件系统 /proc文 ...
- linux系统中的基础监控(硬盘,内存,系统负载,CPU,网络等)
Linux系统常见日常监控 系统信息 查看 CentOS 版本号:cat /etc/redhat-release 综合监控 nmon 系统负载 命令:w(判断整体瓶颈) 12:04:52 up 1 ...
- Linux系统中的日常监控知识点
1.命令熟悉之w [xiongchao@oc3006745124 Desktop]$ w :: up :, users, load average: 1.48, 1.19, 1.11 USER TTY ...
- Linux系统中的load average(平均负载/运行队列)
1.load average 的含义 系统负载(System Load)是系统CPU繁忙程度的度量,即有多少进程在等待被CPU调度(进程等待队列的长度) linux系统中的Load对当前CPU工作量的 ...
- Linux系统中的load average
1. load average 定义 linux系统中的Load对当前CPU工作量的度量.简单的说是进程队列的长度. Load Average 就是一段时间 (1 分钟.5分钟.15分钟) 内平均 L ...
- 云服务器 ECS Linux 系统中常见的日志文件介绍
云服务器 ECS Linux 系统中,日志文件是非常重要的文件,它们记录了很多系统中重要的事.Linux 系统中常见日志文件概述如下: /var/log/cron可以在 cron 文件中检查 cron ...
- 理解Linux系统中的load average(图文版)转
一.什么是load average? linux系统中的Load对当前CPU工作量的度量 (WikiPedia: the system load is a measure of the amount ...
- Linux系统中如何查找大文件或文件夹的方法
在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在Linux系统中如何查找大文件或文件 ...
- 学习Linux系统中命令的简单方法
如果说如何快速学习.了解Linux的话,我的答案是学命令.背命令!为何呢?对于一名新手来说,去学习Linux的思想.了解Linux的架构.明白Linux中“一切皆文件”概念虽然说是没有错,是对的.但是 ...
随机推荐
- Apache 项目列表功能分类便于技术选型
big-data (49): Apache Accumulo Apache Airavata Apache Ambari Apache Apex Apache Avro Apache Be ...
- 路飞学城-Python开发集训-第3章
学习心得: 通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结 ...
- ubantu 安装 wget
sudo apt-get update sudo apt-get install wget wget
- Apollo 3.0 硬件与系统安装指南
https://github.com/ApolloAuto/apollo/blob/master/docs/quickstart/apollo_3_0_hardware_system_installa ...
- [Flume]使用 Flume 来传递web log 到 hdfs 的例子
[Flume]使用 Flume 来传递web log 到 hdfs 的例子: 在 hdfs 上创建存储 log 的目录: $ hdfs dfs -mkdir -p /test001/weblogsfl ...
- 命令行创建mysql数据库指定编码方法
GBK: create database test2 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; UTF8: CREATE DATABASE t ...
- 强大的开源企业级数据监控利器Lepus安装与配置管理
开篇介绍 官方网站:http://www.lepus.cc 开源企业级数据库监控系统 简洁.直观.强大的开源数据库监控系统,MySQL/Oracle/MongoDB/Redis一站式性能监控,让数据库 ...
- Python3 与 C# 基础语法对比(就当Python和C#基础的普及吧)
文章汇总:https://www.cnblogs.com/dotnetcrazy/p/9160514.html 多图旧排版:https://www.cnblogs.com/dunitian/p/9 ...
- MySQL数据类型--日期和时间类型
MySQL中的多种时间和格式数据类型 日期和时间类型是为了方便在数据库中存储日期和时间而设计的.MySQL中有多种表示日期和时间的数据类型. 其中,year类型表示时间,date类型表示日期,time ...
- stark组件的分页,模糊查询,批量删除
1.分页组件高阶 2.整合展示数据showlist类 3.stark组件之分页 3.stark组件之search模糊查询 4.action批量处理数据 4.总结 1.分页组件高阶 1.分页的class ...