Merge "[GPU Service] Add independent AID for gpu service."
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index 2dcfb53..b72ed16 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -97,8 +97,12 @@
}
}
+bool dev_is_overlayfs(const std::string& dev) {
+ return (dev == "overlay") || (dev == "overlayfs");
+}
+
bool make_block_device_writable(const std::string& dev) {
- if ((dev == "overlay") || (dev == "overlayfs")) return true;
+ if (dev_is_overlayfs(dev)) return true;
int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
if (fd == -1) {
return false;
@@ -161,6 +165,10 @@
return true;
}
bool is_root = strcmp(dir, "/") == 0;
+ if (is_root && dev_is_overlayfs(find_mount("/system", false))) {
+ dir = "/system";
+ is_root = false;
+ }
std::string dev = find_mount(dir, is_root);
if (is_root && dev.empty()) {
// The fstab entry will be /system if the device switched roots during
diff --git a/fastboot/constants.h b/fastboot/constants.h
index 705da33..81f0560 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -64,3 +64,4 @@
#define FB_VAR_OFF_MODE_CHARGE_STATE "off-mode-charge"
#define FB_VAR_BATTERY_VOLTAGE "battery-voltage"
#define FB_VAR_BATTERY_SOC_OK "battery-soc-ok"
+#define FB_VAR_SUPER_PARTITION_NAME "super-partition-name"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 11c838a..08744ec 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -99,7 +99,8 @@
{FB_VAR_OFF_MODE_CHARGE_STATE, {GetOffModeChargeState, nullptr}},
{FB_VAR_BATTERY_VOLTAGE, {GetBatteryVoltage, nullptr}},
{FB_VAR_BATTERY_SOC_OK, {GetBatterySoCOk, nullptr}},
- {FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}}};
+ {FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}},
+ {FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}}};
if (args.size() < 2) {
return device->WriteFail("Missing argument");
diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp
index 66b90bf..7c9e1d0 100644
--- a/fastboot/device/flashing.cpp
+++ b/fastboot/device/flashing.cpp
@@ -148,13 +148,40 @@
// image.
std::string slot_suffix = device->GetCurrentSlot();
uint32_t slot_number = SlotNumberForSlotSuffix(slot_suffix);
- if (wipe || !ReadMetadata(super_name, slot_number)) {
+ std::unique_ptr<LpMetadata> old_metadata = ReadMetadata(super_name, slot_number);
+ if (wipe || !old_metadata) {
if (!FlashPartitionTable(super_name, *new_metadata.get())) {
return device->WriteFail("Unable to flash new partition table");
}
return device->WriteOkay("Successfully flashed partition table");
}
+ std::set<std::string> partitions_to_keep;
+ for (const auto& partition : old_metadata->partitions) {
+ // Preserve partitions in the other slot, but not the current slot.
+ std::string partition_name = GetPartitionName(partition);
+ if (!slot_suffix.empty() && GetPartitionSlotSuffix(partition_name) == slot_suffix) {
+ continue;
+ }
+ partitions_to_keep.emplace(partition_name);
+ }
+
+ // Do not preserve the scratch partition.
+ partitions_to_keep.erase("scratch");
+
+ if (!partitions_to_keep.empty()) {
+ std::unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(*new_metadata.get());
+ if (!builder->ImportPartitions(*old_metadata.get(), partitions_to_keep)) {
+ return device->WriteFail(
+ "Old partitions are not compatible with the new super layout; wipe needed");
+ }
+
+ new_metadata = builder->Export();
+ if (!new_metadata) {
+ return device->WriteFail("Unable to build new partition table; wipe needed");
+ }
+ }
+
// Write the new table to every metadata slot.
bool ok = true;
for (size_t i = 0; i < new_metadata->geometry.metadata_slot_count; i++) {
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index cbd2856..601af34 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -24,7 +24,9 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <ext4_utils/ext4_utils.h>
+#include <fs_mgr.h>
#include <healthhalutils/HealthHalUtils.h>
+#include <liblp/liblp.h>
#include "fastboot_device.h"
#include "flashing.h"
@@ -35,6 +37,7 @@
using ::android::hardware::fastboot::V1_0::FileSystemType;
using ::android::hardware::fastboot::V1_0::Result;
using ::android::hardware::fastboot::V1_0::Status;
+using namespace android::fs_mgr;
constexpr char kFastbootProtocolVersion[] = "0.4";
@@ -417,3 +420,10 @@
*message = android::base::GetProperty("ro.revision", "");
return true;
}
+
+bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& /* args */,
+ std::string* message) {
+ uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
+ *message = fs_mgr_get_super_partition_name(slot_number);
+ return true;
+}
diff --git a/fastboot/device/variables.h b/fastboot/device/variables.h
index 59b71e8..015a4c5 100644
--- a/fastboot/device/variables.h
+++ b/fastboot/device/variables.h
@@ -59,6 +59,8 @@
std::string* message);
bool GetBatterySoCOk(FastbootDevice* device, const std::vector<std::string>& args,
std::string* message);
+bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& args,
+ std::string* message);
// Helpers for getvar all.
std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device);
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3c6b1b7..625e047 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1129,25 +1129,6 @@
return fb->GetVar("is-userspace", &value) == fastboot::SUCCESS && value == "yes";
}
-static bool if_partition_exists(const std::string& partition, const std::string& slot) {
- std::string has_slot;
- std::string partition_name = partition;
-
- if (fb->GetVar("has-slot:" + partition, &has_slot) == fastboot::SUCCESS && has_slot == "yes") {
- if (slot == "") {
- std::string current_slot = get_current_slot();
- if (current_slot == "") {
- die("Failed to identify current slot");
- }
- partition_name += "_" + current_slot;
- } else {
- partition_name += "_" + slot;
- }
- }
- std::string partition_size;
- return fb->GetVar("partition-size:" + partition_name, &partition_size) == fastboot::SUCCESS;
-}
-
static void reboot_to_userspace_fastboot() {
fb->RebootTo("fastboot");
@@ -1200,6 +1181,15 @@
void FlashAllTool::Flash() {
DumpInfo();
CheckRequirements();
+
+ // Change the slot first, so we boot into the correct recovery image when
+ // using fastbootd.
+ if (slot_override_ == "all") {
+ set_active("a");
+ } else {
+ set_active(slot_override_);
+ }
+
DetermineSecondarySlot();
CollectImages();
@@ -1223,12 +1213,6 @@
// Flash OS images, resizing logical partitions as needed.
FlashImages(os_images_);
-
- if (slot_override_ == "all") {
- set_active("a");
- } else {
- set_active(slot_override_);
- }
}
void FlashAllTool::CheckRequirements() {
@@ -1243,7 +1227,7 @@
if (skip_secondary_) {
return;
}
- if (slot_override_ != "") {
+ if (slot_override_ != "" && slot_override_ != "all") {
secondary_slot_ = get_other_slot(slot_override_);
} else {
secondary_slot_ = get_other_slot();
@@ -1304,10 +1288,6 @@
}
void FlashAllTool::UpdateSuperPartition() {
- if (!if_partition_exists("super", "")) {
- return;
- }
-
int fd = source_.OpenFile("super_empty.img");
if (fd < 0) {
return;
@@ -1318,9 +1298,14 @@
if (!is_userspace_fastboot()) {
die("Failed to boot into userspace; one or more components might be unbootable.");
}
- fb->Download("super", fd, get_file_size(fd));
- std::string command = "update-super:super";
+ std::string super_name;
+ if (fb->GetVar("super-partition-name", &super_name) != fastboot::RetCode::SUCCESS) {
+ super_name = "super";
+ }
+ fb->Download(super_name, fd, get_file_size(fd));
+
+ std::string command = "update-super:" + super_name;
if (wipe_) {
command += ":wipe";
}
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index fc3a05c..e89c91c 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -403,10 +403,13 @@
static bool is_dt_fstab_compatible() {
std::string dt_value;
std::string file_name = get_android_dt_dir() + "/fstab/compatible";
- if (read_dt_file(file_name, &dt_value)) {
- if (dt_value == "android,fstab") {
- return true;
- }
+
+ if (read_dt_file(file_name, &dt_value) && dt_value == "android,fstab") {
+ // If there's no status property or its set to "ok" or "okay", then we use the DT fstab.
+ std::string status_value;
+ std::string status_file_name = get_android_dt_dir() + "/fstab/status";
+ return !read_dt_file(status_file_name, &status_value) || status_value == "ok" ||
+ status_value == "okay";
}
return false;
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 3cd33b1..4007ad9 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -184,22 +184,26 @@
if (!builder) {
return false;
}
-
- for (size_t i = 0; i < partition.num_extents; i++) {
- const LpMetadataExtent& extent = metadata.extents[partition.first_extent_index + i];
- if (extent.target_type == LP_TARGET_TYPE_LINEAR) {
- auto copy = std::make_unique<LinearExtent>(extent.num_sectors, extent.target_source,
- extent.target_data);
- builder->AddExtent(std::move(copy));
- } else if (extent.target_type == LP_TARGET_TYPE_ZERO) {
- auto copy = std::make_unique<ZeroExtent>(extent.num_sectors);
- builder->AddExtent(std::move(copy));
- }
- }
+ ImportExtents(builder, metadata, partition);
}
return true;
}
+void MetadataBuilder::ImportExtents(Partition* dest, const LpMetadata& metadata,
+ const LpMetadataPartition& source) {
+ for (size_t i = 0; i < source.num_extents; i++) {
+ const LpMetadataExtent& extent = metadata.extents[source.first_extent_index + i];
+ if (extent.target_type == LP_TARGET_TYPE_LINEAR) {
+ auto copy = std::make_unique<LinearExtent>(extent.num_sectors, extent.target_source,
+ extent.target_data);
+ dest->AddExtent(std::move(copy));
+ } else if (extent.target_type == LP_TARGET_TYPE_ZERO) {
+ auto copy = std::make_unique<ZeroExtent>(extent.num_sectors);
+ dest->AddExtent(std::move(copy));
+ }
+ }
+}
+
static bool VerifyDeviceProperties(const BlockDeviceInfo& device_info) {
if (device_info.logical_block_size % LP_SECTOR_SIZE != 0) {
LERROR << "Block device " << device_info.partition_name
@@ -471,13 +475,18 @@
return free_regions;
}
-bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
+bool MetadataBuilder::ValidatePartitionSizeChange(Partition* partition, uint64_t old_size,
+ uint64_t new_size) {
PartitionGroup* group = FindGroup(partition->group_name());
CHECK(group);
+ if (new_size <= old_size) {
+ return true;
+ }
+
// Figure out how much we need to allocate, and whether our group has
// enough space remaining.
- uint64_t space_needed = aligned_size - partition->size();
+ uint64_t space_needed = new_size - old_size;
if (group->maximum_size() > 0) {
uint64_t group_size = TotalSizeOfGroup(group);
if (group_size >= group->maximum_size() ||
@@ -488,7 +497,11 @@
return false;
}
}
+ return true;
+}
+bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
+ uint64_t space_needed = aligned_size - partition->size();
uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE;
DCHECK(sectors_needed * LP_SECTOR_SIZE == space_needed);
@@ -704,6 +717,10 @@
uint64_t aligned_size = AlignTo(requested_size, geometry_.logical_block_size);
uint64_t old_size = partition->size();
+ if (!ValidatePartitionSizeChange(partition, old_size, aligned_size)) {
+ return false;
+ }
+
if (aligned_size > old_size) {
if (!GrowPartition(partition, aligned_size)) {
return false;
@@ -750,5 +767,74 @@
}
}
+static bool CompareBlockDevices(const LpMetadataBlockDevice& first,
+ const LpMetadataBlockDevice& second) {
+ // Note: we don't compare alignment, since it's a performance thing and
+ // won't affect whether old extents continue to work.
+ return first.first_logical_sector == second.first_logical_sector && first.size == second.size &&
+ GetBlockDevicePartitionName(first) == GetBlockDevicePartitionName(second);
+}
+
+bool MetadataBuilder::ImportPartitions(const LpMetadata& metadata,
+ const std::set<std::string>& partition_names) {
+ // The block device list must be identical. We do not try to be clever and
+ // allow ordering changes or changes that don't affect partitions. This
+ // process is designed to allow the most common flashing scenarios and more
+ // complex ones should require a wipe.
+ if (metadata.block_devices.size() != block_devices_.size()) {
+ LINFO << "Block device tables does not match.";
+ return false;
+ }
+ for (size_t i = 0; i < metadata.block_devices.size(); i++) {
+ const LpMetadataBlockDevice& old_device = metadata.block_devices[i];
+ const LpMetadataBlockDevice& new_device = block_devices_[i];
+ if (!CompareBlockDevices(old_device, new_device)) {
+ LINFO << "Block device tables do not match";
+ return false;
+ }
+ }
+
+ // Import named partitions. Note that we do not attempt to merge group
+ // information here. If the device changed its group names, the old
+ // partitions will fail to merge. The same could happen if the group
+ // allocation sizes change.
+ for (const auto& partition : metadata.partitions) {
+ std::string partition_name = GetPartitionName(partition);
+ if (partition_names.find(partition_name) == partition_names.end()) {
+ continue;
+ }
+ if (!ImportPartition(metadata, partition)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool MetadataBuilder::ImportPartition(const LpMetadata& metadata,
+ const LpMetadataPartition& source) {
+ std::string partition_name = GetPartitionName(source);
+ Partition* partition = FindPartition(partition_name);
+ if (!partition) {
+ std::string group_name = GetPartitionGroupName(metadata.groups[source.group_index]);
+ partition = AddPartition(partition_name, group_name, source.attributes);
+ if (!partition) {
+ return false;
+ }
+ }
+ if (partition->size() > 0) {
+ LINFO << "Importing partition table would overwrite non-empty partition: "
+ << partition_name;
+ return false;
+ }
+
+ ImportExtents(partition, metadata, source);
+
+ if (!ValidatePartitionSizeChange(partition, 0, partition->size())) {
+ partition->RemoveExtents();
+ return false;
+ }
+ return true;
+}
+
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index c27e300..35cab38 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -632,3 +632,64 @@
EXPECT_EQ(metadata->extents[2].target_data, 1472);
EXPECT_EQ(metadata->extents[2].target_source, 2);
}
+
+TEST(liblp, ImportPartitionsOk) {
+ unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
+ ASSERT_NE(builder, nullptr);
+
+ Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
+ Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
+ ASSERT_NE(system, nullptr);
+ ASSERT_NE(vendor, nullptr);
+ EXPECT_EQ(builder->ResizePartition(system, 65536), true);
+ EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
+ EXPECT_EQ(builder->ResizePartition(system, 98304), true);
+
+ unique_ptr<LpMetadata> exported = builder->Export();
+ ASSERT_NE(exported, nullptr);
+
+ builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
+ ASSERT_NE(builder, nullptr);
+
+ ASSERT_TRUE(builder->ImportPartitions(*exported.get(), {"vendor"}));
+ EXPECT_NE(builder->FindPartition("vendor"), nullptr);
+ EXPECT_EQ(builder->FindPartition("system"), nullptr);
+
+ unique_ptr<LpMetadata> new_metadata = builder->Export();
+ ASSERT_NE(new_metadata, nullptr);
+
+ ASSERT_EQ(exported->partitions.size(), static_cast<size_t>(2));
+ ASSERT_EQ(GetPartitionName(exported->partitions[1]), "vendor");
+ ASSERT_EQ(new_metadata->partitions.size(), static_cast<size_t>(1));
+ ASSERT_EQ(GetPartitionName(new_metadata->partitions[0]), "vendor");
+
+ const LpMetadataExtent& extent_a =
+ exported->extents[exported->partitions[1].first_extent_index];
+ const LpMetadataExtent& extent_b =
+ new_metadata->extents[new_metadata->partitions[0].first_extent_index];
+ EXPECT_EQ(extent_a.num_sectors, extent_b.num_sectors);
+ EXPECT_EQ(extent_a.target_type, extent_b.target_type);
+ EXPECT_EQ(extent_a.target_data, extent_b.target_data);
+ EXPECT_EQ(extent_a.target_source, extent_b.target_source);
+}
+
+TEST(liblp, ImportPartitionsFail) {
+ unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
+ ASSERT_NE(builder, nullptr);
+
+ Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
+ Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
+ ASSERT_NE(system, nullptr);
+ ASSERT_NE(vendor, nullptr);
+ EXPECT_EQ(builder->ResizePartition(system, 65536), true);
+ EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
+ EXPECT_EQ(builder->ResizePartition(system, 98304), true);
+
+ unique_ptr<LpMetadata> exported = builder->Export();
+ ASSERT_NE(exported, nullptr);
+
+ // Different device size.
+ builder = MetadataBuilder::New(1024 * 2048, 1024, 2);
+ ASSERT_NE(builder, nullptr);
+ EXPECT_FALSE(builder->ImportPartitions(*exported.get(), {"system"}));
+}
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index f9de106..d5e3fed 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -22,6 +22,7 @@
#include <map>
#include <memory>
+#include <set>
#include "liblp.h"
#include "partition_opener.h"
@@ -225,6 +226,11 @@
bool GetBlockDeviceInfo(const std::string& partition_name, BlockDeviceInfo* info) const;
bool UpdateBlockDeviceInfo(const std::string& partition_name, const BlockDeviceInfo& info);
+ // Attempt to preserve the named partitions from an older metadata. If this
+ // is not possible (for example, the block device list has changed) then
+ // false is returned.
+ bool ImportPartitions(const LpMetadata& metadata, const std::set<std::string>& partition_names);
+
private:
MetadataBuilder();
MetadataBuilder(const MetadataBuilder&) = delete;
@@ -240,6 +246,10 @@
uint64_t TotalSizeOfGroup(PartitionGroup* group) const;
bool UpdateBlockDeviceInfo(size_t index, const BlockDeviceInfo& info);
bool FindBlockDeviceByName(const std::string& partition_name, uint32_t* index) const;
+ bool ValidatePartitionSizeChange(Partition* partition, uint64_t old_size, uint64_t new_size);
+ void ImportExtents(Partition* dest, const LpMetadata& metadata,
+ const LpMetadataPartition& source);
+ bool ImportPartition(const LpMetadata& metadata, const LpMetadataPartition& source);
struct Interval {
uint32_t device_index;
diff --git a/fs_mgr/liblp/include/liblp/liblp.h b/fs_mgr/liblp/include/liblp/liblp.h
index a5dac00..8723a7f 100644
--- a/fs_mgr/liblp/include/liblp/liblp.h
+++ b/fs_mgr/liblp/include/liblp/liblp.h
@@ -93,8 +93,9 @@
// Get the list of block device names required by the given metadata.
std::vector<std::string> GetBlockDevicePartitionNames(const LpMetadata& metadata);
-// Helper to return a slot number for a slot suffix.
+// Slot suffix helpers.
uint32_t SlotNumberForSlotSuffix(const std::string& suffix);
+std::string GetPartitionSlotSuffix(const std::string& partition_name);
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index 199d994..cce90a3 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -97,15 +97,15 @@
}
uint32_t SlotNumberForSlotSuffix(const std::string& suffix) {
- if (suffix.empty()) {
+ if (suffix.empty() || suffix == "a" || suffix == "_a") {
return 0;
- }
- if (suffix.size() != 2 || suffix[0] != '_' || suffix[1] < 'a') {
+ } else if (suffix == "b" || suffix == "_b") {
+ return 1;
+ } else {
LERROR << __PRETTY_FUNCTION__ << "slot '" << suffix
<< "' does not have a recognized format.";
return 0;
}
- return suffix[1] - 'a';
}
uint64_t GetTotalSuperPartitionSize(const LpMetadata& metadata) {
@@ -124,5 +124,13 @@
return list;
}
+std::string GetPartitionSlotSuffix(const std::string& partition_name) {
+ if (partition_name.size() <= 2) {
+ return "";
+ }
+ std::string suffix = partition_name.substr(partition_name.size() - 2);
+ return (suffix == "_a" || suffix == "_b") ? suffix : "";
+}
+
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/liblp/utility_test.cpp b/fs_mgr/liblp/utility_test.cpp
index bdf6dfd..0fa4590 100644
--- a/fs_mgr/liblp/utility_test.cpp
+++ b/fs_mgr/liblp/utility_test.cpp
@@ -24,10 +24,12 @@
TEST(liblp, SlotNumberForSlotSuffix) {
EXPECT_EQ(SlotNumberForSlotSuffix(""), 0);
+ EXPECT_EQ(SlotNumberForSlotSuffix("a"), 0);
EXPECT_EQ(SlotNumberForSlotSuffix("_a"), 0);
+ EXPECT_EQ(SlotNumberForSlotSuffix("b"), 1);
EXPECT_EQ(SlotNumberForSlotSuffix("_b"), 1);
- EXPECT_EQ(SlotNumberForSlotSuffix("_c"), 2);
- EXPECT_EQ(SlotNumberForSlotSuffix("_d"), 3);
+ EXPECT_EQ(SlotNumberForSlotSuffix("_c"), 0);
+ EXPECT_EQ(SlotNumberForSlotSuffix("_d"), 0);
}
TEST(liblp, GetMetadataOffset) {
@@ -60,3 +62,11 @@
EXPECT_EQ(AlignTo(32, 32, 30), 62);
EXPECT_EQ(AlignTo(17, 32, 30), 30);
}
+
+TEST(liblp, GetPartitionSlotSuffix) {
+ EXPECT_EQ(GetPartitionSlotSuffix("system"), "");
+ EXPECT_EQ(GetPartitionSlotSuffix("_"), "");
+ EXPECT_EQ(GetPartitionSlotSuffix("_a"), "");
+ EXPECT_EQ(GetPartitionSlotSuffix("system_a"), "_a");
+ EXPECT_EQ(GetPartitionSlotSuffix("system_b"), "_b");
+}
diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp
index c740bd4..f4c9b99 100644
--- a/fs_mgr/liblp/writer.cpp
+++ b/fs_mgr/liblp/writer.cpp
@@ -82,12 +82,8 @@
// Perform sanity checks so we don't accidentally overwrite valid metadata
// with potentially invalid metadata, or random partition data with metadata.
-static bool ValidateAndSerializeMetadata(int fd, const LpMetadata& metadata, std::string* blob) {
- uint64_t blockdevice_size;
- if (!GetDescriptorSize(fd, &blockdevice_size)) {
- return false;
- }
-
+static bool ValidateAndSerializeMetadata(const IPartitionOpener& opener, const LpMetadata& metadata,
+ std::string* blob) {
const LpMetadataHeader& header = metadata.header;
const LpMetadataGeometry& geometry = metadata.geometry;
@@ -104,7 +100,7 @@
// metadata.
uint64_t reserved_size = LP_METADATA_GEOMETRY_SIZE +
uint64_t(geometry.metadata_max_size) * geometry.metadata_slot_count;
- uint64_t total_reserved = reserved_size * 2;
+ uint64_t total_reserved = LP_PARTITION_RESERVED_BYTES + reserved_size * 2;
const LpMetadataBlockDevice* super_device = GetMetadataSuperBlockDevice(metadata);
if (!super_device) {
@@ -112,15 +108,27 @@
return false;
}
- if (total_reserved > blockdevice_size ||
- total_reserved > super_device->first_logical_sector * LP_SECTOR_SIZE) {
+ if (total_reserved > super_device->first_logical_sector * LP_SECTOR_SIZE) {
LERROR << "Not enough space to store all logical partition metadata slots.";
return false;
}
- if (blockdevice_size != super_device->size) {
- LERROR << "Block device size " << blockdevice_size
- << " does not match metadata requested size " << super_device->size;
- return false;
+ for (const auto& block_device : metadata.block_devices) {
+ std::string partition_name = GetBlockDevicePartitionName(block_device);
+ if ((block_device.first_logical_sector + 1) * LP_SECTOR_SIZE > block_device.size) {
+ LERROR << "Block device " << partition_name << " has invalid first sector "
+ << block_device.first_logical_sector << " for size " << block_device.size;
+ return false;
+ }
+ BlockDeviceInfo info;
+ if (!opener.GetInfo(partition_name, &info)) {
+ PERROR << partition_name << ": ioctl";
+ return false;
+ }
+ if (info.size != block_device.size) {
+ LERROR << "Block device " << partition_name << " size mismatch (expected"
+ << block_device.size << ", got " << info.size << ")";
+ return false;
+ }
}
// Make sure all partition entries reference valid extents.
@@ -230,7 +238,7 @@
// basic checks that the geometry and tables are coherent, and will fit
// on the given block device.
std::string metadata_blob;
- if (!ValidateAndSerializeMetadata(fd, metadata, &metadata_blob)) {
+ if (!ValidateAndSerializeMetadata(opener, metadata, &metadata_blob)) {
return false;
}
@@ -295,7 +303,7 @@
// basic checks that the geometry and tables are coherent, and will fit
// on the given block device.
std::string blob;
- if (!ValidateAndSerializeMetadata(fd, metadata, &blob)) {
+ if (!ValidateAndSerializeMetadata(opener, metadata, &blob)) {
return false;
}
@@ -327,7 +335,7 @@
// synchronize the backup copy. This guarantees that a partial write
// still leaves one copy intact.
std::string old_blob;
- if (!ValidateAndSerializeMetadata(fd, *primary.get(), &old_blob)) {
+ if (!ValidateAndSerializeMetadata(opener, *primary.get(), &old_blob)) {
LERROR << "Error serializing primary metadata to repair corrupted backup";
return false;
}
@@ -339,7 +347,7 @@
// The backup copy is coherent, and the primary is not. Sync it for
// safety.
std::string old_blob;
- if (!ValidateAndSerializeMetadata(fd, *backup.get(), &old_blob)) {
+ if (!ValidateAndSerializeMetadata(opener, *backup.get(), &old_blob)) {
LERROR << "Error serializing primary metadata to repair corrupted backup";
return false;
}
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 6b908d3..98c0879 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -274,9 +274,8 @@
echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
die "overlay takeover after remount"
!(adb_sh grep "^overlay " /proc/mounts </dev/null | grep " overlay ro,") &&
- !(adb_sh grep " rw," /proc/mounts </dev/null |
- skip_administrative_mounts) ||
- die "remount overlayfs missed a spot"
+ !(adb_sh grep " rw," /proc/mounts </dev/null | skip_administrative_mounts) ||
+ die "remount overlayfs missed a spot (ro)"
adb_su "sed -n '1,/overlay \\/system/p' /proc/mounts" </dev/null |
skip_administrative_mounts |
diff --git a/run-as/.clang-format b/run-as/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/run-as/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp
index ac470d4..971b9f4 100644
--- a/run-as/run-as.cpp
+++ b/run-as/run-as.cpp
@@ -144,7 +144,7 @@
// Some devices can disable running run-as, such as Chrome OS when running in
// non-developer mode.
if (android::base::GetBoolProperty("ro.boot.disable_runas", false)) {
- error(1, 0, "run-as is disabled from the kernel commandline");
+ error(1, 0, "run-as is disabled from the kernel commandline");
}
char* pkgname = argv[1];