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管理部分了
android 2.2 vold (二)---Vold 中 Netlink事件通信机制分析
最新推荐文章于 2021-06-03 11:46:52 发布