Do not map dynamic partitions on VABC devices
With VABC, we no longer need to map all partitions before
reading/writing, so don't try to map them.
1. modify GetPartitionDevice to return empty path for target partitions
on VABC
2. Add a separate GetMountableTargetDevice for obtaining a mountable
device path, specifically for postinstall
Test: treehugger
Change-Id: Ib1f608914fc49c677ce7389140ca79b028171191
diff --git a/aosp/boot_control_android.cc b/aosp/boot_control_android.cc
index bda65be..3b20fc2 100644
--- a/aosp/boot_control_android.cc
+++ b/aosp/boot_control_android.cc
@@ -30,8 +30,6 @@
using std::string;
-using android::dm::DmDeviceState;
-using android::hardware::hidl_string;
using android::hardware::Return;
using android::hardware::boot::V1_0::BoolResult;
using android::hardware::boot::V1_0::CommandResult;
@@ -183,4 +181,12 @@
return dynamic_control_.get();
}
+std::optional<PartitionDevice> BootControlAndroid::GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload) const {
+ return dynamic_control_->GetPartitionDevice(
+ partition_name, slot, current_slot, not_in_payload);
+}
} // namespace chromeos_update_engine
diff --git a/aosp/boot_control_android.h b/aosp/boot_control_android.h
index e288723..926023a 100644
--- a/aosp/boot_control_android.h
+++ b/aosp/boot_control_android.h
@@ -44,6 +44,11 @@
// BootControlInterface overrides.
unsigned int GetNumSlots() const override;
BootControlInterface::Slot GetCurrentSlot() const override;
+ std::optional<PartitionDevice> GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload = false) const override;
bool GetPartitionDevice(const std::string& partition_name,
BootControlInterface::Slot slot,
bool not_in_payload,
diff --git a/aosp/dynamic_partition_control_android.cc b/aosp/dynamic_partition_control_android.cc
index 3ced3e0..1575796 100644
--- a/aosp/dynamic_partition_control_android.cc
+++ b/aosp/dynamic_partition_control_android.cc
@@ -16,6 +16,7 @@
#include "update_engine/aosp/dynamic_partition_control_android.h"
+#include <algorithm>
#include <chrono> // NOLINT(build/c++11) - using libsnapshot / liblp API
#include <cstdint>
#include <map>
@@ -960,47 +961,16 @@
bool not_in_payload,
std::string* device,
bool* is_dynamic) {
- const auto& partition_name_suffix =
- partition_name + SlotSuffixForSlotNumber(slot);
- std::string device_dir_str;
- TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
- base::FilePath device_dir(device_dir_str);
-
- if (is_dynamic) {
- *is_dynamic = false;
- }
-
- // When looking up target partition devices, treat them as static if the
- // current payload doesn't encode them as dynamic partitions. This may happen
- // when applying a retrofit update on top of a dynamic-partitions-enabled
- // build.
- if (GetDynamicPartitionsFeatureFlag().IsEnabled() &&
- (slot == current_slot || is_target_dynamic_)) {
- switch (GetDynamicPartitionDevice(device_dir,
- partition_name_suffix,
- slot,
- current_slot,
- not_in_payload,
- device)) {
- case DynamicPartitionDeviceStatus::SUCCESS:
- if (is_dynamic) {
- *is_dynamic = true;
- }
- return true;
- case DynamicPartitionDeviceStatus::TRY_STATIC:
- break;
- case DynamicPartitionDeviceStatus::ERROR: // fallthrough
- default:
- return false;
- }
- }
- base::FilePath path = device_dir.Append(partition_name_suffix);
- if (!DeviceExists(path.value())) {
- LOG(ERROR) << "Device file " << path.value() << " does not exist.";
+ auto partition_dev = GetPartitionDevice(partition_name, slot, current_slot);
+ if (!partition_dev.has_value()) {
return false;
}
-
- *device = path.value();
+ if (device) {
+ *device = std::move(partition_dev->rw_device_path);
+ }
+ if (is_dynamic) {
+ *is_dynamic = partition_dev->is_dynamic;
+ }
return true;
}
@@ -1013,6 +983,73 @@
partition_name, slot, current_slot, false, device, nullptr);
}
+static std::string GetStaticDevicePath(
+ const base::FilePath& device_dir,
+ const std::string& partition_name_suffixed) {
+ base::FilePath path = device_dir.Append(partition_name_suffixed);
+ return path.value();
+}
+
+std::optional<PartitionDevice>
+DynamicPartitionControlAndroid::GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload) {
+ std::string device_dir_str;
+ if (!GetDeviceDir(&device_dir_str)) {
+ LOG(ERROR) << "Failed to GetDeviceDir()";
+ return {};
+ }
+ const base::FilePath device_dir(device_dir_str);
+ // When VABC is enabled, we can't get device path for dynamic partitions in
+ // target slot.
+ const auto& partition_name_suffix =
+ partition_name + SlotSuffixForSlotNumber(slot);
+ if (GetVirtualAbCompressionFeatureFlag().IsEnabled() &&
+ IsDynamicPartition(partition_name) && slot != current_slot) {
+ return {{.mountable_device_path =
+ GetStaticDevicePath(device_dir, partition_name_suffix),
+ .is_dynamic = true}};
+ }
+
+ // When looking up target partition devices, treat them as static if the
+ // current payload doesn't encode them as dynamic partitions. This may happen
+ // when applying a retrofit update on top of a dynamic-partitions-enabled
+ // build.
+ std::string device;
+ if (GetDynamicPartitionsFeatureFlag().IsEnabled() &&
+ (slot == current_slot || is_target_dynamic_)) {
+ switch (GetDynamicPartitionDevice(device_dir,
+ partition_name_suffix,
+ slot,
+ current_slot,
+ not_in_payload,
+ &device)) {
+ case DynamicPartitionDeviceStatus::SUCCESS:
+ return {{.rw_device_path = device,
+ .mountable_device_path = device,
+ .is_dynamic = true}};
+
+ case DynamicPartitionDeviceStatus::TRY_STATIC:
+ break;
+ case DynamicPartitionDeviceStatus::ERROR: // fallthrough
+ default:
+ return {};
+ }
+ }
+ // Try static partitions.
+ auto static_path = GetStaticDevicePath(device_dir, partition_name_suffix);
+ if (!DeviceExists(static_path)) {
+ LOG(ERROR) << "Device file " << static_path << " does not exist.";
+ return {};
+ }
+
+ return {{.rw_device_path = static_path,
+ .mountable_device_path = static_path,
+ .is_dynamic = false}};
+}
+
bool DynamicPartitionControlAndroid::IsSuperBlockDevice(
const base::FilePath& device_dir,
uint32_t current_slot,
@@ -1294,4 +1331,5 @@
dynamic_partition_list_.end(),
partition_name) != dynamic_partition_list_.end();
}
+
} // namespace chromeos_update_engine
diff --git a/aosp/dynamic_partition_control_android.h b/aosp/dynamic_partition_control_android.h
index 4a2b114..ecab6fa 100644
--- a/aosp/dynamic_partition_control_android.h
+++ b/aosp/dynamic_partition_control_android.h
@@ -35,6 +35,7 @@
public:
DynamicPartitionControlAndroid();
~DynamicPartitionControlAndroid();
+
FeatureFlag GetDynamicPartitionsFeatureFlag() override;
FeatureFlag GetVirtualAbFeatureFlag() override;
FeatureFlag GetVirtualAbCompressionFeatureFlag() override;
@@ -71,6 +72,13 @@
// Note: this function is only used by BootControl*::GetPartitionDevice.
// Other callers should prefer BootControl*::GetPartitionDevice over
// BootControl*::GetDynamicPartitionControl()->GetPartitionDevice().
+ std::optional<PartitionDevice> GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload = false);
+ // Deprecated, please use GetPartitionDevice(string, uint32_t, uint32_t);
+ // TODO(zhangkelvin) Remove below deprecated APIs.
bool GetPartitionDevice(const std::string& partition_name,
uint32_t slot,
uint32_t current_slot,
@@ -110,10 +118,10 @@
virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder(
const std::string& super_device, uint32_t slot);
- // Retrieves metadata from |super_device| at slot |source_slot|. And modifies
- // the metadata so that during updates, the metadata can be written to
- // |target_slot|. In particular, on retrofit devices, the returned metadata
- // automatically includes block devices at |target_slot|.
+ // Retrieves metadata from |super_device| at slot |source_slot|. And
+ // modifies the metadata so that during updates, the metadata can be written
+ // to |target_slot|. In particular, on retrofit devices, the returned
+ // metadata automatically includes block devices at |target_slot|.
virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder(
const std::string& super_device,
uint32_t source_slot,
@@ -210,6 +218,9 @@
bool MapAllPartitions() override;
+ void SetSourceSlot(uint32_t slot) { source_slot_ = slot; }
+ void SetTargetSlot(uint32_t slot) { target_slot_ = slot; }
+
private:
friend class DynamicPartitionControlAndroidTest;
friend class SnapshotPartitionTestP;
@@ -231,8 +242,8 @@
uint32_t target_slot,
const DeltaArchiveManifest& manifest);
- // Helper for PreparePartitionsForUpdate. Used for snapshotted partitions for
- // Virtual A/B update.
+ // Helper for PreparePartitionsForUpdate. Used for snapshotted partitions
+ // for Virtual A/B update.
bool PrepareSnapshotPartitionsForUpdate(uint32_t source_slot,
uint32_t target_slot,
const DeltaArchiveManifest& manifest,
@@ -270,17 +281,20 @@
// Returns true if metadata is expected to be mounted, false otherwise.
// Note that it returns false on non-Virtual A/B devices.
//
- // Almost all functions of SnapshotManager depends on metadata being mounted.
+ // Almost all functions of SnapshotManager depends on metadata being
+ // mounted.
// - In Android mode for Virtual A/B devices, assume it is mounted. If not,
// let caller fails when calling into SnapshotManager.
- // - In recovery for Virtual A/B devices, it is possible that metadata is not
+ // - In recovery for Virtual A/B devices, it is possible that metadata is
+ // not
// formatted, hence it cannot be mounted. Caller should not call into
// SnapshotManager.
- // - On non-Virtual A/B devices, updates do not depend on metadata partition.
+ // - On non-Virtual A/B devices, updates do not depend on metadata
+ // partition.
// Caller should not call into SnapshotManager.
//
- // This function does NOT mount metadata partition. Use EnsureMetadataMounted
- // to mount metadata partition.
+ // This function does NOT mount metadata partition. Use
+ // EnsureMetadataMounted to mount metadata partition.
bool ExpectMetadataMounted();
// Ensure /metadata is mounted. Returns true if successful, false otherwise.
@@ -303,6 +317,7 @@
// Whether the target partitions should be loaded as dynamic partitions. Set
// by PreparePartitionsForUpdate() per each update.
bool is_target_dynamic_ = false;
+
uint32_t source_slot_ = UINT32_MAX;
uint32_t target_slot_ = UINT32_MAX;
std::vector<std::string> dynamic_partition_list_;
diff --git a/aosp/dynamic_partition_control_android_unittest.cc b/aosp/dynamic_partition_control_android_unittest.cc
index 7e751db..af5ae2c 100644
--- a/aosp/dynamic_partition_control_android_unittest.cc
+++ b/aosp/dynamic_partition_control_android_unittest.cc
@@ -16,6 +16,7 @@
#include "update_engine/aosp/dynamic_partition_control_android.h"
+#include <algorithm>
#include <set>
#include <vector>
@@ -38,6 +39,7 @@
using testing::_;
using testing::AnyNumber;
using testing::AnyOf;
+using testing::AtLeast;
using testing::Invoke;
using testing::NiceMock;
using testing::Not;
@@ -55,6 +57,8 @@
.WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
.WillByDefault(Return(FeatureFlag(FeatureFlag::Value::NONE)));
+ ON_CALL(dynamicControl(), GetVirtualAbCompressionFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::NONE)));
ON_CALL(dynamicControl(), GetDeviceDir(_))
.WillByDefault(Invoke([](auto path) {
@@ -217,6 +221,8 @@
void SetUp() override {
DynamicPartitionControlAndroidTest::SetUp();
SetSlots(GetParam());
+ dynamicControl().SetSourceSlot(source());
+ dynamicControl().SetTargetSlot(target());
}
};
@@ -386,6 +392,84 @@
EXPECT_EQ(GetDevice(T("bar")), bar_device);
}
+TEST_P(DynamicPartitionControlAndroidTestP, GetMountableDevicePath) {
+ ON_CALL(dynamicControl(), GetDynamicPartitionsFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+ ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+ ON_CALL(dynamicControl(), GetVirtualAbCompressionFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::NONE)));
+ ON_CALL(dynamicControl(), IsDynamicPartition(_)).WillByDefault(Return(true));
+
+ EXPECT_CALL(dynamicControl(),
+ DeviceExists(AnyOf(GetDevice(S("vendor")),
+ GetDevice(T("vendor")),
+ GetDevice(S("system")),
+ GetDevice(T("system")))))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(
+ dynamicControl(),
+ GetState(AnyOf(S("vendor"), T("vendor"), S("system"), T("system"))))
+ .WillRepeatedly(Return(DmDeviceState::ACTIVE));
+
+ SetMetadata(source(), {{S("system"), 2_GiB}, {S("vendor"), 1_GiB}});
+ SetMetadata(target(), {{T("system"), 2_GiB}, {T("vendor"), 1_GiB}});
+ std::string device;
+ ASSERT_TRUE(dynamicControl().GetPartitionDevice(
+ "system", source(), source(), &device));
+ ASSERT_EQ(GetDmDevice(S("system")), device);
+
+ ASSERT_TRUE(dynamicControl().GetPartitionDevice(
+ "system", target(), source(), &device));
+ ASSERT_EQ(GetDevice(T("system")), device);
+
+ // If VABC is disabled, mountable device path should be same as device path.
+ auto device_info =
+ dynamicControl().GetPartitionDevice("system", target(), source());
+ ASSERT_TRUE(device_info.has_value());
+ ASSERT_EQ(device_info->mountable_device_path, device);
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, GetMountableDevicePathVABC) {
+ ON_CALL(dynamicControl(), GetDynamicPartitionsFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+ ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+ ON_CALL(dynamicControl(), GetVirtualAbCompressionFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+ EXPECT_CALL(dynamicControl(), IsDynamicPartition(_))
+ .Times(AtLeast(1))
+ .WillRepeatedly(Return(true));
+
+ EXPECT_CALL(dynamicControl(),
+ DeviceExists(AnyOf(GetDevice(S("vendor")),
+ GetDevice(T("vendor")),
+ GetDevice(S("system")),
+ GetDevice(T("system")))))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(
+ dynamicControl(),
+ GetState(AnyOf(S("vendor"), T("vendor"), S("system"), T("system"))))
+ .WillRepeatedly(Return(DmDeviceState::ACTIVE));
+
+ SetMetadata(source(), {{S("system"), 2_GiB}, {S("vendor"), 1_GiB}});
+ SetMetadata(target(), {{T("system"), 2_GiB}, {T("vendor"), 1_GiB}});
+
+ std::string device;
+ ASSERT_TRUE(dynamicControl().GetPartitionDevice(
+ "system", source(), source(), &device));
+ ASSERT_EQ(GetDmDevice(S("system")), device);
+
+ ASSERT_TRUE(dynamicControl().GetPartitionDevice(
+ "system", target(), source(), &device));
+ ASSERT_EQ("", device);
+
+ auto device_info =
+ dynamicControl().GetPartitionDevice("system", target(), source());
+ ASSERT_TRUE(device_info.has_value());
+ ASSERT_EQ(device_info->mountable_device_path, GetDevice(T("system")));
+}
+
TEST_P(DynamicPartitionControlAndroidTestP,
GetPartitionDeviceWhenResumingUpdate) {
// Static partition bar_{a,b} exists.
diff --git a/aosp/dynamic_partition_test_utils.h b/aosp/dynamic_partition_test_utils.h
index c7be1cb..c518382 100644
--- a/aosp/dynamic_partition_test_utils.h
+++ b/aosp/dynamic_partition_test_utils.h
@@ -47,7 +47,7 @@
constexpr const uint32_t kMaxNumSlots = 2;
constexpr const char* kSlotSuffixes[kMaxNumSlots] = {"_a", "_b"};
-constexpr const char* kFakeDevicePath = "/fake/dev/path/";
+constexpr std::string_view kFakeDevicePath = "/fake/dev/path/";
constexpr const char* kFakeDmDevicePath = "/fake/dm/dev/path/";
constexpr const uint32_t kFakeMetadataSize = 65536;
constexpr const char* kDefaultGroup = "foo";
@@ -112,7 +112,7 @@
}
inline std::string GetDevice(const std::string& name) {
- return kFakeDevicePath + name;
+ return std::string(kFakeDevicePath) + name;
}
inline std::string GetDmDevice(const std::string& name) {
diff --git a/aosp/mock_dynamic_partition_control_android.h b/aosp/mock_dynamic_partition_control_android.h
index 8d8ddb3..1d4bb14 100644
--- a/aosp/mock_dynamic_partition_control_android.h
+++ b/aosp/mock_dynamic_partition_control_android.h
@@ -70,6 +70,7 @@
MOCK_METHOD(FeatureFlag, GetDynamicPartitionsFeatureFlag, (), (override));
MOCK_METHOD(std::string, GetSuperPartitionName, (uint32_t), (override));
MOCK_METHOD(FeatureFlag, GetVirtualAbFeatureFlag, (), (override));
+ MOCK_METHOD(FeatureFlag, GetVirtualAbCompressionFeatureFlag, (), (override));
MOCK_METHOD(bool, FinishUpdate, (bool), (override));
MOCK_METHOD(bool,
GetSystemOtherPath,
@@ -132,6 +133,8 @@
return DynamicPartitionControlAndroid::PrepareDynamicPartitionsForUpdate(
source_slot, target_slot, manifest, delete_source);
}
+ using DynamicPartitionControlAndroid::SetSourceSlot;
+ using DynamicPartitionControlAndroid::SetTargetSlot;
};
} // namespace chromeos_update_engine
diff --git a/common/boot_control_interface.h b/common/boot_control_interface.h
index c93de5c..3b61add 100644
--- a/common/boot_control_interface.h
+++ b/common/boot_control_interface.h
@@ -75,6 +75,11 @@
Slot slot,
std::string* device) const = 0;
+ virtual std::optional<PartitionDevice> GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload = false) const = 0;
// Returns whether the passed |slot| is marked as bootable. Returns false if
// the slot is invalid.
virtual bool IsSlotBootable(Slot slot) const = 0;
diff --git a/common/boot_control_stub.cc b/common/boot_control_stub.cc
index 907f670..a1cc055 100644
--- a/common/boot_control_stub.cc
+++ b/common/boot_control_stub.cc
@@ -44,6 +44,15 @@
return false;
}
+std::optional<PartitionDevice> BootControlStub::GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload) const {
+ LOG(ERROR) << __FUNCTION__ << " should never be called.";
+ return {};
+}
+
bool BootControlStub::GetPartitionDevice(const string& partition_name,
Slot slot,
string* device) const {
diff --git a/common/boot_control_stub.h b/common/boot_control_stub.h
index a1bdb96..dcddbae 100644
--- a/common/boot_control_stub.h
+++ b/common/boot_control_stub.h
@@ -48,6 +48,11 @@
bool GetPartitionDevice(const std::string& partition_name,
BootControlInterface::Slot slot,
std::string* device) const override;
+ std::optional<PartitionDevice> GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload = false) const override;
bool IsSlotBootable(BootControlInterface::Slot slot) const override;
bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
bool SetActiveBootSlot(BootControlInterface::Slot slot) override;
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index 1362c19..855d6e8 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -36,6 +36,12 @@
namespace chromeos_update_engine {
+struct PartitionDevice {
+ std::string rw_device_path;
+ std::string mountable_device_path;
+ bool is_dynamic;
+};
+
struct FeatureFlag {
enum class Value { NONE = 0, RETROFIT, LAUNCH };
constexpr explicit FeatureFlag(Value value) : value_(value) {}
diff --git a/common/fake_boot_control.h b/common/fake_boot_control.h
index 98b93e6..fc7839d 100644
--- a/common/fake_boot_control.h
+++ b/common/fake_boot_control.h
@@ -51,14 +51,16 @@
bool not_in_payload,
std::string* device,
bool* is_dynamic) const override {
- if (slot >= num_slots_)
+ auto dev =
+ GetPartitionDevice(partition_name, slot, current_slot_, not_in_payload);
+ if (!dev.has_value()) {
return false;
- auto part_it = devices_[slot].find(partition_name);
- if (part_it == devices_[slot].end())
- return false;
- *device = part_it->second;
- if (is_dynamic != nullptr) {
- *is_dynamic = false;
+ }
+ if (is_dynamic) {
+ *is_dynamic = dev->is_dynamic;
+ }
+ if (device) {
+ *device = dev->rw_device_path;
}
return true;
}
@@ -120,6 +122,25 @@
return dynamic_partition_control_.get();
}
+ std::optional<PartitionDevice> GetPartitionDevice(
+ const std::string& partition_name,
+ uint32_t slot,
+ uint32_t current_slot,
+ bool not_in_payload = false) const override {
+ if (slot >= devices_.size()) {
+ return {};
+ }
+ auto device_path = devices_[slot].find(partition_name);
+ if (device_path == devices_[slot].end()) {
+ return {};
+ }
+ PartitionDevice device;
+ device.is_dynamic = false;
+ device.rw_device_path = device_path->second;
+ device.mountable_device_path = device.rw_device_path;
+ return device;
+ }
+
private:
BootControlInterface::Slot num_slots_{2};
BootControlInterface::Slot current_slot_{0};
diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc
index 4a37836..f4bbeb4 100644
--- a/payload_consumer/install_plan.cc
+++ b/payload_consumer/install_plan.cc
@@ -109,18 +109,19 @@
for (Partition& partition : partitions) {
if (source_slot != BootControlInterface::kInvalidSlot &&
partition.source_size > 0) {
- result = boot_control->GetPartitionDevice(
- partition.name, source_slot, &partition.source_path) &&
- result;
+ TEST_AND_RETURN_FALSE(boot_control->GetPartitionDevice(
+ partition.name, source_slot, &partition.source_path));
} else {
partition.source_path.clear();
}
if (target_slot != BootControlInterface::kInvalidSlot &&
partition.target_size > 0) {
- result = boot_control->GetPartitionDevice(
- partition.name, target_slot, &partition.target_path) &&
- result;
+ auto device = boot_control->GetPartitionDevice(
+ partition.name, target_slot, source_slot);
+ TEST_AND_RETURN_FALSE(device.has_value());
+ partition.target_path = device->rw_device_path;
+ partition.postinstall_mount_device = device->mountable_device_path;
} else {
partition.target_path.clear();
}
diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h
index ee1a72b..7068f6c 100644
--- a/payload_consumer/install_plan.h
+++ b/payload_consumer/install_plan.h
@@ -98,9 +98,17 @@
uint64_t source_size{0};
brillo::Blob source_hash;
+ // |target_path| is intended to be a path to block device, which you can
+ // open with |open| syscall and perform regular unix style read/write.
+ // For VABC, this will be empty. As you can't read/write VABC devices with
+ // regular syscall.
std::string target_path;
+ // |mountable_target_device| is intended to be a path to block device which
+ // can be used for mounting this block device's underlying filesystem.
+ std::string postinstall_mount_device;
uint64_t target_size{0};
brillo::Blob target_hash;
+
uint32_t block_size{0};
// Whether we should run the postinstall script from this partition and the
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index d51241f..bd49639 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -50,7 +50,6 @@
namespace chromeos_update_engine {
-using brillo::MessageLoop;
using std::string;
using std::vector;
@@ -127,7 +126,7 @@
const InstallPlan::Partition& partition =
install_plan_.partitions[current_partition_];
- const string mountable_device = partition.target_path;
+ const string mountable_device = partition.postinstall_mount_device;
if (mountable_device.empty()) {
LOG(ERROR) << "Cannot make mountable device from " << partition.target_path;
return CompletePostinstall(ErrorCode::kPostinstallRunnerError);
diff --git a/payload_consumer/postinstall_runner_action_unittest.cc b/payload_consumer/postinstall_runner_action_unittest.cc
index cce86e9..9b330d9 100644
--- a/payload_consumer/postinstall_runner_action_unittest.cc
+++ b/payload_consumer/postinstall_runner_action_unittest.cc
@@ -195,6 +195,7 @@
InstallPlan::Partition part;
part.name = "part";
part.target_path = device_path;
+ part.postinstall_mount_device = device_path;
part.run_postinstall = true;
part.postinstall_path = postinstall_program;
InstallPlan install_plan;
@@ -356,6 +357,7 @@
InstallPlan::Partition part;
part.name = "part";
part.target_path = "/dev/null";
+ part.postinstall_mount_device = "/dev/null";
part.run_postinstall = true;
part.postinstall_path = kPostinstallDefaultScript;
part.postinstall_optional = true;