Merge "Move tombstone_proto_to_text out of libdebuggerd." into main
diff --git a/debuggerd/libdebuggerd/scudo.cpp b/debuggerd/libdebuggerd/scudo.cpp
index 837f406..ea8dff4 100644
--- a/debuggerd/libdebuggerd/scudo.cpp
+++ b/debuggerd/libdebuggerd/scudo.cpp
@@ -78,7 +78,8 @@
}
__scudo_get_error_info(&error_info_, process_info.maybe_tagged_fault_address, stack_depot.get(),
- region_info.get(), ring_buffer.get(), memory.get(), memory_tags.get(),
+ __scudo_get_stack_depot_size(), region_info.get(), ring_buffer.get(),
+ process_info.scudo_ring_buffer_size, memory.get(), memory_tags.get(),
memory_begin, memory_end - memory_begin);
}
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index 25c5a6e..0947ff9 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -224,7 +224,7 @@
auto remove_if_callback = [&](const auto& task) -> bool {
if (auto flash_task = task->AsFlashTask()) {
return helper->WillFlash(flash_task->GetPartitionAndSlot());
- } else if (auto update_super_task = task->AsUpdateSuperTask()) {
+ } else if (task->AsUpdateSuperTask()) {
return true;
} else if (auto reboot_task = task->AsRebootTask()) {
if (reboot_task->GetTarget() == "fastboot") {
diff --git a/fastboot/task_test.cpp b/fastboot/task_test.cpp
index 9cde1a8..81154c6 100644
--- a/fastboot/task_test.cpp
+++ b/fastboot/task_test.cpp
@@ -354,7 +354,7 @@
const std::vector<std::unique_ptr<Task>>& tasks) {
bool contains_optimized_task = false;
for (auto& task : tasks) {
- if (auto optimized_task = task->AsOptimizedFlashSuperTask()) {
+ if (task->AsOptimizedFlashSuperTask()) {
contains_optimized_task = true;
}
if (auto flash_task = task->AsFlashTask()) {
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index 324f50a..edecd7c 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -25,7 +25,7 @@
{
"name": "vab_legacy_tests"
},
- // TODO: b/279009697
+ // TODO(b/279009697):
//{"name": "vabc_legacy_tests"},
{
"name": "cow_api_test"
@@ -47,7 +47,7 @@
{
"name": "vab_legacy_tests"
},
- // TODO: b/279009697
+ // TODO(b/279009697):
//{"name": "vabc_legacy_tests"}
{
"name": "snapuserd_test"
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 35c8c63..a94a274 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1244,17 +1244,27 @@
};
std::string fs_mgr_find_bow_device(const std::string& block_device) {
- if (block_device.substr(0, 5) != "/dev/") {
- LOG(ERROR) << "Expected block device, got " << block_device;
- return std::string();
+ // handle symlink such as "/dev/block/mapper/userdata"
+ std::string real_path;
+ if (!android::base::Realpath(block_device, &real_path)) {
+ real_path = block_device;
}
- std::string sys_dir = std::string("/sys/") + block_device.substr(5);
-
+ struct stat st;
+ if (stat(real_path.c_str(), &st) < 0) {
+ PLOG(ERROR) << "stat failed: " << real_path;
+ return std::string();
+ }
+ if (!S_ISBLK(st.st_mode)) {
+ PLOG(ERROR) << real_path << " is not block device";
+ return std::string();
+ }
+ std::string sys_dir = android::base::StringPrintf("/sys/dev/block/%u:%u", major(st.st_rdev),
+ minor(st.st_rdev));
for (;;) {
std::string name;
if (!android::base::ReadFileToString(sys_dir + "/dm/name", &name)) {
- PLOG(ERROR) << block_device << " is not dm device";
+ PLOG(ERROR) << real_path << " is not dm device";
return std::string();
}
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
index 717ad2d..6b34152 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
@@ -226,6 +226,9 @@
uint64_t source_info_;
constexpr uint64_t source() const { return source_info_ & kCowOpSourceInfoDataMask; }
constexpr void set_source(uint64_t source) {
+ // Clear the first 48 bit first
+ source_info_ &= ~kCowOpSourceInfoDataMask;
+ // Set the actual source field
source_info_ |= source & kCowOpSourceInfoDataMask;
}
constexpr CowOperationType type() const {
@@ -234,6 +237,9 @@
return static_cast<CowOperationType>(type);
}
constexpr void set_type(CowOperationType type) {
+ // Clear the top 4 bits first
+ source_info_ &= ((1ULL << kCowOpSourceInfoTypeBit) - 1);
+ // set the actual type bits
source_info_ |= (static_cast<uint64_t>(type) & kCowOpSourceInfoTypeMask)
<< kCowOpSourceInfoTypeBit;
}
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp
index ea34c27..27accdc 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp
@@ -15,17 +15,15 @@
#include <sys/stat.h>
#include <cstdio>
-#include <iostream>
#include <memory>
-#include <string_view>
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
+#include <libsnapshot/cow_format.h>
#include <libsnapshot/cow_reader.h>
#include <libsnapshot/cow_writer.h>
-#include "cow_decompress.h"
-#include "libsnapshot/cow_format.h"
#include "writer_v2.h"
#include "writer_v3.h"
@@ -621,5 +619,57 @@
ASSERT_EQ(expected_block, 0);
ASSERT_TRUE(iter->AtEnd());
}
+
+TEST_F(CowTestV3, SetSourceManyTimes) {
+ CowOperationV3 op{};
+ op.set_source(1);
+ ASSERT_EQ(op.source(), 1);
+ op.set_source(2);
+ ASSERT_EQ(op.source(), 2);
+ op.set_source(4);
+ ASSERT_EQ(op.source(), 4);
+ op.set_source(8);
+ ASSERT_EQ(op.source(), 8);
+}
+
+TEST_F(CowTestV3, SetTypeManyTimes) {
+ CowOperationV3 op{};
+ op.set_type(kCowCopyOp);
+ ASSERT_EQ(op.type(), kCowCopyOp);
+ op.set_type(kCowReplaceOp);
+ ASSERT_EQ(op.type(), kCowReplaceOp);
+ op.set_type(kCowZeroOp);
+ ASSERT_EQ(op.type(), kCowZeroOp);
+ op.set_type(kCowXorOp);
+ ASSERT_EQ(op.type(), kCowXorOp);
+}
+
+TEST_F(CowTestV3, SetTypeSourceInverleave) {
+ CowOperationV3 op{};
+ op.set_type(kCowCopyOp);
+ ASSERT_EQ(op.type(), kCowCopyOp);
+ op.set_source(0x010203040506);
+ ASSERT_EQ(op.source(), 0x010203040506);
+ ASSERT_EQ(op.type(), kCowCopyOp);
+ op.set_type(kCowReplaceOp);
+ ASSERT_EQ(op.source(), 0x010203040506);
+ ASSERT_EQ(op.type(), kCowReplaceOp);
+}
+
+TEST_F(CowTestV3, CowSizeEstimate) {
+ CowOptions options{};
+ options.compression = "none";
+ auto estimator = android::snapshot::CreateCowEstimator(3, options);
+ ASSERT_TRUE(estimator->AddZeroBlocks(0, 1024 * 1024));
+ const auto cow_size = estimator->GetCowSize();
+ options.op_count_max = 1024 * 1024;
+ options.max_blocks = 1024 * 1024;
+ CowWriterV3 writer(options, GetCowFd());
+ ASSERT_TRUE(writer.Initialize());
+ ASSERT_TRUE(writer.AddZeroBlocks(0, 1024 * 1024));
+
+ ASSERT_LE(writer.GetCowSize(), cow_size);
+}
+
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp
index 5bdc5fd..07f6f00 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp
@@ -327,7 +327,12 @@
bool CowWriterV3::WriteOperation(const CowOperationV3& op, const void* data, size_t size) {
if (IsEstimating()) {
header_.op_count++;
- header_.op_count_max++;
+ if (header_.op_count > header_.op_count_max) {
+ // If we increment op_count_max, the offset of data section would
+ // change. So need to update |next_data_pos_|
+ next_data_pos_ += (header_.op_count - header_.op_count_max) * sizeof(CowOperationV3);
+ header_.op_count_max = header_.op_count;
+ }
next_data_pos_ += op.data_length;
return true;
}