summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBowgo Tsai2018-05-16 05:33:44 -0500
committerBowgo Tsai2018-05-18 20:31:35 -0500
commit5ee7dae840eaebdd1aec47632e2a32e1ba7dd90a (patch)
tree3b8104eb360e70ef781dcc01375cbbef37165b18
parentff17cc31e5aa49fc8cce1693f813d150a7343ab5 (diff)
downloadplatform-system-core-5ee7dae840eaebdd1aec47632e2a32e1ba7dd90a.tar.gz
platform-system-core-5ee7dae840eaebdd1aec47632e2a32e1ba7dd90a.tar.xz
platform-system-core-5ee7dae840eaebdd1aec47632e2a32e1ba7dd90a.zip
Adds /dev/block/by-name/<partition> symlinks
During uevent processing, some "by-name" symlinks will be created. /dev/block/<type>/<device>/by-name/<partition> <type> can be: platform, pci or vbd. <device> might be: soc.0/f9824900.sdhci, soc.0/f9824900.sdhci, etc. <partition> might be: system, vendor, system_a, system_b, etc. e.g., on a non-A/B device: /dev/block/platform/soc.0/f9824900.sdhci/by-name/system /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor On a A/B device: /dev/block/platform/soc/1da4000.ufshc/by-name/system_a /dev/block/platform/soc/1da4000.ufshc/by-name/system_b /dev/block/platform/soc/1da4000.ufshc/by-name/vendor_a /dev/block/platform/soc/1da4000.ufshc/by-name/vendor_b However, those symlinks are "device-specific". This change adds the "generic" symlinks in ueventd, in addition to the existing symlinks, when the possible "boot devices" are specified in device tree. e.g., &firmware_android { compatible = "android,firmware"; boot_devices ="soc/1da4000.ufshc,soc.0/f9824900.sdhci"; } The following symlinks will then be created on the aforementioned non-A/B and A/B devices, respectively. /dev/block/by-name/system /dev/block/by-name/vendor /dev/block/by-name/system_a /dev/block/by-name/system_b /dev/block/by-name/vendor_a /dev/block/by-name/vendor_b Note that both <type> and <device> are skipped in the newly create symlinks. It assumes there is no more than one devices with the same <partition>, which is the assumption of current first stage mount flow. Finally, when 'boot_devices' in DT is absent, it fallbacks to extract 'boot_devices' from fstab settings. e.g., using 'soc/1da4000.ufshc', 'soc.0/f9824900.sdhci' for a fstab with the following content: /dev/block/platform/soc/1da4000.ufshc/by-name/system /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor Bug: 78613232 Test: adb shell ls /dev/block/by-name Change-Id: Iec920b5a72409b6a2bdbeeb290f0a3acd2046b5d Merged-In: Iec920b5a72409b6a2bdbeeb290f0a3acd2046b5d (cherry picked from commit 8eec38f4e463d8cd980562ec49432c17972cc5cb)
-rw-r--r--fs_mgr/fs_mgr_fstab.cpp60
-rw-r--r--fs_mgr/include_fstab/fstab/fstab.h2
-rw-r--r--init/devices.cpp20
-rw-r--r--init/devices.h6
-rw-r--r--init/init_first_stage.cpp15
-rw-r--r--init/ueventd.cpp4
6 files changed, 95 insertions, 12 deletions
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 9d504d6d5..68cc530dd 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -679,6 +679,49 @@ static struct fstab *in_place_merge(struct fstab *a, struct fstab *b)
679 return a; 679 return a;
680} 680}
681 681
682/* Extracts <device>s from the by-name symlinks specified in a fstab:
683 * /dev/block/<type>/<device>/by-name/<partition>
684 *
685 * <type> can be: platform, pci or vbd.
686 *
687 * For example, given the following entries in the input fstab:
688 * /dev/block/platform/soc/1da4000.ufshc/by-name/system
689 * /dev/block/pci/soc.0/f9824900.sdhci/by-name/vendor
690 * it returns a set { "soc/1da4000.ufshc", "soc.0/f9824900.sdhci" }.
691 */
692static std::set<std::string> extract_boot_devices(const fstab& fstab) {
693 std::set<std::string> boot_devices;
694
695 for (int i = 0; i < fstab.num_entries; i++) {
696 std::string blk_device(fstab.recs[i].blk_device);
697 // Skips blk_device that doesn't conform to the format.
698 if (!android::base::StartsWith(blk_device, "/dev/block") ||
699 android::base::StartsWith(blk_device, "/dev/block/by-name") ||
700 android::base::StartsWith(blk_device, "/dev/block/bootdevice/by-name")) {
701 continue;
702 }
703 // Skips non-by_name blk_device.
704 // /dev/block/<type>/<device>/by-name/<partition>
705 // ^ slash_by_name
706 auto slash_by_name = blk_device.find("/by-name");
707 if (slash_by_name == std::string::npos) continue;
708 blk_device.erase(slash_by_name); // erases /by-name/<partition>
709
710 // Erases /dev/block/, now we have <type>/<device>
711 blk_device.erase(0, std::string("/dev/block/").size());
712
713 // <type>/<device>
714 // ^ first_slash
715 auto first_slash = blk_device.find('/');
716 if (first_slash == std::string::npos) continue;
717
718 auto boot_device = blk_device.substr(first_slash + 1);
719 if (!boot_device.empty()) boot_devices.insert(std::move(boot_device));
720 }
721
722 return boot_devices;
723}
724
682struct fstab *fs_mgr_read_fstab(const char *fstab_path) 725struct fstab *fs_mgr_read_fstab(const char *fstab_path)
683{ 726{
684 FILE *fstab_file; 727 FILE *fstab_file;
@@ -855,6 +898,23 @@ struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const st
855 return nullptr; 898 return nullptr;
856} 899}
857 900
901std::set<std::string> fs_mgr_get_boot_devices() {
902 // boot_devices can be specified in device tree.
903 std::string dt_value;
904 std::string file_name = get_android_dt_dir() + "/boot_devices";
905 if (read_dt_file(file_name, &dt_value)) {
906 auto boot_devices = android::base::Split(dt_value, ",");
907 return std::set<std::string>(boot_devices.begin(), boot_devices.end());
908 }
909
910 // Fallback to extract boot devices from fstab.
911 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
912 fs_mgr_free_fstab);
913 if (fstab) return extract_boot_devices(*fstab);
914
915 return {};
916}
917
858int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab) 918int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab)
859{ 919{
860 return fstab->fs_mgr_flags & MF_VOLDMANAGED; 920 return fstab->fs_mgr_flags & MF_VOLDMANAGED;
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 8c585dd2f..e8da2ac85 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -22,6 +22,7 @@
22#include <stdint.h> 22#include <stdint.h>
23#include <stdio.h> 23#include <stdio.h>
24 24
25#include <set>
25#include <string> 26#include <string>
26 27
27/* 28/*
@@ -87,5 +88,6 @@ int fs_mgr_is_quota(const struct fstab_rec* fstab);
87int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); 88int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
88 89
89std::string fs_mgr_get_slot_suffix(); 90std::string fs_mgr_get_slot_suffix();
91std::set<std::string> fs_mgr_get_boot_devices();
90 92
91#endif /* __CORE_FS_TAB_H */ 93#endif /* __CORE_FS_TAB_H */
diff --git a/init/devices.cpp b/init/devices.cpp
index 688ad6196..ada1e2870 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -329,6 +329,10 @@ std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev
329 << partition_name_sanitized << "'"; 329 << partition_name_sanitized << "'";
330 } 330 }
331 links.emplace_back(link_path + "/by-name/" + partition_name_sanitized); 331 links.emplace_back(link_path + "/by-name/" + partition_name_sanitized);
332 // Adds symlink: /dev/block/by-name/<partition_name>.
333 if (boot_devices_.find(device) != boot_devices_.end()) {
334 links.emplace_back("/dev/block/by-name/" + partition_name_sanitized);
335 }
332 } 336 }
333 337
334 auto last_slash = uevent.path.rfind('/'); 338 auto last_slash = uevent.path.rfind('/');
@@ -346,8 +350,14 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
346 PLOG(ERROR) << "Failed to create directory " << Dirname(link); 350 PLOG(ERROR) << "Failed to create directory " << Dirname(link);
347 } 351 }
348 352
349 if (symlink(devpath.c_str(), link.c_str()) && errno != EEXIST) { 353 if (symlink(devpath.c_str(), link.c_str())) {
350 PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link; 354 if (errno != EEXIST) {
355 PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link;
356 } else if (std::string link_path;
357 Readlink(link, &link_path) && link_path != devpath) {
358 PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link
359 << ", which already links to: " << link_path;
360 }
351 } 361 }
352 } 362 }
353 } 363 }
@@ -411,16 +421,18 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
411 421
412DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions, 422DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
413 std::vector<SysfsPermissions> sysfs_permissions, 423 std::vector<SysfsPermissions> sysfs_permissions,
414 std::vector<Subsystem> subsystems, bool skip_restorecon) 424 std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
425 bool skip_restorecon)
415 : dev_permissions_(std::move(dev_permissions)), 426 : dev_permissions_(std::move(dev_permissions)),
416 sysfs_permissions_(std::move(sysfs_permissions)), 427 sysfs_permissions_(std::move(sysfs_permissions)),
417 subsystems_(std::move(subsystems)), 428 subsystems_(std::move(subsystems)),
429 boot_devices_(std::move(boot_devices)),
418 skip_restorecon_(skip_restorecon), 430 skip_restorecon_(skip_restorecon),
419 sysfs_mount_point_("/sys") {} 431 sysfs_mount_point_("/sys") {}
420 432
421DeviceHandler::DeviceHandler() 433DeviceHandler::DeviceHandler()
422 : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, 434 : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
423 std::vector<Subsystem>{}, false) {} 435 std::vector<Subsystem>{}, std::set<std::string>{}, false) {}
424 436
425} // namespace init 437} // namespace init
426} // namespace android 438} // namespace android
diff --git a/init/devices.h b/init/devices.h
index 1f8f1e8a9..f9035da3d 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -21,6 +21,7 @@
21#include <sys/types.h> 21#include <sys/types.h>
22 22
23#include <algorithm> 23#include <algorithm>
24#include <set>
24#include <string> 25#include <string>
25#include <vector> 26#include <vector>
26 27
@@ -103,8 +104,8 @@ class DeviceHandler {
103 104
104 DeviceHandler(); 105 DeviceHandler();
105 DeviceHandler(std::vector<Permissions> dev_permissions, 106 DeviceHandler(std::vector<Permissions> dev_permissions,
106 std::vector<SysfsPermissions> sysfs_permissions, 107 std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems,
107 std::vector<Subsystem> subsystems, bool skip_restorecon); 108 std::set<std::string> boot_devices, bool skip_restorecon);
108 ~DeviceHandler(){}; 109 ~DeviceHandler(){};
109 110
110 void HandleDeviceEvent(const Uevent& uevent); 111 void HandleDeviceEvent(const Uevent& uevent);
@@ -125,6 +126,7 @@ class DeviceHandler {
125 std::vector<Permissions> dev_permissions_; 126 std::vector<Permissions> dev_permissions_;
126 std::vector<SysfsPermissions> sysfs_permissions_; 127 std::vector<SysfsPermissions> sysfs_permissions_;
127 std::vector<Subsystem> subsystems_; 128 std::vector<Subsystem> subsystems_;
129 std::set<std::string> boot_devices_;
128 bool skip_restorecon_; 130 bool skip_restorecon_;
129 std::string sysfs_mount_point_; 131 std::string sysfs_mount_point_;
130}; 132};
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 1dfceb459..033ce419a 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -72,7 +72,7 @@ class FirstStageMount {
72 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_; 72 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
73 std::vector<fstab_rec*> mount_fstab_recs_; 73 std::vector<fstab_rec*> mount_fstab_recs_;
74 std::set<std::string> required_devices_partition_names_; 74 std::set<std::string> required_devices_partition_names_;
75 DeviceHandler device_handler_; 75 std::unique_ptr<DeviceHandler> device_handler_;
76 UeventListener uevent_listener_; 76 UeventListener uevent_listener_;
77}; 77};
78 78
@@ -127,6 +127,11 @@ FirstStageMount::FirstStageMount()
127 for (int i = 0; i < device_tree_fstab_->num_entries; i++) { 127 for (int i = 0; i < device_tree_fstab_->num_entries; i++) {
128 mount_fstab_recs_.push_back(&device_tree_fstab_->recs[i]); 128 mount_fstab_recs_.push_back(&device_tree_fstab_->recs[i]);
129 } 129 }
130
131 auto boot_devices = fs_mgr_get_boot_devices();
132 device_handler_ =
133 std::make_unique<DeviceHandler>(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
134 std::vector<Subsystem>{}, std::move(boot_devices), false);
130} 135}
131 136
132std::unique_ptr<FirstStageMount> FirstStageMount::Create() { 137std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
@@ -165,7 +170,7 @@ bool FirstStageMount::InitRequiredDevices() {
165 bool found = false; 170 bool found = false;
166 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) { 171 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
167 if (uevent.path == dm_path) { 172 if (uevent.path == dm_path) {
168 device_handler_.HandleDeviceEvent(uevent); 173 device_handler_->HandleDeviceEvent(uevent);
169 found = true; 174 found = true;
170 return ListenerAction::kStop; 175 return ListenerAction::kStop;
171 } 176 }
@@ -215,7 +220,7 @@ ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const
215 if (iter != required_devices_partition_names_.end()) { 220 if (iter != required_devices_partition_names_.end()) {
216 LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter; 221 LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
217 required_devices_partition_names_.erase(iter); 222 required_devices_partition_names_.erase(iter);
218 device_handler_.HandleDeviceEvent(uevent); 223 device_handler_->HandleDeviceEvent(uevent);
219 if (required_devices_partition_names_.empty()) { 224 if (required_devices_partition_names_.empty()) {
220 return ListenerAction::kStop; 225 return ListenerAction::kStop;
221 } else { 226 } else {
@@ -252,7 +257,7 @@ bool FirstStageMount::InitVerityDevice(const std::string& verity_device) {
252 auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) { 257 auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) {
253 if (uevent.device_name == device_name) { 258 if (uevent.device_name == device_name) {
254 LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; 259 LOG(VERBOSE) << "Creating dm-verity device : " << verity_device;
255 device_handler_.HandleDeviceEvent(uevent); 260 device_handler_->HandleDeviceEvent(uevent);
256 found = true; 261 found = true;
257 return ListenerAction::kStop; 262 return ListenerAction::kStop;
258 } 263 }
@@ -414,7 +419,7 @@ ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) {
414 // is not empty. e.g., 419 // is not empty. e.g.,
415 // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem 420 // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem
416 // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1 421 // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1
417 std::vector<std::string> links = device_handler_.GetBlockDeviceSymlinks(uevent); 422 std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
418 if (!links.empty()) { 423 if (!links.empty()) {
419 auto[it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]); 424 auto[it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]);
420 if (!inserted) { 425 if (!inserted) {
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 1435d82ef..a284203ba 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -30,6 +30,7 @@
30#include <android-base/chrono_utils.h> 30#include <android-base/chrono_utils.h>
31#include <android-base/logging.h> 31#include <android-base/logging.h>
32#include <android-base/properties.h> 32#include <android-base/properties.h>
33#include <fstab/fstab.h>
33#include <selinux/android.h> 34#include <selinux/android.h>
34#include <selinux/selinux.h> 35#include <selinux/selinux.h>
35 36
@@ -242,8 +243,9 @@ DeviceHandler CreateDeviceHandler() {
242 std::string hardware = android::base::GetProperty("ro.hardware", ""); 243 std::string hardware = android::base::GetProperty("ro.hardware", "");
243 parser.ParseConfig("/ueventd." + hardware + ".rc"); 244 parser.ParseConfig("/ueventd." + hardware + ".rc");
244 245
246 auto boot_devices = fs_mgr_get_boot_devices();
245 return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions), 247 return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions),
246 std::move(subsystems), true); 248 std::move(subsystems), std::move(boot_devices), true);
247} 249}
248 250
249int ueventd_main(int argc, char** argv) { 251int ueventd_main(int argc, char** argv) {