Android2.2 Vold 分析-(二)---Vold 中 Netlink事件通信机制分析

Vold 中 Netlink事件通信机制分析

NetlinkHandler的成员函数start()会调用SocketListener::startListen()

在system/vold/main.cpp main()函数中调用nl->start(),就是调用int NetlinkManager::start() 函数,该函数主要功能:
(1). 创建NETLINK socket
(2). 构建NetlinkHandler对象,并通过其成员函数start()调用SocketListener::startListen();
分析如下:
int NetlinkManager::start() { struct sockaddr_nl nladdr; int sz = 64 * 1024; 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) {} if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) { } if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {} mHandler = new NetlinkHandler(mSock); if (mHandler->start()) { } return 0; }

调用startListen,mSock前面创建,
int SocketListener::startListener() { if (!mSocketName && mSock == -1) { } else if (mSocketName) { if ((mSock = android_get_control_socket(mSocketName)) < 0) { } } if (mListen && listen(mSock, 4) < 0) {} //监听套接字执行这一部分 else if (!mListen) //如果非监听套接字(TCP有监听套接字,和数据交换套接字,UDP只有数据交换套接字),Netlink为UDP,所以执行这一部分; mClients->push_back(new SocketClient(mSock)); //直接执行这一行,将NetLink的socket添加到mClient容器中; if (pipe(mCtrlPipe)) { } if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) { } //启动新的线程,这里的this 指的是NetlinkHandler的对象 如下: return 0; }

线程函数:void *SocketListener::threadStart(void *obj) { SocketListener *me = reinterpret_cast<SocketListener *>(obj); //将NetlinkHandler对象强制转换为SocketListener类型对象,调用其runListener函数 me->runListener(); }

线程真正执行的函数:mListen成员用来判定是否监听套接字

Netlink套接字属于udp套接字,非监听套接字,该函数的主要功能体现在,如果该套接字有数据到来,就调用相关函数读取数据。

void SocketListener::runListener() { while(1) { //无线循环,一直监听 SocketClientCollection::iterator it; fd_set read_fds; int rc = 0; int max = 0; FD_ZERO(&read_fds); //清空文件描述符集read_fds if (mListen) { max = mSock; FD_SET(mSock, &read_fds); //添加文件描述符到文件描述符集read_fds } FD_SET(mCtrlPipe[0], &read_fds); if (mCtrlPipe[0] > max) max = mCtrlPipe[0]; pthread_mutex_lock(&mClientsLock); for (it = mClients->begin(); it != mClients->end(); ++it) { //将容器nClient中的sockets添加到文件描述符集read_fds FD_SET((*it)->getSocket(), &read_fds); if ((*it)->getSocket() > max) max = (*it)->getSocket(); } pthread_mutex_unlock(&mClientsLock); if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) { //等待文件描述符中某一文件描述符或者说socket有数据到来 continue; } else if (!rc) continue; if (FD_ISSET(mCtrlPipe[0], &read_fds)) //管道 break; if (mListen && FD_ISSET(mSock, &read_fds)) { //监听套接字 struct sockaddr addr; socklen_t alen = sizeof(addr); int c; if ((c = accept(mSock, &addr, &alen)) < 0) { //接收链接请求,建立连接,如果成功c即为建立链接后的数据交换套接字,将其添加到mClient器; continue; } pthread_mutex_lock(&mClientsLock); mClients->push_back(new SocketClient(c)); pthread_mutex_unlock(&mClientsLock); } do { //非监听套接字处理 pthread_mutex_lock(&mClientsLock); for (it = mClients->begin(); it != mClients->end(); ++it) { int fd = (*it)->getSocket(); if (FD_ISSET(fd, &read_fds)) { pthread_mutex_unlock(&mClientsLock); if (!onDataAvailable(*it)) { //调用相应的数据读取函数,读取数据 close(fd); pthread_mutex_lock(&mClientsLock); delete *it; it = mClients->erase(it); pthread_mutex_unlock(&mClientsLock); } FD_CLR(fd, &read_fds); continue; } } pthread_mutex_unlock(&mClientsLock); } while (0); } }


分析函数: onDataAvailable(*it)
onDataAvailable是在类SocketListener中定义的纯虚函数,在Android2.2中共有五个类继承该类,并对函数onDataAvailable进行了实现,分别是:
DhcpListener(system/core/nexus)、
FrameworkListener(system/core/libsysutils/src)、
NetlinkListener(system/core/libsysutils/src)、
SupplicantListener(system/core/nexus)、
TiwlanEventListener(system/core/nexus);

针对Netlink创建的套接字,是由NetlinkHandler对象调用的startListen函数,并开启的相关线程,而且NetlinkHandler继承了NetlinkListener,
所以此处调用的是NetlinkListener类的成员函数onDataAvailable;
system/core/libsysutils/src/NetlinkListener.cpp
bool NetlinkListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); int count; if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) { } //读取数据 NetlinkEvent *evt = new NetlinkEvent(); if (!evt->decode(mBuffer, count)) { } onEvent(evt); //NetlinkListener类定义了纯虚函数,其子类NetlinkHandler对其进行了实现,所以此处调用子类NetlinkHandler的onEvent函数; out: delete evt; return true; }


onEvent 函数分析:
system/vold/NetlinkHandler.cpp

void NetlinkHandler::onEvent(NetlinkEvent *evt) { VolumeManager *vm = VolumeManager::Instance(); const char *subsys = evt->getSubsystem(); if (!subsys) { SLOGW("No subsystem found in netlink event"); return; } if (!strcmp(subsys, "block")) { vm->handleBlockEvent(evt); } else if (!strcmp(subsys, "switch")) { vm->handleSwitchEvent(evt); } else if (!strcmp(subsys, "battery")) { } else if (!strcmp(subsys, "power_supply")) { } }
这下子又回到了vold进程中,到此在android中vold相关部分的Netlink event传递机制分析完成,下一步该分析真正的vold管理部分了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值