libsnapshot: op_count_max default to max blocks

In the case that op_count_max is read in as zero, we should use the
upper bound of max blocks as the estimation. One case in which this
error can happen is if a v2 cow estimator is used, we should still be
able to run an OTA if we upper bound our ops buffer size estimation.

Test: th
Change-Id: I97ca66368d6631bf43c8911ed66f99c9e8096e2d
This commit is contained in:
Daniel Zheng 2024-01-04 14:12:57 -08:00
parent 2c82c81f12
commit 2aed5a5e4c
3 changed files with 21 additions and 8 deletions

View file

@ -72,6 +72,7 @@ TEST_F(CowTestV3, CowHeaderV2Test) {
TEST_F(CowTestV3, Header) {
CowOptions options;
options.op_count_max = 15;
auto writer = CreateCowWriter(3, options, GetCowFd());
ASSERT_TRUE(writer->Finalize());

View file

@ -129,6 +129,18 @@ bool CowWriterV3::ParseOptions() {
header_.compression_algorithm = *algorithm;
header_.op_count_max = options_.op_count_max;
if (!IsEstimating() && header_.op_count_max == 0) {
if (!options_.max_blocks.has_value()) {
LOG(ERROR) << "can't size op buffer size since op_count_max is 0 and max_blocks is not "
"set.";
return false;
}
LOG(INFO) << "op count max is read in as 0. Setting to "
"num blocks in partition "
<< options_.max_blocks.value();
header_.op_count_max = options_.max_blocks.value();
}
if (parts.size() > 1) {
if (!android::base::ParseUint(parts[1], &compression_.compression_level)) {
LOG(ERROR) << "failed to parse compression level invalid type: " << parts[1];

View file

@ -1142,8 +1142,8 @@ auto SnapshotManager::CheckMergeState(const std::function<bool()>& before_cancel
return result;
}
auto SnapshotManager::CheckMergeState(LockedFile* lock, const std::function<bool()>& before_cancel)
-> MergeResult {
auto SnapshotManager::CheckMergeState(LockedFile* lock,
const std::function<bool()>& before_cancel) -> MergeResult {
SnapshotUpdateStatus update_status = ReadSnapshotUpdateStatus(lock);
switch (update_status.state()) {
case UpdateState::None:
@ -1218,8 +1218,8 @@ auto SnapshotManager::CheckMergeState(LockedFile* lock, const std::function<bool
wrong_phase = true;
break;
default:
LOG(ERROR) << "Unknown merge status for \"" << snapshot << "\": "
<< "\"" << result.state << "\"";
LOG(ERROR) << "Unknown merge status for \"" << snapshot << "\": " << "\""
<< result.state << "\"";
if (failure_code == MergeFailureCode::Ok) {
failure_code = MergeFailureCode::UnexpectedMergeState;
}
@ -2797,8 +2797,8 @@ bool SnapshotManager::UnmapAllSnapshots(LockedFile* lock) {
return true;
}
auto SnapshotManager::OpenFile(const std::string& file, int lock_flags)
-> std::unique_ptr<LockedFile> {
auto SnapshotManager::OpenFile(const std::string& file,
int lock_flags) -> std::unique_ptr<LockedFile> {
unique_fd fd(open(file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
if (fd < 0) {
PLOG(ERROR) << "Open failed: " << file;
@ -3558,6 +3558,7 @@ Return SnapshotManager::InitializeUpdateSnapshots(
options.compression = it->second.compression_algorithm();
if (cow_version >= 3) {
options.op_count_max = it->second.estimated_ops_buffer_size();
options.max_blocks = {it->second.device_size() / options.block_size};
}
auto writer = CreateCowWriter(cow_version, options, std::move(fd));
@ -4343,8 +4344,7 @@ bool SnapshotManager::DeleteDeviceIfExists(const std::string& name,
}
}
LOG(ERROR) << "Device-mapper device " << name << "(" << full_path << ")"
<< " still in use."
LOG(ERROR) << "Device-mapper device " << name << "(" << full_path << ")" << " still in use."
<< " Probably a file descriptor was leaked or held open, or a loop device is"
<< " attached.";
return false;