Merge "liblog: android_log_event_list class permit -EBUSY retry"
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 78d0c07..28da9db 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -47,8 +47,9 @@
#include <logwrap/logwrap.h>
#include <private/android_logger.h> // for __android_log_is_debuggable()
+#include "fs_mgr.h"
+#include "fs_mgr_avb.h"
#include "fs_mgr_priv.h"
-#include "fs_mgr_priv_avb.h"
#define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
#define KEY_IN_FOOTER "footer"
@@ -819,7 +820,7 @@
return -1;
}
}
- if (!avb_handle->SetUpAvb(&fstab->recs[i])) {
+ if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
LERROR << "Failed to set up AVB on partition: "
<< fstab->recs[i].mount_point << ", skipping!";
/* Skips mounting the device. */
@@ -1031,7 +1032,7 @@
return -1;
}
}
- if (!avb_handle->SetUpAvb(&fstab->recs[i])) {
+ if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
LERROR << "Failed to set up AVB on partition: "
<< fstab->recs[i].mount_point << ", skipping!";
/* Skips mounting the device. */
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 76ec236..7c82bb1 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -38,9 +38,9 @@
#include <utils/Compat.h>
#include "fs_mgr.h"
+#include "fs_mgr_avb.h"
#include "fs_mgr_avb_ops.h"
#include "fs_mgr_priv.h"
-#include "fs_mgr_priv_avb.h"
#include "fs_mgr_priv_dm_ioctl.h"
#include "fs_mgr_priv_sha.h"
@@ -336,7 +336,8 @@
static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
const AvbHashtreeDescriptor& hashtree_desc,
- const std::string& salt, const std::string& root_digest) {
+ const std::string& salt, const std::string& root_digest,
+ bool wait_for_verity_dev) {
// Gets the device mapper fd.
android::base::unique_fd fd(open("/dev/device-mapper", O_RDWR));
if (fd < 0) {
@@ -375,13 +376,12 @@
// Marks the underlying block device as read-only.
fs_mgr_set_blk_ro(fstab_entry->blk_device);
- // TODO(bowgotsai): support verified all partition at boot.
// Updates fstab_rec->blk_device to verity device name.
free(fstab_entry->blk_device);
fstab_entry->blk_device = strdup(verity_blk_name.c_str());
// Makes sure we've set everything up properly.
- if (fs_mgr_test_access(verity_blk_name.c_str()) < 0) {
+ if (wait_for_verity_dev && fs_mgr_test_access(verity_blk_name.c_str()) < 0) {
return false;
}
@@ -519,7 +519,7 @@
return nullptr;
}
-bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry) {
+bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) {
if (!fstab_entry) return false;
if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) {
return false;
@@ -545,7 +545,8 @@
}
// Converts HASHTREE descriptor to verity_table_params.
- if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest)) {
+ if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest,
+ wait_for_verity_dev)) {
return false;
}
return true;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index dfbde18..dc73c24 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -768,6 +768,11 @@
return fstab->fs_mgr_flags & MF_VERIFY;
}
+int fs_mgr_is_avb(const struct fstab_rec *fstab)
+{
+ return fstab->fs_mgr_flags & MF_AVB;
+}
+
int fs_mgr_is_verifyatboot(const struct fstab_rec *fstab)
{
return fstab->fs_mgr_flags & MF_VERIFYATBOOT;
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 3c2fea4..cea70b4 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -123,6 +123,7 @@
int fs_mgr_is_nonremovable(const struct fstab_rec *fstab);
int fs_mgr_is_verified(const struct fstab_rec *fstab);
int fs_mgr_is_verifyatboot(const struct fstab_rec *fstab);
+int fs_mgr_is_avb(const struct fstab_rec *fstab);
int fs_mgr_is_encryptable(const struct fstab_rec *fstab);
int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab);
const char* fs_mgr_get_file_encryption_mode(const struct fstab_rec *fstab);
diff --git a/fs_mgr/fs_mgr_priv_avb.h b/fs_mgr/include/fs_mgr_avb.h
similarity index 83%
rename from fs_mgr/fs_mgr_priv_avb.h
rename to fs_mgr/include/fs_mgr_avb.h
index 99a033e..526a5ce 100644
--- a/fs_mgr/fs_mgr_priv_avb.h
+++ b/fs_mgr/include/fs_mgr_avb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef __CORE_FS_MGR_PRIV_AVB_H
-#define __CORE_FS_MGR_PRIV_AVB_H
+#ifndef __CORE_FS_MGR_AVB_H
+#define __CORE_FS_MGR_AVB_H
#include <memory>
#include <string>
@@ -63,18 +63,22 @@
static FsManagerAvbUniquePtr Open(const std::string& device_file_by_name_prefix);
// Sets up dm-verity on the given fstab entry.
+ // The 'wait_for_verity_dev' parameter makes this function wait for the
+ // verity device to get created before return.
// Returns true if the mount point is eligible to mount, it includes:
// - status_ is kFsMgrAvbHandleHashtreeDisabled or
// - status_ is kFsMgrAvbHandleSuccess and sending ioctl DM_TABLE_LOAD
// to load verity table is success.
// Otherwise, returns false.
- bool SetUpAvb(fstab_rec* fstab_entry);
+ bool SetUpAvb(fstab_rec* fstab_entry, bool wait_for_verity_dev);
- FsManagerAvbHandle(const FsManagerAvbHandle&) = delete; // no copy
- FsManagerAvbHandle& operator=(const FsManagerAvbHandle&) = delete; // no assignment
+ bool AvbHashtreeDisabled() { return status_ == kFsManagerAvbHandleHashtreeDisabled; }
- FsManagerAvbHandle(FsManagerAvbHandle&&) noexcept = delete; // no move
- FsManagerAvbHandle& operator=(FsManagerAvbHandle&&) noexcept = delete; // no move assignment
+ FsManagerAvbHandle(const FsManagerAvbHandle&) = delete; // no copy
+ FsManagerAvbHandle& operator=(const FsManagerAvbHandle&) = delete; // no assignment
+
+ FsManagerAvbHandle(FsManagerAvbHandle&&) noexcept = delete; // no move
+ FsManagerAvbHandle& operator=(FsManagerAvbHandle&&) noexcept = delete; // no move assignment
~FsManagerAvbHandle() {
if (avb_slot_data_) {
@@ -90,4 +94,4 @@
FsManagerAvbHandleStatus status_;
};
-#endif /* __CORE_FS_MGR_PRIV_AVB_H */
+#endif /* __CORE_FS_MGR_AVB_H */
diff --git a/init/Android.mk b/init/Android.mk
index dbbf40a..7e9b613 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -148,8 +148,9 @@
util_test.cpp \
LOCAL_SHARED_LIBRARIES += \
- libcutils \
libbase \
+ libcutils \
+ libselinux \
LOCAL_STATIC_LIBRARIES := libinit
LOCAL_SANITIZE := integer
diff --git a/init/devices.cpp b/init/devices.cpp
index 52f018b..6cd3564 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -604,94 +604,35 @@
remove_platform_device(path);
}
-static const char *parse_device_name(struct uevent *uevent, unsigned int len)
-{
- const char *name;
+static void handle_block_device_event(uevent* uevent) {
+ // if it's not a /dev device, nothing to do
+ if (uevent->major < 0 || uevent->minor < 0) return;
- /* if it's not a /dev device, nothing else to do */
- 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);
+ const char* base = "/dev/block/";
make_dir(base, 0755);
+ std::string name = android::base::Basename(uevent->path);
+ std::string devpath = base + name;
+
std::vector<std::string> links;
if (!strncmp(uevent->path, "/devices/", 9))
links = get_block_device_symlinks(uevent);
- handle_device(uevent->action, devpath, uevent->path, 1,
- uevent->major, uevent->minor, links);
+ handle_device(uevent->action, devpath.c_str(), uevent->path, 1, uevent->major, uevent->minor,
+ links);
}
-static bool assemble_devpath(char *devpath, const char *dirname,
- const char *devname)
-{
- 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 handle_generic_device_event(uevent* uevent) {
+ // if it's not a /dev device, nothing to do
+ if (uevent->major < 0 || uevent->minor < 0) return;
-static void mkdir_recursive_for_devpath(const char *devpath)
-{
- char dir[DEVPATH_LEN];
- char *slash;
+ std::string name = android::base::Basename(uevent->path);
+ ueventd_subsystem* subsystem = ueventd_subsystem_find_by_name(uevent->subsystem);
- strcpy(dir, 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);
+ std::string devpath;
if (subsystem) {
- const char *devname;
+ std::string devname;
switch (subsystem->devname_src) {
case DEVNAME_UEVENT_DEVNAME:
@@ -707,67 +648,35 @@
return;
}
- if (!assemble_devpath(devpath, subsystem->dirname, devname))
- return;
- mkdir_recursive_for_devpath(devpath);
+ // TODO: Remove std::string()
+ devpath = std::string(subsystem->dirname) + "/" + devname;
+ mkdir_recursive(android::base::Dirname(devpath), 0755);
} else if (!strncmp(uevent->subsystem, "usb", 3)) {
- if (!strcmp(uevent->subsystem, "usb")) {
+ if (!strcmp(uevent->subsystem, "usb")) {
if (uevent->device_name) {
- if (!assemble_devpath(devpath, "/dev", uevent->device_name))
- return;
- mkdir_recursive_for_devpath(devpath);
- }
- else {
- /* This imitates the file system that would be created
- * if we were using devfs instead.
- * Minors are broken up into groups of 128, starting at "001"
- */
- int bus_id = uevent->minor / 128 + 1;
- int device_id = uevent->minor % 128 + 1;
- /* build directories */
- make_dir("/dev/bus", 0755);
- make_dir("/dev/bus/usb", 0755);
- snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
- make_dir(devpath, 0755);
- snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
- }
- } 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);
+ // TODO: Remove std::string
+ devpath = "/dev/" + std::string(uevent->device_name);
+ } else {
+ // This imitates the file system that would be created
+ // if we were using devfs instead.
+ // Minors are broken up into groups of 128, starting at "001"
+ int bus_id = uevent->minor / 128 + 1;
+ int device_id = uevent->minor % 128 + 1;
+ devpath = android::base::StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
+ }
+ mkdir_recursive(android::base::Dirname(devpath), 0755);
+ } else {
+ // ignore other USB events
+ return;
+ }
+ } else {
+ devpath = "/dev/" + name;
+ }
- if (!devpath[0])
- snprintf(devpath, sizeof(devpath), "%s%s", base, name);
+ auto links = get_character_device_symlinks(uevent);
- handle_device(uevent->action, devpath, uevent->path, 0,
- uevent->major, uevent->minor, links);
+ handle_device(uevent->action, devpath.c_str(), uevent->path, 0, uevent->major, uevent->minor,
+ links);
}
static void handle_device_event(struct uevent *uevent)
diff --git a/init/util.cpp b/init/util.cpp
index bbc59cb..32ae93d 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -194,37 +194,18 @@
return success;
}
-int mkdir_recursive(const char *pathname, mode_t mode)
-{
- char buf[128];
- const char *slash;
- const char *p = pathname;
- int width;
- int ret;
- struct stat info;
-
- 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;
+int mkdir_recursive(const std::string& path, mode_t mode) {
+ std::string::size_type slash = 0;
+ while ((slash = path.find('/', slash + 1)) != std::string::npos) {
+ auto directory = path.substr(0, slash);
+ struct stat info;
+ if (stat(directory.c_str(), &info) != 0) {
+ auto ret = make_dir(directory.c_str(), mode);
+ if (ret && errno != EEXIST) return ret;
}
}
- ret = make_dir(pathname, mode);
- if (ret && errno != EEXIST)
- return ret;
+ auto ret = make_dir(path.c_str(), mode);
+ if (ret && errno != EEXIST) return ret;
return 0;
}
diff --git a/init/util.h b/init/util.h
index 38a7bdb..0bb9cdf 100644
--- a/init/util.h
+++ b/init/util.h
@@ -60,7 +60,7 @@
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);
void import_kernel_cmdline(bool in_qemu,
const std::function<void(const std::string&, const std::string&, bool)>&);
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 0c0350a..b8b409a 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -120,3 +120,39 @@
EXPECT_EQ(UINT_MAX, decode_uid("toot"));
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()));
+}
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 579ee32..1609ef2 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -1,5 +1,37 @@
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
# sysfs attributes, not on arbitrary paths.