总结:NetlinkManager是直接接收Kernel消息的模块,其从kernel接收Uevent事件,然后转换成一个NetlinkEvent对象,最后调用VolumeManager的处理函数继续后续操作。NetLinkEvent以及Uevent存在的目的就是告知上层底层发生的一切。
1、system/vold/NetlinkManager.cpp
由之前的了解,可知,在系统启动后,NetlinkManager会做以下事情:
1、nm->setBroadcaster((SocketListener *) cl);
2、if (nm->start()) {
SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));
exit(1);
}
3、coldboot("/sys/block");
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
2、2:start方法:
首先初始化接收底层消息的socket,并为其开辟内存空间。
struct sockaddr_nl nladdr;
int sz = 64 * 1024;
int on = 1;
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) {
SLOGE("Unable to create uevent socket: %s", strerror(errno));
return -1;
}
执行bind操作:
if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
SLOGE("Unable to bind uevent socket: %s", strerror(errno));
goto out;
}
创建NetlinkHandle对象,并把创建好的socket传递给NetlinkHandle对象。
mHandler = new NetlinkHandler(mSock);
if (mHandler->start()) {
SLOGE("Unable to start NetlinkHandler: %s", strerror(errno));
goto out;
}
执行NetlinkHandle的start方法。
2.3:coldboot("/sys/block");方法
static void do_coldboot(DIR *d, int lvl)
{
struct dirent *de;
int dfd, fd;
dfd = dirfd(d);
fd = openat(dfd, "uevent", O_WRONLY);
if(fd >= 0) {
write(fd, "add\n", 4);
close(fd);
}
while((de = readdir(d))) {
DIR *d2;
if (de->d_name[0] == '.')
continue;
if (de->d_type != DT_DIR && lvl > 0)
continue;
fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);
if(fd < 0)
continue;
d2 = fdopendir(fd);
if(d2 == 0)
close(fd);
else {
do_coldboot(d2, lvl + 1);
closedir(d2);
}
}
}
此方法是往/sys/block文件夹下的设备文件中写入内容,从而触发kernel发送Uevent事件。
3、NetlinkHandler执行start方法
NetlinkHandler的start方法,最终会执行SocketListener中:
int NetlinkHandler::start() {
return this->startListener();
}
SocketListener
int SocketListener::startListener() {
return startListener(4);
}
int SocketListener::startListener(int backlog) {
if (!mSocketName && mSock == -1) {
SLOGE("Failed to start unbound listener");
errno = EINVAL;
return -1;
} else if (mSocketName) {
if ((mSock = android_get_control_socket(mSocketName)) < 0) {
SLOGE("Obtaining file descriptor socket '%s' failed: %s",
mSocketName, strerror(errno));
return -1;
}
SLOGV("got mSock = %d for %s", mSock, mSocketName);
}
if (mListen && listen(mSock, backlog) < 0) {
SLOGE("Unable to listen on socket (%s)", strerror(errno));
return -1;
} else if (!mListen)
mClients->push_back(new SocketClient(mSock, false, mUseCmdNum));
if (pipe(mCtrlPipe)) {
SLOGE("pipe failed (%s)", strerror(errno));
return -1;
}
if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) {
SLOGE("pthread_create (%s)", strerror(errno));
return -1;
}
return 0;
}
这里主要处理了3件事情:
1、以mSock作为参数,构建SocketClient,并加入到mClient中。
mClients->push_back(new SocketClient(mSock, false, mUseCmdNum));
2、创建管道,进行读取和写入操作。
if (pipe(mCtrlPipe)) {
SLOGE("pipe failed (%s)", strerror(errno));
return -1;
}
3、创建线程SocketListener,并执行。
if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) {
SLOGE("pthread_create (%s)", strerror(errno));
return -1;
}
5、那么我们接下来的流程就到了NetlinkHandler创建的线程的执行中。
void *SocketListener::threadStart(void *obj) {
SocketListener *me = reinterpret_cast<SocketListener *>(obj);
me->runListener();
pthread_exit(NULL);
return NULL;
}
执行runListener方法:
这个方法会做如下事情 :
socket获取kernel上报的NetLinkEvent并回调onEvent方法。
NetlinkEvent *evt = new NetlinkEvent();
if (evt->decode(mBuffer, count, mFormat)) {
onEvent(evt);
} else if (mFormat != NETLINK_FORMAT_BINARY) {
// Don't complain if parseBinaryNetlinkMessage returns false. That can
// just mean that the buffer contained no messages we're interested in.
SLOGE("Error decoding NetlinkEvent");
}
最终:NetLinkHandler方法执行onEvent方法:
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);
}
其会调用VolumeManager的handleBlockEvent方法。