summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Anderson2018-06-14 17:03:53 -0500
committerDavid Anderson2018-06-19 16:03:58 -0500
commit6590df2763bf5fc7e14957e678a328ecf69a7aca (patch)
tree0f89ad58d7564737343c32da31341433651b1d78
parentea3b8ac9ff7bfa954a8d1c145586db495a8d28e7 (diff)
downloadplatform-system-core-6590df2763bf5fc7e14957e678a328ecf69a7aca.tar.gz
platform-system-core-6590df2763bf5fc7e14957e678a328ecf69a7aca.tar.xz
platform-system-core-6590df2763bf5fc7e14957e678a328ecf69a7aca.zip
init: Create logical partitions via liblp.
Currently, init can create logical partitions by hardcoding them in fs_mgr or by specifying them in device-tree. This change allows init to also create logical partitions by using liblp, which stores partition tables in a physical partition. The current name for this partition is "android". Two aspects of this code will change long-term. One, the prototype code using device-tree will be deleted once fastboot supports logical partitions. Two, libdm will obsolete most of the code in fs_mgr_dm_linear.cpp. For now however we preserve how the prototype code functions and we layer liblp on top of the existing dm_linear logic. Bug: 79173901 Test: N/A Change-Id: If014a109da78fa12269bf0df0dda39028ac2d1aa
-rw-r--r--fs_mgr/fs_mgr_dm_linear.cpp26
-rw-r--r--fs_mgr/include/fs_mgr_dm_linear.h1
-rw-r--r--fs_mgr/liblp/include/liblp/metadata_format.h3
-rw-r--r--fs_mgr/liblp/utility.cpp12
-rw-r--r--init/init_first_stage.cpp57
5 files changed, 83 insertions, 16 deletions
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index b2f3a6887..ed42d40e1 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -37,6 +37,7 @@
37#include <android-base/stringprintf.h> 37#include <android-base/stringprintf.h>
38#include <android-base/strings.h> 38#include <android-base/strings.h>
39#include <android-base/unique_fd.h> 39#include <android-base/unique_fd.h>
40#include <liblp/reader.h>
40 41
41#include "fs_mgr_priv.h" 42#include "fs_mgr_priv.h"
42#include "fs_mgr_priv_dm_ioctl.h" 43#include "fs_mgr_priv_dm_ioctl.h"
@@ -137,5 +138,30 @@ std::unique_ptr<LogicalPartitionTable> LoadPartitionsFromDeviceTree() {
137 return nullptr; 138 return nullptr;
138} 139}
139 140
141bool CreateLogicalPartitions(const std::string& block_device) {
142 uint32_t slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
143 auto metadata = ReadMetadata(block_device.c_str(), slot);
144 if (!metadata) {
145 LOG(ERROR) << "Could not read partition table.";
146 return true;
147 }
148
149 LogicalPartitionTable table;
150 for (const auto& partition : metadata->partitions) {
151 LogicalPartition new_partition;
152 new_partition.name = GetPartitionName(partition);
153 new_partition.attributes = partition.attributes;
154 for (size_t i = 0; i < partition.num_extents; i++) {
155 const auto& extent = metadata->extents[partition.first_extent_index + i];
156 new_partition.extents.emplace_back(new_partition.num_sectors, extent.target_data,
157 extent.num_sectors, block_device.c_str());
158 new_partition.num_sectors += extent.num_sectors;
159 }
160 table.partitions.push_back(new_partition);
161 }
162
163 return CreateLogicalPartitions(table);
164}
165
140} // namespace fs_mgr 166} // namespace fs_mgr
141} // namespace android 167} // namespace android
diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h
index 7f928e508..9772c4b4b 100644
--- a/fs_mgr/include/fs_mgr_dm_linear.h
+++ b/fs_mgr/include/fs_mgr_dm_linear.h
@@ -92,6 +92,7 @@ std::unique_ptr<LogicalPartitionTable> LoadPartitionsFromDeviceTree();
92// /dev/block/dm-<name> where |name| is the partition name. 92// /dev/block/dm-<name> where |name| is the partition name.
93// 93//
94bool CreateLogicalPartitions(const LogicalPartitionTable& table); 94bool CreateLogicalPartitions(const LogicalPartitionTable& table);
95bool CreateLogicalPartitions(const std::string& block_device);
95 96
96} // namespace fs_mgr 97} // namespace fs_mgr
97} // namespace android 98} // namespace android
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index f6262ff63..6a2c65583 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -256,6 +256,9 @@ struct LpMetadata {
256std::string GetPartitionName(const LpMetadataPartition& partition); 256std::string GetPartitionName(const LpMetadataPartition& partition);
257std::string GetPartitionGuid(const LpMetadataPartition& partition); 257std::string GetPartitionGuid(const LpMetadataPartition& partition);
258 258
259// Helper to return a slot number for a slot suffix.
260uint32_t SlotNumberForSlotSuffix(const std::string& suffix);
261
259} // namespace fs_mgr 262} // namespace fs_mgr
260} // namespace android 263} // namespace android
261#endif 264#endif
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index 958700b61..217d80256 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -88,5 +88,17 @@ std::string GetPartitionGuid(const LpMetadataPartition& partition) {
88 return buffer; 88 return buffer;
89} 89}
90 90
91uint32_t SlotNumberForSlotSuffix(const std::string& suffix) {
92 if (suffix.empty()) {
93 return 0;
94 }
95 if (suffix.size() != 2 || suffix[0] != '_' || suffix[1] < 'a') {
96 LERROR << __PRETTY_FUNCTION__ << "slot '" << suffix
97 << "' does not have a recognized format.";
98 return 0;
99 }
100 return suffix[1] - 'a';
101}
102
91} // namespace fs_mgr 103} // namespace fs_mgr
92} // namespace android 104} // namespace android
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index db60ce11e..2bc9f3ae0 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -29,6 +29,7 @@
29#include <android-base/file.h> 29#include <android-base/file.h>
30#include <android-base/logging.h> 30#include <android-base/logging.h>
31#include <android-base/strings.h> 31#include <android-base/strings.h>
32#include <liblp/metadata_format.h>
32 33
33#include "devices.h" 34#include "devices.h"
34#include "fs_mgr.h" 35#include "fs_mgr.h"
@@ -75,6 +76,7 @@ class FirstStageMount {
75 76
76 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_; 77 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
77 std::unique_ptr<LogicalPartitionTable> dm_linear_table_; 78 std::unique_ptr<LogicalPartitionTable> dm_linear_table_;
79 std::string lp_metadata_partition_;
78 std::vector<fstab_rec*> mount_fstab_recs_; 80 std::vector<fstab_rec*> mount_fstab_recs_;
79 std::set<std::string> required_devices_partition_names_; 81 std::set<std::string> required_devices_partition_names_;
80 std::unique_ptr<DeviceHandler> device_handler_; 82 std::unique_ptr<DeviceHandler> device_handler_;
@@ -120,13 +122,17 @@ static bool inline IsRecoveryMode() {
120} 122}
121 123
122static inline bool IsDmLinearEnabled() { 124static inline bool IsDmLinearEnabled() {
123 bool enabled = false; 125 static bool checked = false;
124 import_kernel_cmdline( 126 static bool enabled = false;
125 false, [&enabled](const std::string& key, const std::string& value, bool in_qemu) { 127 if (checked) {
126 if (key == "androidboot.logical_partitions" && value == "1") { 128 return enabled;
127 enabled = true; 129 }
128 } 130 import_kernel_cmdline(false, [](const std::string& key, const std::string& value, bool in_qemu) {
129 }); 131 if (key == "androidboot.logical_partitions" && value == "1") {
132 enabled = true;
133 }
134 });
135 checked = true;
130 return enabled; 136 return enabled;
131} 137}
132 138
@@ -163,7 +169,7 @@ std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
163} 169}
164 170
165bool FirstStageMount::DoFirstStageMount() { 171bool FirstStageMount::DoFirstStageMount() {
166 if (!dm_linear_table_ && mount_fstab_recs_.empty()) { 172 if (!IsDmLinearEnabled() && mount_fstab_recs_.empty()) {
167 // Nothing to mount. 173 // Nothing to mount.
168 LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)"; 174 LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
169 return true; 175 return true;
@@ -184,14 +190,18 @@ bool FirstStageMount::InitDevices() {
184 190
185bool FirstStageMount::GetBackingDmLinearDevices() { 191bool FirstStageMount::GetBackingDmLinearDevices() {
186 // Add any additional devices required for dm-linear mappings. 192 // Add any additional devices required for dm-linear mappings.
187 if (!dm_linear_table_) { 193 if (!IsDmLinearEnabled()) {
188 return true; 194 return true;
189 } 195 }
190 196
191 for (const auto& partition : dm_linear_table_->partitions) { 197 required_devices_partition_names_.emplace(LP_METADATA_PARTITION_NAME);
192 for (const auto& extent : partition.extents) { 198
193 const std::string& partition_name = android::base::Basename(extent.block_device()); 199 if (dm_linear_table_) {
194 required_devices_partition_names_.emplace(partition_name); 200 for (const auto& partition : dm_linear_table_->partitions) {
201 for (const auto& extent : partition.extents) {
202 const std::string& partition_name = android::base::Basename(extent.block_device());
203 required_devices_partition_names_.emplace(partition_name);
204 }
195 } 205 }
196 } 206 }
197 return true; 207 return true;
@@ -205,7 +215,7 @@ bool FirstStageMount::InitRequiredDevices() {
205 return true; 215 return true;
206 } 216 }
207 217
208 if (dm_linear_table_ || need_dm_verity_) { 218 if (IsDmLinearEnabled() || need_dm_verity_) {
209 const std::string dm_path = "/devices/virtual/misc/device-mapper"; 219 const std::string dm_path = "/devices/virtual/misc/device-mapper";
210 bool found = false; 220 bool found = false;
211 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) { 221 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
@@ -253,10 +263,21 @@ bool FirstStageMount::InitRequiredDevices() {
253} 263}
254 264
255bool FirstStageMount::CreateLogicalPartitions() { 265bool FirstStageMount::CreateLogicalPartitions() {
256 if (!dm_linear_table_) { 266 if (!IsDmLinearEnabled()) {
257 return true; 267 return true;
258 } 268 }
259 return android::fs_mgr::CreateLogicalPartitions(*dm_linear_table_.get()); 269
270 if (lp_metadata_partition_.empty()) {
271 LOG(ERROR) << "Could not locate logical partition tables in partition "
272 << LP_METADATA_PARTITION_NAME;
273 return false;
274 }
275 if (dm_linear_table_) {
276 if (!android::fs_mgr::CreateLogicalPartitions(*dm_linear_table_.get())) {
277 return false;
278 }
279 }
280 return android::fs_mgr::CreateLogicalPartitions(lp_metadata_partition_);
260} 281}
261 282
262ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) { 283ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) {
@@ -266,6 +287,10 @@ ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const
266 auto iter = required_devices_partition_names_.find(name); 287 auto iter = required_devices_partition_names_.find(name);
267 if (iter != required_devices_partition_names_.end()) { 288 if (iter != required_devices_partition_names_.end()) {
268 LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter; 289 LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
290 if (IsDmLinearEnabled() && name == LP_METADATA_PARTITION_NAME) {
291 std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
292 lp_metadata_partition_ = links[0];
293 }
269 required_devices_partition_names_.erase(iter); 294 required_devices_partition_names_.erase(iter);
270 device_handler_->HandleDeviceEvent(uevent); 295 device_handler_->HandleDeviceEvent(uevent);
271 if (required_devices_partition_names_.empty()) { 296 if (required_devices_partition_names_.empty()) {