Snap for 5733735 from 1674790b4cabab6cedc4dfefb9829f96ba8b6d5b to qt-c2f2-release
Change-Id: Id77486e62141d7877fc6223919f59ca77f6e0dff
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 0a6014d..f21d529 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -32,7 +32,6 @@
#include <unistd.h>
#include <algorithm>
-#include <map>
#include <memory>
#include <string>
#include <vector>
@@ -517,10 +516,166 @@
return ret;
}
+bool fs_mgr_overlayfs_set_shared_mount(const std::string& mount_point, bool shared_flag) {
+ auto ret = mount(nullptr, mount_point.c_str(), nullptr, shared_flag ? MS_SHARED : MS_PRIVATE,
+ nullptr);
+ if (ret) {
+ PERROR << "__mount(target=" << mount_point
+ << ",flag=" << (shared_flag ? "MS_SHARED" : "MS_PRIVATE") << ")=" << ret;
+ return false;
+ }
+ return true;
+}
+
+bool fs_mgr_overlayfs_move_mount(const std::string& source, const std::string& target) {
+ auto ret = mount(source.c_str(), target.c_str(), nullptr, MS_MOVE, nullptr);
+ if (ret) {
+ PERROR << "__mount(source=" << source << ",target=" << target << ",flag=MS_MOVE)=" << ret;
+ return false;
+ }
+ return true;
+}
+
+struct mount_info {
+ std::string mount_point;
+ bool shared_flag;
+};
+
+std::vector<mount_info> ReadMountinfoFromFile(const std::string& path) {
+ std::vector<mount_info> info;
+
+ auto file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+ if (!file) {
+ PERROR << __FUNCTION__ << "(): cannot open file: '" << path << "'";
+ return info;
+ }
+
+ ssize_t len;
+ size_t alloc_len = 0;
+ char* line = nullptr;
+ while ((len = getline(&line, &alloc_len, file.get())) != -1) {
+ /* if the last character is a newline, shorten the string by 1 byte */
+ if (line[len - 1] == '\n') {
+ line[len - 1] = '\0';
+ }
+
+ static constexpr char delim[] = " \t";
+ char* save_ptr;
+ if (!strtok_r(line, delim, &save_ptr)) {
+ LERROR << "Error parsing mount ID";
+ break;
+ }
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing parent ID";
+ break;
+ }
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing mount source";
+ break;
+ }
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing root";
+ break;
+ }
+
+ char* p;
+ if (!(p = strtok_r(nullptr, delim, &save_ptr))) {
+ LERROR << "Error parsing mount_point";
+ break;
+ }
+ mount_info entry = {p, false};
+
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing mount_flags";
+ break;
+ }
+
+ while ((p = strtok_r(nullptr, delim, &save_ptr))) {
+ if ((p[0] == '-') && (p[1] == '\0')) break;
+ if (android::base::StartsWith(p, "shared:")) entry.shared_flag = true;
+ }
+ if (!p) {
+ LERROR << "Error parsing fields";
+ break;
+ }
+ info.emplace_back(std::move(entry));
+ }
+
+ free(line);
+ if (info.empty()) {
+ LERROR << __FUNCTION__ << "(): failed to load mountinfo from : '" << path << "'";
+ }
+ return info;
+}
+
bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
auto options = fs_mgr_get_overlayfs_options(mount_point);
if (options.empty()) return false;
+ auto retval = true;
+ auto save_errno = errno;
+
+ struct move_entry {
+ std::string mount_point;
+ std::string dir;
+ bool shared_flag;
+ };
+ std::vector<move_entry> move;
+ auto parent_private = false;
+ auto parent_made_private = false;
+ auto dev_private = false;
+ auto dev_made_private = false;
+ for (auto& entry : ReadMountinfoFromFile("/proc/self/mountinfo")) {
+ if ((entry.mount_point == mount_point) && !entry.shared_flag) {
+ parent_private = true;
+ }
+ if ((entry.mount_point == "/dev") && !entry.shared_flag) {
+ dev_private = true;
+ }
+
+ if (!android::base::StartsWith(entry.mount_point, mount_point + "/")) {
+ continue;
+ }
+ if (std::find_if(move.begin(), move.end(), [&entry](const auto& it) {
+ return android::base::StartsWith(entry.mount_point, it.mount_point + "/");
+ }) != move.end()) {
+ continue;
+ }
+
+ // use as the bound directory in /dev.
+ auto new_context = fs_mgr_get_context(entry.mount_point);
+ if (!new_context.empty() && setfscreatecon(new_context.c_str())) {
+ PERROR << "setfscreatecon " << new_context;
+ }
+ move_entry new_entry = {std::move(entry.mount_point), "/dev/TemporaryDir-XXXXXX",
+ entry.shared_flag};
+ const auto target = mkdtemp(new_entry.dir.data());
+ if (!target) {
+ retval = false;
+ save_errno = errno;
+ PERROR << "temporary directory for MS_BIND";
+ setfscreatecon(nullptr);
+ continue;
+ }
+ setfscreatecon(nullptr);
+
+ if (!parent_private && !parent_made_private) {
+ parent_made_private = fs_mgr_overlayfs_set_shared_mount(mount_point, false);
+ }
+ if (new_entry.shared_flag) {
+ new_entry.shared_flag = fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, false);
+ }
+ if (!fs_mgr_overlayfs_move_mount(new_entry.mount_point, new_entry.dir)) {
+ retval = false;
+ save_errno = errno;
+ if (new_entry.shared_flag) {
+ fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, true);
+ }
+ continue;
+ }
+ move.emplace_back(std::move(new_entry));
+ }
+
// hijack __mount() report format to help triage
auto report = "__mount(source=overlay,target="s + mount_point + ",type=overlay";
const auto opt_list = android::base::Split(options, ",");
@@ -535,12 +690,38 @@
auto ret = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_RELATIME,
options.c_str());
if (ret) {
+ retval = false;
+ save_errno = errno;
PERROR << report << ret;
- return false;
} else {
LINFO << report << ret;
- return true;
}
+
+ // Move submounts back.
+ for (const auto& entry : move) {
+ if (!dev_private && !dev_made_private) {
+ dev_made_private = fs_mgr_overlayfs_set_shared_mount("/dev", false);
+ }
+
+ if (!fs_mgr_overlayfs_move_mount(entry.dir, entry.mount_point)) {
+ retval = false;
+ save_errno = errno;
+ } else if (entry.shared_flag &&
+ !fs_mgr_overlayfs_set_shared_mount(entry.mount_point, true)) {
+ retval = false;
+ save_errno = errno;
+ }
+ rmdir(entry.dir.c_str());
+ }
+ if (dev_made_private) {
+ fs_mgr_overlayfs_set_shared_mount("/dev", true);
+ }
+ if (parent_made_private) {
+ fs_mgr_overlayfs_set_shared_mount(mount_point, true);
+ }
+
+ errno = save_errno;
+ return retval;
}
// Mount kScratchMountPoint
diff --git a/usbd/usbd.cpp b/usbd/usbd.cpp
index 191fb92..6e24d8e 100644
--- a/usbd/usbd.cpp
+++ b/usbd/usbd.cpp
@@ -24,8 +24,6 @@
#include <hidl/HidlTransportSupport.h>
-#define PERSISTENT_USB_CONFIG "persist.sys.usb.config"
-
using android::base::GetProperty;
using android::base::SetProperty;
using android::hardware::configureRpcThreadpool;
@@ -34,14 +32,15 @@
using android::hardware::Return;
int main(int /*argc*/, char** /*argv*/) {
- configureRpcThreadpool(1, true /*callerWillJoin*/);
+ if (GetProperty("ro.bootmode", "") == "charger") exit(0);
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
android::sp<IUsbGadget> gadget = IUsbGadget::getService();
Return<void> ret;
if (gadget != nullptr) {
LOG(INFO) << "Usb HAL found.";
- std::string function = GetProperty(PERSISTENT_USB_CONFIG, "");
+ std::string function = GetProperty("persist.sys.usb.config", "");
if (function == "adb") {
LOG(INFO) << "peristent prop is adb";
SetProperty("ctl.start", "adbd");