Merge "Adds /dev/block/by-name/<partition> symlinks"
This commit is contained in:
commit
98214c81d1
6 changed files with 95 additions and 12 deletions
|
|
@ -686,6 +686,49 @@ static struct fstab *in_place_merge(struct fstab *a, struct fstab *b)
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extracts <device>s from the by-name symlinks specified in a fstab:
|
||||||
|
* /dev/block/<type>/<device>/by-name/<partition>
|
||||||
|
*
|
||||||
|
* <type> can be: platform, pci or vbd.
|
||||||
|
*
|
||||||
|
* For example, given the following entries in the input fstab:
|
||||||
|
* /dev/block/platform/soc/1da4000.ufshc/by-name/system
|
||||||
|
* /dev/block/pci/soc.0/f9824900.sdhci/by-name/vendor
|
||||||
|
* it returns a set { "soc/1da4000.ufshc", "soc.0/f9824900.sdhci" }.
|
||||||
|
*/
|
||||||
|
static std::set<std::string> extract_boot_devices(const fstab& fstab) {
|
||||||
|
std::set<std::string> boot_devices;
|
||||||
|
|
||||||
|
for (int i = 0; i < fstab.num_entries; i++) {
|
||||||
|
std::string blk_device(fstab.recs[i].blk_device);
|
||||||
|
// Skips blk_device that doesn't conform to the format.
|
||||||
|
if (!android::base::StartsWith(blk_device, "/dev/block") ||
|
||||||
|
android::base::StartsWith(blk_device, "/dev/block/by-name") ||
|
||||||
|
android::base::StartsWith(blk_device, "/dev/block/bootdevice/by-name")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Skips non-by_name blk_device.
|
||||||
|
// /dev/block/<type>/<device>/by-name/<partition>
|
||||||
|
// ^ slash_by_name
|
||||||
|
auto slash_by_name = blk_device.find("/by-name");
|
||||||
|
if (slash_by_name == std::string::npos) continue;
|
||||||
|
blk_device.erase(slash_by_name); // erases /by-name/<partition>
|
||||||
|
|
||||||
|
// Erases /dev/block/, now we have <type>/<device>
|
||||||
|
blk_device.erase(0, std::string("/dev/block/").size());
|
||||||
|
|
||||||
|
// <type>/<device>
|
||||||
|
// ^ first_slash
|
||||||
|
auto first_slash = blk_device.find('/');
|
||||||
|
if (first_slash == std::string::npos) continue;
|
||||||
|
|
||||||
|
auto boot_device = blk_device.substr(first_slash + 1);
|
||||||
|
if (!boot_device.empty()) boot_devices.insert(std::move(boot_device));
|
||||||
|
}
|
||||||
|
|
||||||
|
return boot_devices;
|
||||||
|
}
|
||||||
|
|
||||||
struct fstab *fs_mgr_read_fstab(const char *fstab_path)
|
struct fstab *fs_mgr_read_fstab(const char *fstab_path)
|
||||||
{
|
{
|
||||||
FILE *fstab_file;
|
FILE *fstab_file;
|
||||||
|
|
@ -863,6 +906,23 @@ struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const st
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<std::string> fs_mgr_get_boot_devices() {
|
||||||
|
// boot_devices can be specified in device tree.
|
||||||
|
std::string dt_value;
|
||||||
|
std::string file_name = get_android_dt_dir() + "/boot_devices";
|
||||||
|
if (read_dt_file(file_name, &dt_value)) {
|
||||||
|
auto boot_devices = android::base::Split(dt_value, ",");
|
||||||
|
return std::set<std::string>(boot_devices.begin(), boot_devices.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to extract boot devices from fstab.
|
||||||
|
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
||||||
|
fs_mgr_free_fstab);
|
||||||
|
if (fstab) return extract_boot_devices(*fstab);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab)
|
int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab)
|
||||||
{
|
{
|
||||||
return fstab->fs_mgr_flags & MF_VOLDMANAGED;
|
return fstab->fs_mgr_flags & MF_VOLDMANAGED;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -89,5 +90,6 @@ int fs_mgr_is_logical(const struct fstab_rec* fstab);
|
||||||
int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
|
int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
|
||||||
|
|
||||||
std::string fs_mgr_get_slot_suffix();
|
std::string fs_mgr_get_slot_suffix();
|
||||||
|
std::set<std::string> fs_mgr_get_boot_devices();
|
||||||
|
|
||||||
#endif /* __CORE_FS_TAB_H */
|
#endif /* __CORE_FS_TAB_H */
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,10 @@ std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev
|
||||||
<< partition_name_sanitized << "'";
|
<< partition_name_sanitized << "'";
|
||||||
}
|
}
|
||||||
links.emplace_back(link_path + "/by-name/" + partition_name_sanitized);
|
links.emplace_back(link_path + "/by-name/" + partition_name_sanitized);
|
||||||
|
// Adds symlink: /dev/block/by-name/<partition_name>.
|
||||||
|
if (boot_devices_.find(device) != boot_devices_.end()) {
|
||||||
|
links.emplace_back("/dev/block/by-name/" + partition_name_sanitized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto last_slash = uevent.path.rfind('/');
|
auto last_slash = uevent.path.rfind('/');
|
||||||
|
|
@ -346,8 +350,14 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
|
||||||
PLOG(ERROR) << "Failed to create directory " << Dirname(link);
|
PLOG(ERROR) << "Failed to create directory " << Dirname(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symlink(devpath.c_str(), link.c_str()) && errno != EEXIST) {
|
if (symlink(devpath.c_str(), link.c_str())) {
|
||||||
PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link;
|
if (errno != EEXIST) {
|
||||||
|
PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link;
|
||||||
|
} else if (std::string link_path;
|
||||||
|
Readlink(link, &link_path) && link_path != devpath) {
|
||||||
|
PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link
|
||||||
|
<< ", which already links to: " << link_path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -411,16 +421,18 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
|
||||||
|
|
||||||
DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
|
DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
|
||||||
std::vector<SysfsPermissions> sysfs_permissions,
|
std::vector<SysfsPermissions> sysfs_permissions,
|
||||||
std::vector<Subsystem> subsystems, bool skip_restorecon)
|
std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
|
||||||
|
bool skip_restorecon)
|
||||||
: dev_permissions_(std::move(dev_permissions)),
|
: dev_permissions_(std::move(dev_permissions)),
|
||||||
sysfs_permissions_(std::move(sysfs_permissions)),
|
sysfs_permissions_(std::move(sysfs_permissions)),
|
||||||
subsystems_(std::move(subsystems)),
|
subsystems_(std::move(subsystems)),
|
||||||
|
boot_devices_(std::move(boot_devices)),
|
||||||
skip_restorecon_(skip_restorecon),
|
skip_restorecon_(skip_restorecon),
|
||||||
sysfs_mount_point_("/sys") {}
|
sysfs_mount_point_("/sys") {}
|
||||||
|
|
||||||
DeviceHandler::DeviceHandler()
|
DeviceHandler::DeviceHandler()
|
||||||
: DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
|
: DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
|
||||||
std::vector<Subsystem>{}, false) {}
|
std::vector<Subsystem>{}, std::set<std::string>{}, false) {}
|
||||||
|
|
||||||
} // namespace init
|
} // namespace init
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -103,8 +104,8 @@ class DeviceHandler {
|
||||||
|
|
||||||
DeviceHandler();
|
DeviceHandler();
|
||||||
DeviceHandler(std::vector<Permissions> dev_permissions,
|
DeviceHandler(std::vector<Permissions> dev_permissions,
|
||||||
std::vector<SysfsPermissions> sysfs_permissions,
|
std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems,
|
||||||
std::vector<Subsystem> subsystems, bool skip_restorecon);
|
std::set<std::string> boot_devices, bool skip_restorecon);
|
||||||
~DeviceHandler(){};
|
~DeviceHandler(){};
|
||||||
|
|
||||||
void HandleDeviceEvent(const Uevent& uevent);
|
void HandleDeviceEvent(const Uevent& uevent);
|
||||||
|
|
@ -125,6 +126,7 @@ class DeviceHandler {
|
||||||
std::vector<Permissions> dev_permissions_;
|
std::vector<Permissions> dev_permissions_;
|
||||||
std::vector<SysfsPermissions> sysfs_permissions_;
|
std::vector<SysfsPermissions> sysfs_permissions_;
|
||||||
std::vector<Subsystem> subsystems_;
|
std::vector<Subsystem> subsystems_;
|
||||||
|
std::set<std::string> boot_devices_;
|
||||||
bool skip_restorecon_;
|
bool skip_restorecon_;
|
||||||
std::string sysfs_mount_point_;
|
std::string sysfs_mount_point_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ class FirstStageMount {
|
||||||
std::unique_ptr<LogicalPartitionTable> dm_linear_table_;
|
std::unique_ptr<LogicalPartitionTable> dm_linear_table_;
|
||||||
std::vector<fstab_rec*> mount_fstab_recs_;
|
std::vector<fstab_rec*> mount_fstab_recs_;
|
||||||
std::set<std::string> required_devices_partition_names_;
|
std::set<std::string> required_devices_partition_names_;
|
||||||
DeviceHandler device_handler_;
|
std::unique_ptr<DeviceHandler> device_handler_;
|
||||||
UeventListener uevent_listener_;
|
UeventListener uevent_listener_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -147,6 +147,11 @@ FirstStageMount::FirstStageMount()
|
||||||
if (IsDmLinearEnabled()) {
|
if (IsDmLinearEnabled()) {
|
||||||
dm_linear_table_ = android::fs_mgr::LoadPartitionsFromDeviceTree();
|
dm_linear_table_ = android::fs_mgr::LoadPartitionsFromDeviceTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto boot_devices = fs_mgr_get_boot_devices();
|
||||||
|
device_handler_ =
|
||||||
|
std::make_unique<DeviceHandler>(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
|
||||||
|
std::vector<Subsystem>{}, std::move(boot_devices), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
|
std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
|
||||||
|
|
@ -205,7 +210,7 @@ bool FirstStageMount::InitRequiredDevices() {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
|
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
|
||||||
if (uevent.path == dm_path) {
|
if (uevent.path == dm_path) {
|
||||||
device_handler_.HandleDeviceEvent(uevent);
|
device_handler_->HandleDeviceEvent(uevent);
|
||||||
found = true;
|
found = true;
|
||||||
return ListenerAction::kStop;
|
return ListenerAction::kStop;
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +267,7 @@ ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const
|
||||||
if (iter != required_devices_partition_names_.end()) {
|
if (iter != required_devices_partition_names_.end()) {
|
||||||
LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
|
LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
|
||||||
required_devices_partition_names_.erase(iter);
|
required_devices_partition_names_.erase(iter);
|
||||||
device_handler_.HandleDeviceEvent(uevent);
|
device_handler_->HandleDeviceEvent(uevent);
|
||||||
if (required_devices_partition_names_.empty()) {
|
if (required_devices_partition_names_.empty()) {
|
||||||
return ListenerAction::kStop;
|
return ListenerAction::kStop;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -299,7 +304,7 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
|
||||||
auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
|
auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
|
||||||
if (uevent.device_name == device_name) {
|
if (uevent.device_name == device_name) {
|
||||||
LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
|
LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
|
||||||
device_handler_.HandleDeviceEvent(uevent);
|
device_handler_->HandleDeviceEvent(uevent);
|
||||||
found = true;
|
found = true;
|
||||||
return ListenerAction::kStop;
|
return ListenerAction::kStop;
|
||||||
}
|
}
|
||||||
|
|
@ -469,7 +474,7 @@ ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) {
|
||||||
// is not empty. e.g.,
|
// is not empty. e.g.,
|
||||||
// - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem
|
// - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem
|
||||||
// - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1
|
// - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1
|
||||||
std::vector<std::string> links = device_handler_.GetBlockDeviceSymlinks(uevent);
|
std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
|
||||||
if (!links.empty()) {
|
if (!links.empty()) {
|
||||||
auto[it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]);
|
auto[it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]);
|
||||||
if (!inserted) {
|
if (!inserted) {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include <android-base/chrono_utils.h>
|
#include <android-base/chrono_utils.h>
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
|
#include <fstab/fstab.h>
|
||||||
#include <selinux/android.h>
|
#include <selinux/android.h>
|
||||||
#include <selinux/selinux.h>
|
#include <selinux/selinux.h>
|
||||||
|
|
||||||
|
|
@ -242,8 +243,9 @@ DeviceHandler CreateDeviceHandler() {
|
||||||
std::string hardware = android::base::GetProperty("ro.hardware", "");
|
std::string hardware = android::base::GetProperty("ro.hardware", "");
|
||||||
parser.ParseConfig("/ueventd." + hardware + ".rc");
|
parser.ParseConfig("/ueventd." + hardware + ".rc");
|
||||||
|
|
||||||
|
auto boot_devices = fs_mgr_get_boot_devices();
|
||||||
return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions),
|
return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions),
|
||||||
std::move(subsystems), true);
|
std::move(subsystems), std::move(boot_devices), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ueventd_main(int argc, char** argv) {
|
int ueventd_main(int argc, char** argv) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue