Merge changes Ie5ec609a,I5a2ac369,I690137b5 am: 659b78ed10 am: 01b87aac9c
am: 8d9eee4f2b
Change-Id: I5cd7d00f71bfd3970189481f381629cedc358c9b
This commit is contained in:
commit
aa85663027
6 changed files with 123 additions and 164 deletions
|
|
@ -148,8 +148,9 @@ LOCAL_SRC_FILES := \
|
||||||
util_test.cpp \
|
util_test.cpp \
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES += \
|
LOCAL_SHARED_LIBRARIES += \
|
||||||
libcutils \
|
|
||||||
libbase \
|
libbase \
|
||||||
|
libcutils \
|
||||||
|
libselinux \
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := libinit
|
LOCAL_STATIC_LIBRARIES := libinit
|
||||||
LOCAL_SANITIZE := integer
|
LOCAL_SANITIZE := integer
|
||||||
|
|
|
||||||
173
init/devices.cpp
173
init/devices.cpp
|
|
@ -604,94 +604,35 @@ static void handle_platform_device_event(struct uevent *uevent)
|
||||||
remove_platform_device(path);
|
remove_platform_device(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *parse_device_name(struct uevent *uevent, unsigned int len)
|
static void handle_block_device_event(uevent* uevent) {
|
||||||
{
|
// if it's not a /dev device, nothing to do
|
||||||
const char *name;
|
if (uevent->major < 0 || uevent->minor < 0) return;
|
||||||
|
|
||||||
/* if it's not a /dev device, nothing else to do */
|
const char* base = "/dev/block/";
|
||||||
if((uevent->major < 0) || (uevent->minor < 0))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* do we have a name? */
|
|
||||||
name = strrchr(uevent->path, '/');
|
|
||||||
if(!name)
|
|
||||||
return NULL;
|
|
||||||
name++;
|
|
||||||
|
|
||||||
/* too-long names would overrun our buffer */
|
|
||||||
if(strlen(name) > len) {
|
|
||||||
LOG(ERROR) << "DEVPATH=" << name << " exceeds " << len << "-character limit on filename; ignoring event";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEVPATH_LEN 96
|
|
||||||
#define MAX_DEV_NAME 64
|
|
||||||
|
|
||||||
static void handle_block_device_event(struct uevent *uevent)
|
|
||||||
{
|
|
||||||
const char *base = "/dev/block/";
|
|
||||||
const char *name;
|
|
||||||
char devpath[DEVPATH_LEN];
|
|
||||||
|
|
||||||
name = parse_device_name(uevent, MAX_DEV_NAME);
|
|
||||||
if (!name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
snprintf(devpath, sizeof(devpath), "%s%s", base, name);
|
|
||||||
make_dir(base, 0755);
|
make_dir(base, 0755);
|
||||||
|
|
||||||
|
std::string name = android::base::Basename(uevent->path);
|
||||||
|
std::string devpath = base + name;
|
||||||
|
|
||||||
std::vector<std::string> links;
|
std::vector<std::string> links;
|
||||||
if (!strncmp(uevent->path, "/devices/", 9))
|
if (!strncmp(uevent->path, "/devices/", 9))
|
||||||
links = get_block_device_symlinks(uevent);
|
links = get_block_device_symlinks(uevent);
|
||||||
|
|
||||||
handle_device(uevent->action, devpath, uevent->path, 1,
|
handle_device(uevent->action, devpath.c_str(), uevent->path, 1, uevent->major, uevent->minor,
|
||||||
uevent->major, uevent->minor, links);
|
links);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool assemble_devpath(char *devpath, const char *dirname,
|
static void handle_generic_device_event(uevent* uevent) {
|
||||||
const char *devname)
|
// if it's not a /dev device, nothing to do
|
||||||
{
|
if (uevent->major < 0 || uevent->minor < 0) return;
|
||||||
int s = snprintf(devpath, DEVPATH_LEN, "%s/%s", dirname, devname);
|
|
||||||
if (s < 0) {
|
|
||||||
PLOG(ERROR) << "failed to assemble device path; ignoring event";
|
|
||||||
return false;
|
|
||||||
} else if (s >= DEVPATH_LEN) {
|
|
||||||
LOG(ERROR) << dirname << "/" << devname
|
|
||||||
<< " exceeds " << DEVPATH_LEN << "-character limit on path; ignoring event";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mkdir_recursive_for_devpath(const char *devpath)
|
std::string name = android::base::Basename(uevent->path);
|
||||||
{
|
ueventd_subsystem* subsystem = ueventd_subsystem_find_by_name(uevent->subsystem);
|
||||||
char dir[DEVPATH_LEN];
|
|
||||||
char *slash;
|
|
||||||
|
|
||||||
strcpy(dir, devpath);
|
std::string devpath;
|
||||||
slash = strrchr(dir, '/');
|
|
||||||
*slash = '\0';
|
|
||||||
mkdir_recursive(dir, 0755);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_generic_device_event(struct uevent *uevent)
|
|
||||||
{
|
|
||||||
const char *base;
|
|
||||||
const char *name;
|
|
||||||
char devpath[DEVPATH_LEN] = {0};
|
|
||||||
|
|
||||||
name = parse_device_name(uevent, MAX_DEV_NAME);
|
|
||||||
if (!name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct ueventd_subsystem *subsystem =
|
|
||||||
ueventd_subsystem_find_by_name(uevent->subsystem);
|
|
||||||
|
|
||||||
if (subsystem) {
|
if (subsystem) {
|
||||||
const char *devname;
|
std::string devname;
|
||||||
|
|
||||||
switch (subsystem->devname_src) {
|
switch (subsystem->devname_src) {
|
||||||
case DEVNAME_UEVENT_DEVNAME:
|
case DEVNAME_UEVENT_DEVNAME:
|
||||||
|
|
@ -707,67 +648,35 @@ static void handle_generic_device_event(struct uevent *uevent)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assemble_devpath(devpath, subsystem->dirname, devname))
|
// TODO: Remove std::string()
|
||||||
return;
|
devpath = std::string(subsystem->dirname) + "/" + devname;
|
||||||
mkdir_recursive_for_devpath(devpath);
|
mkdir_recursive(android::base::Dirname(devpath), 0755);
|
||||||
} else if (!strncmp(uevent->subsystem, "usb", 3)) {
|
} else if (!strncmp(uevent->subsystem, "usb", 3)) {
|
||||||
if (!strcmp(uevent->subsystem, "usb")) {
|
if (!strcmp(uevent->subsystem, "usb")) {
|
||||||
if (uevent->device_name) {
|
if (uevent->device_name) {
|
||||||
if (!assemble_devpath(devpath, "/dev", uevent->device_name))
|
// TODO: Remove std::string
|
||||||
return;
|
devpath = "/dev/" + std::string(uevent->device_name);
|
||||||
mkdir_recursive_for_devpath(devpath);
|
} else {
|
||||||
}
|
// This imitates the file system that would be created
|
||||||
else {
|
// if we were using devfs instead.
|
||||||
/* This imitates the file system that would be created
|
// Minors are broken up into groups of 128, starting at "001"
|
||||||
* if we were using devfs instead.
|
int bus_id = uevent->minor / 128 + 1;
|
||||||
* Minors are broken up into groups of 128, starting at "001"
|
int device_id = uevent->minor % 128 + 1;
|
||||||
*/
|
devpath = android::base::StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
|
||||||
int bus_id = uevent->minor / 128 + 1;
|
}
|
||||||
int device_id = uevent->minor % 128 + 1;
|
mkdir_recursive(android::base::Dirname(devpath), 0755);
|
||||||
/* build directories */
|
} else {
|
||||||
make_dir("/dev/bus", 0755);
|
// ignore other USB events
|
||||||
make_dir("/dev/bus/usb", 0755);
|
return;
|
||||||
snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
|
}
|
||||||
make_dir(devpath, 0755);
|
} else {
|
||||||
snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
|
devpath = "/dev/" + name;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* ignore other USB events */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (!strncmp(uevent->subsystem, "graphics", 8)) {
|
|
||||||
base = "/dev/graphics/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if (!strncmp(uevent->subsystem, "drm", 3)) {
|
|
||||||
base = "/dev/dri/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if (!strncmp(uevent->subsystem, "oncrpc", 6)) {
|
|
||||||
base = "/dev/oncrpc/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if (!strncmp(uevent->subsystem, "adsp", 4)) {
|
|
||||||
base = "/dev/adsp/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if (!strncmp(uevent->subsystem, "msm_camera", 10)) {
|
|
||||||
base = "/dev/msm_camera/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if(!strncmp(uevent->subsystem, "input", 5)) {
|
|
||||||
base = "/dev/input/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if(!strncmp(uevent->subsystem, "mtd", 3)) {
|
|
||||||
base = "/dev/mtd/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else if(!strncmp(uevent->subsystem, "sound", 5)) {
|
|
||||||
base = "/dev/snd/";
|
|
||||||
make_dir(base, 0755);
|
|
||||||
} else
|
|
||||||
base = "/dev/";
|
|
||||||
auto links = get_character_device_symlinks(uevent);
|
|
||||||
|
|
||||||
if (!devpath[0])
|
auto links = get_character_device_symlinks(uevent);
|
||||||
snprintf(devpath, sizeof(devpath), "%s%s", base, name);
|
|
||||||
|
|
||||||
handle_device(uevent->action, devpath, uevent->path, 0,
|
handle_device(uevent->action, devpath.c_str(), uevent->path, 0, uevent->major, uevent->minor,
|
||||||
uevent->major, uevent->minor, links);
|
links);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_device_event(struct uevent *uevent)
|
static void handle_device_event(struct uevent *uevent)
|
||||||
|
|
|
||||||
|
|
@ -194,37 +194,18 @@ bool write_file(const std::string& path, const std::string& content) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mkdir_recursive(const char *pathname, mode_t mode)
|
int mkdir_recursive(const std::string& path, mode_t mode) {
|
||||||
{
|
std::string::size_type slash = 0;
|
||||||
char buf[128];
|
while ((slash = path.find('/', slash + 1)) != std::string::npos) {
|
||||||
const char *slash;
|
auto directory = path.substr(0, slash);
|
||||||
const char *p = pathname;
|
struct stat info;
|
||||||
int width;
|
if (stat(directory.c_str(), &info) != 0) {
|
||||||
int ret;
|
auto ret = make_dir(directory.c_str(), mode);
|
||||||
struct stat info;
|
if (ret && errno != EEXIST) return ret;
|
||||||
|
|
||||||
while ((slash = strchr(p, '/')) != NULL) {
|
|
||||||
width = slash - pathname;
|
|
||||||
p = slash + 1;
|
|
||||||
if (width < 0)
|
|
||||||
break;
|
|
||||||
if (width == 0)
|
|
||||||
continue;
|
|
||||||
if ((unsigned int)width > sizeof(buf) - 1) {
|
|
||||||
LOG(ERROR) << "path too long for mkdir_recursive";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(buf, pathname, width);
|
|
||||||
buf[width] = 0;
|
|
||||||
if (stat(buf, &info) != 0) {
|
|
||||||
ret = make_dir(buf, mode);
|
|
||||||
if (ret && errno != EEXIST)
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = make_dir(pathname, mode);
|
auto ret = make_dir(path.c_str(), mode);
|
||||||
if (ret && errno != EEXIST)
|
if (ret && errno != EEXIST) return ret;
|
||||||
return ret;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ std::ostream& operator<<(std::ostream& os, const Timer& t);
|
||||||
|
|
||||||
unsigned int decode_uid(const char *s);
|
unsigned int decode_uid(const char *s);
|
||||||
|
|
||||||
int mkdir_recursive(const char *pathname, mode_t mode);
|
int mkdir_recursive(const std::string& pathname, mode_t mode);
|
||||||
int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
|
int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
|
||||||
void import_kernel_cmdline(bool in_qemu,
|
void import_kernel_cmdline(bool in_qemu,
|
||||||
const std::function<void(const std::string&, const std::string&, bool)>&);
|
const std::function<void(const std::string&, const std::string&, bool)>&);
|
||||||
|
|
|
||||||
|
|
@ -120,3 +120,39 @@ TEST(util, decode_uid) {
|
||||||
EXPECT_EQ(UINT_MAX, decode_uid("toot"));
|
EXPECT_EQ(UINT_MAX, decode_uid("toot"));
|
||||||
EXPECT_EQ(123U, decode_uid("123"));
|
EXPECT_EQ(123U, decode_uid("123"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(util, is_dir) {
|
||||||
|
TemporaryDir test_dir;
|
||||||
|
EXPECT_TRUE(is_dir(test_dir.path));
|
||||||
|
TemporaryFile tf;
|
||||||
|
EXPECT_FALSE(is_dir(tf.path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// sehandle is needed for make_dir()
|
||||||
|
// TODO: Remove once sehandle is encapsulated
|
||||||
|
#include <selinux/label.h>
|
||||||
|
selabel_handle* sehandle;
|
||||||
|
|
||||||
|
TEST(util, mkdir_recursive) {
|
||||||
|
TemporaryDir test_dir;
|
||||||
|
std::string path = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
|
||||||
|
EXPECT_EQ(0, mkdir_recursive(path, 0755));
|
||||||
|
std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
|
||||||
|
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||||
|
std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
|
||||||
|
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||||
|
std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
|
||||||
|
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(util, mkdir_recursive_extra_slashes) {
|
||||||
|
TemporaryDir test_dir;
|
||||||
|
std::string path = android::base::StringPrintf("%s/three////directories/deep//", test_dir.path);
|
||||||
|
EXPECT_EQ(0, mkdir_recursive(path, 0755));
|
||||||
|
std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
|
||||||
|
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||||
|
std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
|
||||||
|
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||||
|
std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
|
||||||
|
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,37 @@
|
||||||
subsystem adf
|
subsystem adf
|
||||||
devname uevent_devname
|
devname uevent_devname
|
||||||
|
|
||||||
|
subsystem graphics
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/graphics
|
||||||
|
|
||||||
|
subsystem drm
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/dri
|
||||||
|
|
||||||
|
subsystem oncrpc
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/oncrpc
|
||||||
|
|
||||||
|
subsystem adsp
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/adsp
|
||||||
|
|
||||||
|
subsystem msm_camera
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/msm_camera
|
||||||
|
|
||||||
|
subsystem input
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/input
|
||||||
|
|
||||||
|
subsystem mtd
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/mtd
|
||||||
|
|
||||||
|
subsystem sound
|
||||||
|
devname uevent_devpath
|
||||||
|
dirname /dev/snd
|
||||||
|
|
||||||
# ueventd can only set permissions on device nodes and their associated
|
# ueventd can only set permissions on device nodes and their associated
|
||||||
# sysfs attributes, not on arbitrary paths.
|
# sysfs attributes, not on arbitrary paths.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue