Reject update if static partition is a super block device.
If the static partition is currently used as a super block
device, do not write to it.
Test: manual OTA
Change-Id: I167cfccf7d9df7d09ab633c8928697b57d3b314b
diff --git a/boot_control_android.cc b/boot_control_android.cc
index b99554c..f4e0a4b 100644
--- a/boot_control_android.cc
+++ b/boot_control_android.cc
@@ -105,25 +105,31 @@
return true;
}
-namespace {
+bool BootControlAndroid::IsSuperBlockDevice(
+ const base::FilePath& device_dir,
+ Slot slot,
+ const string& partition_name_suffix) const {
+ string source_device =
+ device_dir.Append(fs_mgr_get_super_partition_name(slot)).value();
+ auto source_metadata = dynamic_control_->LoadMetadataBuilder(
+ source_device, slot, BootControlInterface::kInvalidSlot);
+ return source_metadata->HasBlockDevice(partition_name_suffix);
+}
-enum class DynamicPartitionDeviceStatus {
- SUCCESS,
- ERROR,
- TRY_STATIC,
-};
-
-DynamicPartitionDeviceStatus GetDynamicPartitionDevice(
- DynamicPartitionControlInterface* dynamic_control,
- const string& super_device,
+BootControlAndroid::DynamicPartitionDeviceStatus
+BootControlAndroid::GetDynamicPartitionDevice(
+ const base::FilePath& device_dir,
const string& partition_name_suffix,
Slot slot,
- string* device) {
- if (!dynamic_control->IsDynamicPartitionsEnabled()) {
+ string* device) const {
+ if (!dynamic_control_->IsDynamicPartitionsEnabled()) {
return DynamicPartitionDeviceStatus::TRY_STATIC;
}
- auto builder = dynamic_control->LoadMetadataBuilder(
+ string super_device =
+ device_dir.Append(fs_mgr_get_super_partition_name(slot)).value();
+
+ auto builder = dynamic_control_->LoadMetadataBuilder(
super_device, slot, BootControlInterface::kInvalidSlot);
if (builder == nullptr) {
@@ -135,13 +141,25 @@
if (builder->FindPartition(partition_name_suffix) == nullptr) {
LOG(INFO) << partition_name_suffix
<< " is not in super partition metadata.";
+
+ Slot current_slot = GetCurrentSlot();
+ if (IsSuperBlockDevice(device_dir, current_slot, partition_name_suffix)) {
+ LOG(ERROR) << "The static partition " << partition_name_suffix
+ << " is a block device for current metadata ("
+ << fs_mgr_get_super_partition_name(current_slot) << ", slot "
+ << BootControlInterface::SlotName(current_slot)
+ << "). It cannot be used as a logical partition.";
+ return DynamicPartitionDeviceStatus::ERROR;
+ }
+
return DynamicPartitionDeviceStatus::TRY_STATIC;
}
- DmDeviceState state = dynamic_control->GetState(partition_name_suffix);
+ DmDeviceState state = dynamic_control_->GetState(partition_name_suffix);
if (state == DmDeviceState::ACTIVE) {
- if (dynamic_control->GetDmDevicePathByName(partition_name_suffix, device)) {
+ if (dynamic_control_->GetDmDevicePathByName(partition_name_suffix,
+ device)) {
LOG(INFO) << partition_name_suffix
<< " is mapped on device mapper: " << *device;
return DynamicPartitionDeviceStatus::SUCCESS;
@@ -156,11 +174,11 @@
// Hence, if it is not mapped, we assume it is a source partition and
// map it without force_writable.
if (state == DmDeviceState::INVALID) {
- if (dynamic_control->MapPartitionOnDeviceMapper(super_device,
- partition_name_suffix,
- slot,
- false /* force_writable */,
- device)) {
+ if (dynamic_control_->MapPartitionOnDeviceMapper(super_device,
+ partition_name_suffix,
+ slot,
+ false /* force_writable */,
+ device)) {
return DynamicPartitionDeviceStatus::SUCCESS;
}
return DynamicPartitionDeviceStatus::ERROR;
@@ -171,7 +189,6 @@
<< static_cast<std::underlying_type_t<DmDeviceState>>(state);
return DynamicPartitionDeviceStatus::ERROR;
}
-} // namespace
bool BootControlAndroid::GetPartitionDevice(const string& partition_name,
Slot slot,
@@ -188,13 +205,8 @@
}
base::FilePath device_dir(device_dir_str);
- string super_device =
- device_dir.Append(fs_mgr_get_super_partition_name(slot)).value();
- switch (GetDynamicPartitionDevice(dynamic_control_.get(),
- super_device,
- partition_name_suffix,
- slot,
- device)) {
+ switch (GetDynamicPartitionDevice(
+ device_dir, partition_name_suffix, slot, device)) {
case DynamicPartitionDeviceStatus::SUCCESS:
return true;
case DynamicPartitionDeviceStatus::TRY_STATIC:
diff --git a/boot_control_android.h b/boot_control_android.h
index d831273..d6590fb 100644
--- a/boot_control_android.h
+++ b/boot_control_android.h
@@ -64,6 +64,24 @@
// Wrapper method of IBootControl::getSuffix().
bool GetSuffix(Slot slot, std::string* out) const;
+ enum class DynamicPartitionDeviceStatus {
+ SUCCESS,
+ ERROR,
+ TRY_STATIC,
+ };
+
+ DynamicPartitionDeviceStatus GetDynamicPartitionDevice(
+ const base::FilePath& device_dir,
+ const std::string& partition_name_suffix,
+ Slot slot,
+ std::string* device) const;
+
+ // Return true if |partition_name_suffix| is a block device of
+ // super partition metadata slot |slot|.
+ bool IsSuperBlockDevice(const base::FilePath& device_dir,
+ Slot slot,
+ const std::string& partition_name_suffix) const;
+
DISALLOW_COPY_AND_ASSIGN(BootControlAndroid);
};