Merge "init/fs_mgr: prototype first-stage dm-linear support"
am: 3e946da535
Change-Id: I79fd25d997b451807f9f8ed6ba4145c24defc631
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index f23150d..05dba15 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -42,6 +42,7 @@
"fs_mgr_verity.cpp",
"fs_mgr_avb.cpp",
"fs_mgr_avb_ops.cpp",
+ "fs_mgr_dm_linear.cpp",
],
static_libs: [
"libfec",
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e9040df..6e9ffba 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -794,6 +794,29 @@
return true;
}
+bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
+ // Logical partitions are specified with a named partition rather than a
+ // block device, so if the block device is a path, then it has already
+ // been updated.
+ if (rec->blk_device[0] == '/') {
+ return true;
+ }
+
+ android::base::unique_fd dm_fd(open("/dev/device-mapper", O_RDONLY));
+ if (dm_fd < 0) {
+ PLOG(ERROR) << "open /dev/device-mapper failed";
+ return false;
+ }
+ struct dm_ioctl io;
+ std::string device_name;
+ if (!fs_mgr_dm_get_device_name(&io, rec->blk_device, dm_fd, &device_name)) {
+ return false;
+ }
+ free(rec->blk_device);
+ rec->blk_device = strdup(device_name.c_str());
+ return true;
+}
+
/* When multiple fstab records share the same mount_point, it will
* try to mount each one in turn, and ignore any duplicates after a
* first successful mount.
@@ -845,6 +868,13 @@
}
}
+ if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) {
+ if (!fs_mgr_update_logical_partition(&fstab->recs[i])) {
+ LERROR << "Could not set up logical partition, skipping!";
+ continue;
+ }
+ }
+
if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
!fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all";
@@ -1065,6 +1095,13 @@
return FS_MGR_DOMNT_FAILED;
}
+ if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) {
+ if (!fs_mgr_update_logical_partition(&fstab->recs[i])) {
+ LERROR << "Could not set up logical partition, skipping!";
+ continue;
+ }
+ }
+
/* First check the filesystem if requested */
if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) {
LERROR << "Skipping mounting '" << n_blk_device << "'";
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index cf6b497..5a9cb65 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -585,7 +585,13 @@
// Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor
// to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix.
- std::string partition_name(basename(fstab_entry->blk_device));
+ std::string partition_name;
+ if (fstab_entry->fs_mgr_flags & MF_LOGICAL) {
+ partition_name = fstab_entry->logical_partition_name;
+ } else {
+ partition_name = basename(fstab_entry->blk_device);
+ }
+
if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) {
auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix());
if (ab_suffix != std::string::npos) {
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
new file mode 100644
index 0000000..b2f3a68
--- /dev/null
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "fs_mgr_dm_linear.h"
+
+#include <inttypes.h>
+#include <linux/dm-ioctl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <sstream>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+
+#include "fs_mgr_priv.h"
+#include "fs_mgr_priv_dm_ioctl.h"
+
+namespace android {
+namespace fs_mgr {
+
+std::string LogicalPartitionExtent::Serialize() const {
+ // Note: we need to include an explicit null-terminator.
+ std::string argv =
+ android::base::StringPrintf("%s %" PRIu64, block_device_.c_str(), first_sector_);
+ argv.push_back(0);
+
+ // The kernel expects each target to be aligned.
+ size_t spec_bytes = sizeof(struct dm_target_spec) + argv.size();
+ size_t padding = ((spec_bytes + 7) & ~7) - spec_bytes;
+ for (size_t i = 0; i < padding; i++) {
+ argv.push_back(0);
+ }
+
+ struct dm_target_spec spec;
+ spec.sector_start = logical_sector_;
+ spec.length = num_sectors_;
+ spec.status = 0;
+ strcpy(spec.target_type, "linear");
+ spec.next = sizeof(struct dm_target_spec) + argv.size();
+
+ return std::string((char*)&spec, sizeof(spec)) + argv;
+}
+
+static bool LoadDmTable(int dm_fd, const LogicalPartition& partition) {
+ // Combine all dm_target_spec buffers together.
+ std::string target_string;
+ for (const auto& extent : partition.extents) {
+ target_string += extent.Serialize();
+ }
+
+ // Allocate the ioctl buffer.
+ size_t buffer_size = sizeof(struct dm_ioctl) + target_string.size();
+ std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(buffer_size);
+
+ // Initialize the ioctl buffer header, then copy our target specs in.
+ struct dm_ioctl* io = reinterpret_cast<struct dm_ioctl*>(buffer.get());
+ fs_mgr_dm_ioctl_init(io, buffer_size, partition.name);
+ io->target_count = partition.extents.size();
+ if (partition.attributes & kPartitionReadonly) {
+ io->flags |= DM_READONLY_FLAG;
+ }
+ memcpy(io + 1, target_string.c_str(), target_string.size());
+
+ if (ioctl(dm_fd, DM_TABLE_LOAD, io)) {
+ PERROR << "Failed ioctl() on DM_TABLE_LOAD, partition " << partition.name;
+ return false;
+ }
+ return true;
+}
+
+static bool LoadTablesAndActivate(int dm_fd, const LogicalPartition& partition) {
+ if (!LoadDmTable(dm_fd, partition)) {
+ return false;
+ }
+
+ struct dm_ioctl io;
+ return fs_mgr_dm_resume_table(&io, partition.name, dm_fd);
+}
+
+static bool CreateDmDeviceForPartition(int dm_fd, const LogicalPartition& partition) {
+ struct dm_ioctl io;
+ if (!fs_mgr_dm_create_device(&io, partition.name, dm_fd)) {
+ return false;
+ }
+ if (!LoadTablesAndActivate(dm_fd, partition)) {
+ // Remove the device rather than leave it in an inactive state.
+ fs_mgr_dm_destroy_device(&io, partition.name, dm_fd);
+ return false;
+ }
+
+ LINFO << "Created device-mapper device: " << partition.name;
+ return true;
+}
+
+bool CreateLogicalPartitions(const LogicalPartitionTable& table) {
+ android::base::unique_fd dm_fd(open("/dev/device-mapper", O_RDWR));
+ if (dm_fd < 0) {
+ PLOG(ERROR) << "failed to open /dev/device-mapper";
+ return false;
+ }
+ for (const auto& partition : table.partitions) {
+ if (!CreateDmDeviceForPartition(dm_fd, partition)) {
+ LOG(ERROR) << "could not create dm-linear device for partition: " << partition.name;
+ return false;
+ }
+ }
+ return true;
+}
+
+std::unique_ptr<LogicalPartitionTable> LoadPartitionsFromDeviceTree() {
+ return nullptr;
+}
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 3fbef9f..472ab59 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -109,6 +109,7 @@
{"logicalblk=", MF_LOGICALBLKSIZE},
{"sysfs_path=", MF_SYSFS},
{"defaults", 0},
+ {"logical", MF_LOGICAL},
{0, 0},
};
@@ -445,10 +446,6 @@
LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
return {};
}
- if (!StartsWith(value, "/dev")) {
- LERROR << "dt_fstab: Invalid device node for partition " << dp->d_name;
- return {};
- }
fstab_entry.push_back(value);
std::string mount_point;
@@ -631,6 +628,10 @@
fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size;
fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size;
fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path;
+ if (fstab->recs[cnt].fs_mgr_flags & MF_LOGICAL) {
+ fstab->recs[cnt].logical_partition_name = strdup(fstab->recs[cnt].blk_device);
+ }
+
cnt++;
}
/* If an A/B partition, modify block device to be the real block device */
@@ -797,6 +798,7 @@
for (i = 0; i < fstab->num_entries; i++) {
/* Free the pointers return by strdup(3) */
free(fstab->recs[i].blk_device);
+ free(fstab->recs[i].logical_partition_name);
free(fstab->recs[i].mount_point);
free(fstab->recs[i].fs_type);
free(fstab->recs[i].fs_options);
@@ -944,3 +946,7 @@
{
return fstab->fs_mgr_flags & MF_SYSFS;
}
+
+int fs_mgr_is_logical(const struct fstab_rec* fstab) {
+ return fstab->fs_mgr_flags & MF_LOGICAL;
+}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index ade0cc4..afd7227 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -82,6 +82,7 @@
*
*/
+// clang-format off
#define MF_WAIT 0x1
#define MF_CHECK 0x2
#define MF_CRYPT 0x4
@@ -111,6 +112,8 @@
#define MF_AVB 0X2000000
#define MF_KEYDIRECTORY 0X4000000
#define MF_SYSFS 0X8000000
+#define MF_LOGICAL 0x10000000
+// clang-format on
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp
index 0a113b4..3b01d0e 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/fs_mgr_slotselect.cpp
@@ -36,19 +36,30 @@
std::string ab_suffix;
for (n = 0; n < fstab->num_entries; n++) {
- if (fstab->recs[n].fs_mgr_flags & MF_SLOTSELECT) {
- char *tmp;
+ fstab_rec& record = fstab->recs[n];
+ if (record.fs_mgr_flags & MF_SLOTSELECT) {
if (ab_suffix.empty()) {
ab_suffix = fs_mgr_get_slot_suffix();
// Return false if failed to get ab_suffix when MF_SLOTSELECT is specified.
if (ab_suffix.empty()) return false;
}
- if (asprintf(&tmp, "%s%s", fstab->recs[n].blk_device, ab_suffix.c_str()) > 0) {
- free(fstab->recs[n].blk_device);
- fstab->recs[n].blk_device = tmp;
- } else {
+
+ char* new_blk_device;
+ if (asprintf(&new_blk_device, "%s%s", record.blk_device, ab_suffix.c_str()) <= 0) {
return false;
}
+ free(record.blk_device);
+ record.blk_device = new_blk_device;
+
+ char* new_partition_name;
+ if (record.logical_partition_name) {
+ if (asprintf(&new_partition_name, "%s%s", record.logical_partition_name,
+ ab_suffix.c_str()) <= 0) {
+ return false;
+ }
+ free(record.logical_partition_name);
+ record.logical_partition_name = new_partition_name;
+ }
}
}
return true;
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 653d8fa..72f019e 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -76,6 +76,7 @@
bool fs_mgr_load_verity_state(int* mode);
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
int fs_mgr_swapon_all(struct fstab *fstab);
+bool fs_mgr_update_logical_partition(struct fstab_rec* rec);
int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h
new file mode 100644
index 0000000..7f928e5
--- /dev/null
+++ b/fs_mgr/include/fs_mgr_dm_linear.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CORE_FS_MGR_DM_LINEAR_H
+#define __CORE_FS_MGR_DM_LINEAR_H
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace fs_mgr {
+
+static const uint32_t kPartitionReadonly = 0x1;
+
+class LogicalPartitionExtent {
+ public:
+ LogicalPartitionExtent() : logical_sector_(0), first_sector_(0), num_sectors_(0) {}
+ LogicalPartitionExtent(uint64_t logical_sector, uint64_t first_sector, uint64_t num_sectors,
+ const std::string& block_device)
+ : logical_sector_(logical_sector),
+ first_sector_(first_sector),
+ num_sectors_(num_sectors),
+ block_device_(block_device) {}
+
+ // Return a string containing the dm_target_spec buffer needed to use this
+ // extent in a device-mapper table.
+ std::string Serialize() const;
+
+ const std::string& block_device() const { return block_device_; }
+
+ private:
+ // Logical sector this extent represents in the presented block device.
+ // This is equal to the previous extent's logical sector plus the number
+ // of sectors in that extent. The first extent always starts at 0.
+ uint64_t logical_sector_;
+ // First 512-byte sector of this extent, on the source block device.
+ uint64_t first_sector_;
+ // Number of 512-byte sectors.
+ uint64_t num_sectors_;
+ // Target block device.
+ std::string block_device_;
+};
+
+struct LogicalPartition {
+ LogicalPartition() : attributes(0), num_sectors(0) {}
+
+ std::string name;
+ uint32_t attributes;
+ // Number of 512-byte sectors total.
+ uint64_t num_sectors;
+ // List of extents.
+ std::vector<LogicalPartitionExtent> extents;
+};
+
+struct LogicalPartitionTable {
+ // List of partitions in the partition table.
+ std::vector<LogicalPartition> partitions;
+};
+
+// Load a dm-linear table from the device tree if one is available; otherwise,
+// return null.
+std::unique_ptr<LogicalPartitionTable> LoadPartitionsFromDeviceTree();
+
+// Create device-mapper devices for the given partition table.
+//
+// On success, two devices nodes will be created for each partition, both
+// pointing to the same device:
+// /dev/block/dm-<N> where N is a sequential ID assigned by device-mapper.
+// /dev/block/dm-<name> where |name| is the partition name.
+//
+bool CreateLogicalPartitions(const LogicalPartitionTable& table);
+
+} // namespace fs_mgr
+} // namespace android
+
+#endif // __CORE_FS_MGR_DM_LINEAR_H
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 8c585dd..04ccfc5 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -37,6 +37,7 @@
struct fstab_rec {
char* blk_device;
+ char* logical_partition_name;
char* mount_point;
char* fs_type;
unsigned long flags;
@@ -84,6 +85,7 @@
int fs_mgr_is_nofail(const struct fstab_rec* fstab);
int fs_mgr_is_latemount(const struct fstab_rec* fstab);
int fs_mgr_is_quota(const struct fstab_rec* fstab);
+int fs_mgr_is_logical(const struct fstab_rec* fstab);
int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
std::string fs_mgr_get_slot_suffix();
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 1b6e97e..a5ba647 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -33,11 +33,13 @@
#include "devices.h"
#include "fs_mgr.h"
#include "fs_mgr_avb.h"
+#include "fs_mgr_dm_linear.h"
#include "uevent.h"
#include "uevent_listener.h"
#include "util.h"
using android::base::Timer;
+using android::fs_mgr::LogicalPartitionTable;
namespace android {
namespace init {
@@ -58,18 +60,21 @@
protected:
ListenerAction HandleBlockDevice(const std::string& name, const Uevent&);
bool InitRequiredDevices();
- bool InitVerityDevice(const std::string& verity_device);
+ bool InitMappedDevice(const std::string& verity_device);
+ bool CreateLogicalPartitions();
bool MountPartitions();
+ bool GetBackingDmLinearDevices();
virtual ListenerAction UeventCallback(const Uevent& uevent);
// Pure virtual functions.
- virtual bool GetRequiredDevices() = 0;
+ virtual bool GetDmVerityDevices() = 0;
virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0;
bool need_dm_verity_;
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
+ std::unique_ptr<LogicalPartitionTable> dm_linear_table_;
std::vector<fstab_rec*> mount_fstab_recs_;
std::set<std::string> required_devices_partition_names_;
DeviceHandler device_handler_;
@@ -82,7 +87,7 @@
~FirstStageMountVBootV1() override = default;
protected:
- bool GetRequiredDevices() override;
+ bool GetDmVerityDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
};
@@ -95,7 +100,7 @@
protected:
ListenerAction UeventCallback(const Uevent& uevent) override;
- bool GetRequiredDevices() override;
+ bool GetDmVerityDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
bool InitAvbHandle();
@@ -114,6 +119,17 @@
return access("/sbin/recovery", F_OK) == 0;
}
+static inline bool IsDmLinearEnabled() {
+ bool enabled = false;
+ import_kernel_cmdline(
+ false, [&enabled](const std::string& key, const std::string& value, bool in_qemu) {
+ if (key == "androidboot.lrap" && value == "1") {
+ enabled = true;
+ }
+ });
+ return enabled;
+}
+
// Class Definitions
// -----------------
FirstStageMount::FirstStageMount()
@@ -127,6 +143,10 @@
} else {
LOG(INFO) << "Failed to read fstab from device tree";
}
+
+ if (IsDmLinearEnabled()) {
+ dm_linear_table_ = android::fs_mgr::LoadPartitionsFromDeviceTree();
+ }
}
std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
@@ -138,7 +158,7 @@
}
bool FirstStageMount::DoFirstStageMount() {
- if (mount_fstab_recs_.empty()) {
+ if (!dm_linear_table_ && mount_fstab_recs_.empty()) {
// Nothing to mount.
LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
return true;
@@ -146,13 +166,30 @@
if (!InitDevices()) return false;
+ if (!CreateLogicalPartitions()) return false;
+
if (!MountPartitions()) return false;
return true;
}
bool FirstStageMount::InitDevices() {
- return GetRequiredDevices() && InitRequiredDevices();
+ return GetBackingDmLinearDevices() && GetDmVerityDevices() && InitRequiredDevices();
+}
+
+bool FirstStageMount::GetBackingDmLinearDevices() {
+ // Add any additional devices required for dm-linear mappings.
+ if (!dm_linear_table_) {
+ return true;
+ }
+
+ for (const auto& partition : dm_linear_table_->partitions) {
+ for (const auto& extent : partition.extents) {
+ const std::string& partition_name = android::base::Basename(extent.block_device());
+ required_devices_partition_names_.emplace(partition_name);
+ }
+ }
+ return true;
}
// Creates devices with uevent->partition_name matching one in the member variable
@@ -163,7 +200,7 @@
return true;
}
- if (need_dm_verity_) {
+ if (dm_linear_table_ || need_dm_verity_) {
const std::string dm_path = "/devices/virtual/misc/device-mapper";
bool found = false;
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
@@ -210,6 +247,13 @@
return true;
}
+bool FirstStageMount::CreateLogicalPartitions() {
+ if (!dm_linear_table_) {
+ return true;
+ }
+ return android::fs_mgr::CreateLogicalPartitions(*dm_linear_table_.get());
+}
+
ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) {
// Matches partition name to create device nodes.
// Both required_devices_partition_names_ and uevent->partition_name have A/B
@@ -247,14 +291,14 @@
}
// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
-bool FirstStageMount::InitVerityDevice(const std::string& verity_device) {
- const std::string device_name(basename(verity_device.c_str()));
+bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
+ const std::string device_name(basename(dm_device.c_str()));
const std::string syspath = "/sys/block/" + device_name;
bool found = false;
- auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) {
+ auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
if (uevent.device_name == device_name) {
- LOG(VERBOSE) << "Creating dm-verity device : " << verity_device;
+ LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
device_handler_.HandleDeviceEvent(uevent);
found = true;
return ListenerAction::kStop;
@@ -279,6 +323,14 @@
bool FirstStageMount::MountPartitions() {
for (auto fstab_rec : mount_fstab_recs_) {
+ if (fs_mgr_is_logical(fstab_rec)) {
+ if (!fs_mgr_update_logical_partition(fstab_rec)) {
+ return false;
+ }
+ if (!InitMappedDevice(fstab_rec->blk_device)) {
+ return false;
+ }
+ }
if (!SetUpDmVerity(fstab_rec)) {
PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'";
return false;
@@ -291,7 +343,7 @@
return true;
}
-bool FirstStageMountVBootV1::GetRequiredDevices() {
+bool FirstStageMountVBootV1::GetDmVerityDevices() {
std::string verity_loc_device;
need_dm_verity_ = false;
@@ -344,7 +396,7 @@
// The exact block device name (fstab_rec->blk_device) is changed to
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
// first stage.
- return InitVerityDevice(fstab_rec->blk_device);
+ return InitMappedDevice(fstab_rec->blk_device);
default:
return false;
}
@@ -371,7 +423,7 @@
}
}
-bool FirstStageMountVBootV2::GetRequiredDevices() {
+bool FirstStageMountVBootV2::GetDmVerityDevices() {
need_dm_verity_ = false;
// fstab_rec->blk_device has A/B suffix.
@@ -444,7 +496,7 @@
// The exact block device name (fstab_rec->blk_device) is changed to
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
// first stage.
- return InitVerityDevice(fstab_rec->blk_device);
+ return InitMappedDevice(fstab_rec->blk_device);
default:
return false;
}