Files
SDK_RK3288/system/vold/NetlinkManager.cpp

113 lines
2.9 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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>
#define LOG_TAG "Vold"
#include <cutils/log.h>
#include "NetlinkManager.h"
#include "NetlinkHandler.h"
NetlinkManager *NetlinkManager::sInstance = NULL;
NetlinkManager *NetlinkManager::Instance() {
if (!sInstance)
sInstance = new NetlinkManager();
return sInstance;
}
NetlinkManager::NetlinkManager() {
mBroadcaster = NULL;
}
NetlinkManager::~NetlinkManager() {
}
int NetlinkManager::start() {
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();/* 为接收或发送消息的进程的 ID如果希望内核处理消息为多播消息
* 就把该字段设置为 0否则设置为处理消息的进程 ID
*/
nladdr.nl_groups = 0xffffffff;/* 用于指定多播组bind 函数用于把调用进程加入到该字段指定
* 的多播组,如果设置为 0表示调用者不加入任何多播组。
*/
if ((mSock = socket(PF_NETLINK,
SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
SLOGE("Unable to create uevent socket: %s", strerror(errno));
return -1;
}
if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
SLOGE("Unable to set uevent socket SO_RCVBUFFORCE option: %s", strerror(errno));
goto out;
}
if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
SLOGE("Unable to set uevent socket SO_PASSCRED option: %s", strerror(errno));
goto out;
}
if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
SLOGE("Unable to bind uevent socket: %s", strerror(errno));
goto out;
}
mHandler = new NetlinkHandler(mSock);
if (mHandler->start()) {
SLOGE("Unable to start NetlinkHandler: %s", strerror(errno));
goto out;
}
return 0;
out:
close(mSock);
return -1;
}
int NetlinkManager::stop() {
int status = 0;
if (mHandler->stop()) {
SLOGE("Unable to stop NetlinkHandler: %s", strerror(errno));
status = -1;
}
delete mHandler;
mHandler = NULL;
close(mSock);
mSock = -1;
return status;
}