Netlink
来自个人维基
目录 |
介绍
linux内核与用户空间交互的机制,用于取代linux系统早期的热插拔机制hotplug。
Linux基本系统使用
测试代码
netlink测试和coldboot。coldboot是一个在系统启动以后重新使设备再上发一次内核事件的小程序
Android实现
在Android系统中,对netlink提供了一个C++类封装NetlinkListener。
用户使用时,只要以此为基类,派生出自己的子类就可以很方便的进行使用。在构造函数中传入socket句柄,然后调用startListener开始监听,系统发生的任何内核事件将会回调onEvent函数传递进来。 下面是一份例子代码在froyo系统上进行验证过的
声明
#include <sysutils/NetlinkListener.h> #include <sysutils/NetlinkEvent.h> class NetlinkTest: public NetlinkListener { public: NetlinkTest(int listenerSocket); virtual ~NetlinkTest(); int start(void); int stop(void); protected: virtual void onEvent(NetlinkEvent *evt); };
实现
#include <stdio.h> #include "NetlinkTest.h" NetlinkTest::NetlinkTest(int listenerSocket): NetlinkListener(listenerSocket) { } NetlinkTest::~NetlinkTest() { } int NetlinkTest::start(void) { return this->startListener(); } int NetlinkTest::stop(void) { return this->stop(); } void NetlinkTest::onEvent(NetlinkEvent *evt) { const char *subsys = evt->getSubsystem(); printf("===================================subsys:%s\n",subsys); if (evt->getAction() == NetlinkEvent::NlActionUnknown) { printf("===================================action:%s \n","NlActionUnknown"); } else if (evt->getAction() == NetlinkEvent::NlActionAdd) { printf("===================================action:%s \n","ActionAdd"); } else if (evt->getAction() == NetlinkEvent::NlActionRemove) { printf("===================================action:%s \n","NlActionRemove"); } else if (evt->getAction() == NetlinkEvent::NlActionChange) { printf("===================================action:%s \n","NlActionChange"); } const char * p; p = evt->findParam("DEVPATH"); if (p != NULL) printf("===================================param(major):%s\n",p); else printf("===================================param(major):%s\n","NULL"); return; }
启动
#include <stdio.h> #include <errno.h> #include <sys/socket.h> #include <sys/select.h> #include <sys/time.h> #include <sys/types.h> #include <sys/un.h> #include <linux/netlink.h> #include "NetlinkTest.h" #include <unistd.h> int main(int argc,char* argv[]) { struct sockaddr_nl nladdr; int sz = 64 * 1024; int mSock; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; nladdr.nl_pid = getpid(); nladdr.nl_groups = 0xffffffff; if ((mSock = socket(PF_NETLINK, SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) { printf("Unable to create uevent socket: %s", strerror(errno)); return -1; } if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) { printf("Unable to set uevent socket options: %s", strerror(errno)); return -1; } if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) { printf("Unable to bind uevent socket: %s", strerror(errno)); return -1; } NetlinkTest nlk(mSock); nlk.start(); while(true){ sleep(2); } printf("exit!!!!!!!!!!!!!!!!!!\n"); }