diff options
author | Bowgo Tsai | 2018-05-16 05:33:44 -0500 |
---|---|---|
committer | Bowgo Tsai | 2018-05-18 20:31:35 -0500 |
commit | 5ee7dae840eaebdd1aec47632e2a32e1ba7dd90a (patch) | |
tree | 3b8104eb360e70ef781dcc01375cbbef37165b18 | |
parent | ff17cc31e5aa49fc8cce1693f813d150a7343ab5 (diff) | |
download | platform-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.cpp | 60 | ||||
-rw-r--r-- | fs_mgr/include_fstab/fstab/fstab.h | 2 | ||||
-rw-r--r-- | init/devices.cpp | 20 | ||||
-rw-r--r-- | init/devices.h | 6 | ||||
-rw-r--r-- | init/init_first_stage.cpp | 15 | ||||
-rw-r--r-- | init/ueventd.cpp | 4 |
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 | */ | ||
692 | static 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 | |||
682 | struct fstab *fs_mgr_read_fstab(const char *fstab_path) | 725 | struct 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 | ||
901 | std::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 | |||
858 | int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab) | 918 | int 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); | |||
87 | int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); | 88 | int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); |
88 | 89 | ||
89 | std::string fs_mgr_get_slot_suffix(); | 90 | std::string fs_mgr_get_slot_suffix(); |
91 | std::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 | ||
412 | DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions, | 422 | DeviceHandler::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 | ||
421 | DeviceHandler::DeviceHandler() | 433 | DeviceHandler::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 | ||
132 | std::unique_ptr<FirstStageMount> FirstStageMount::Create() { | 137 | std::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 | ||
249 | int ueventd_main(int argc, char** argv) { | 251 | int ueventd_main(int argc, char** argv) { |