summaryrefslogtreecommitdiffstats
path: root/init/mount_handler.cpp
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2019-03-25 14:24:32 -0700
committerMark Salyzyn <salyzyn@google.com>2019-03-27 20:50:39 +0000
commit793f4b503e200a29638e289b3ad85422f3d187f2 (patch)
tree4caa84f21e1291cc014b529c024b0df28d7f6688 /init/mount_handler.cpp
parent7f43e9fa40d5440f77a9a0b46edaad9d1b69bd8a (diff)
downloadsystem_core-793f4b503e200a29638e289b3ad85422f3d187f2.tar.gz
system_core-793f4b503e200a29638e289b3ad85422f3d187f2.tar.bz2
system_core-793f4b503e200a29638e289b3ad85422f3d187f2.zip
init: mount_handler: system-as-root (legacy)
On marlin, dev.mnt.blk.root is empty. Issue is shared for all devices that are system-as-root. /dev/root /proc/mounts entry exists before the associated block device is instantiated by ueventd. As a result when the device shows up the root mount is updated late when the next mount inotify trigger occurs, delay which we will accept. But the property entries are added before removed in the loop which causes the ultimate property entry for root to report empty. Add /dev/block/dm-0, remove /dev/root, for property dev.mnt.blk.root. Fix is to change to Remove before Adding. Remove /dev/root, then add /dev/block/dm-0. On system-as-root as well, can not just use fstab. Determine if a dm-verity reference is wrapped around system and use that instead. Add some additional filtration of loop and APEX mounts to reduce property noise. Fix issue with creating the std:string line holder from getline(3). Test: manual on marlin Bug: 124072565 Change-Id: Ief2e1a6f559cbcbc87273fc2db35c675bb972f43
Diffstat (limited to 'init/mount_handler.cpp')
-rw-r--r--init/mount_handler.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/init/mount_handler.cpp b/init/mount_handler.cpp
index 12dfc6ddc..c8f0e7691 100644
--- a/init/mount_handler.cpp
+++ b/init/mount_handler.cpp
@@ -27,6 +27,7 @@
#include <algorithm>
#include <string>
#include <utility>
+#include <vector>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -34,6 +35,7 @@
#include <android-base/strings.h>
#include <fs_mgr.h>
#include <fstab/fstab.h>
+#include <libdm/dm.h>
#include "epoll.h"
#include "property_service.h"
@@ -47,8 +49,13 @@ MountHandlerEntry ParseMount(const std::string& line) {
auto fields = android::base::Split(line, " ");
while (fields.size() < 3) fields.emplace_back("");
if (fields[0] == "/dev/root") {
- if (android::fs_mgr::Fstab fstab; android::fs_mgr::ReadDefaultFstab(&fstab)) {
- if (auto entry = GetEntryForMountPoint(&fstab, "/")) {
+ auto& dm = dm::DeviceMapper::Instance();
+ std::string path;
+ if (dm.GetDmDevicePathByName("system", &path) || dm.GetDmDevicePathByName("vroot", &path)) {
+ fields[0] = path;
+ } else if (android::fs_mgr::Fstab fstab; android::fs_mgr::ReadDefaultFstab(&fstab)) {
+ auto entry = GetEntryForMountPoint(&fstab, "/");
+ if (entry || (entry = GetEntryForMountPoint(&fstab, "/system"))) {
fields[0] = entry->blk_device;
}
}
@@ -77,14 +84,19 @@ void SetMountProperty(const MountHandlerEntry& entry, bool add) {
struct stat sb;
if (stat(queue.c_str(), &sb) || !S_ISDIR(sb.st_mode)) value = "";
if (stat(entry.mount_point.c_str(), &sb) || !S_ISDIR(sb.st_mode)) value = "";
- // Skip the noise associated with APEX until there is a need
+ // Clear the noise associated with loopback and APEX.
if (android::base::StartsWith(value, "loop")) value = "";
+ if (android::base::StartsWith(entry.mount_point, "/apex/")) value = "";
}
- std::string property =
- "dev.mnt.blk" + ((entry.mount_point == "/") ? "/root" : entry.mount_point);
- std::replace(property.begin(), property.end(), '/', '.');
- if (value.empty() && android::base::GetProperty(property, "").empty()) return;
- property_set(property, value);
+ auto mount_prop = entry.mount_point;
+ if (mount_prop == "/") mount_prop = "/root";
+ std::replace(mount_prop.begin(), mount_prop.end(), '/', '.');
+ mount_prop = "dev.mnt.blk" + mount_prop;
+ // Set property even if its value does not change to trigger 'on property:'
+ // handling, except for clearing non-existent or already clear property.
+ // Goal is reduction of empty properties and associated triggers.
+ if (value.empty() && android::base::GetProperty(mount_prop, "").empty()) return;
+ property_set(mount_prop, value);
}
} // namespace
@@ -114,25 +126,27 @@ MountHandler::~MountHandler() {
void MountHandler::MountHandlerFunction() {
rewind(fp_.get());
+ std::vector<MountHandlerEntry> touched;
+ auto untouched = mounts_;
char* buf = nullptr;
size_t len = 0;
- auto untouched = mounts_;
while (getline(&buf, &len, fp_.get()) != -1) {
- auto entry = ParseMount(std::string(buf, len));
+ auto entry = ParseMount(std::string(buf));
auto match = untouched.find(entry);
if (match == untouched.end()) {
- SetMountProperty(entry, true);
- mounts_.emplace(std::move(entry));
+ touched.emplace_back(std::move(entry));
} else {
untouched.erase(match);
}
}
free(buf);
for (auto entry : untouched) {
- auto match = mounts_.find(entry);
- if (match == mounts_.end()) continue;
- mounts_.erase(match);
SetMountProperty(entry, false);
+ mounts_.erase(entry);
+ }
+ for (auto entry : touched) {
+ SetMountProperty(entry, true);
+ mounts_.emplace(std::move(entry));
}
}