Merge "init_first_stage: Remove unused srcs & static libs"
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 9ca0eba..0ff047f 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -180,7 +180,6 @@
"libdebuggerd/backtrace.cpp",
"libdebuggerd/gwp_asan.cpp",
"libdebuggerd/open_files_list.cpp",
- "libdebuggerd/scudo.cpp",
"libdebuggerd/tombstone.cpp",
"libdebuggerd/tombstone_proto.cpp",
"libdebuggerd/tombstone_proto_to_text.cpp",
@@ -193,9 +192,6 @@
include_dirs: [
// Needed for private/bionic_fdsan.h
"bionic/libc",
-
- // Needed for scudo/interface.h
- "external/scudo/standalone/include",
],
header_libs: [
"bionic_libc_platform_headers",
@@ -217,7 +213,6 @@
whole_static_libs: [
"libasync_safe",
"gwp_asan_crash_handler",
- "libscudo",
"libtombstone_proto",
"libprocinfo",
"libprotobuf-cpp-lite",
@@ -246,6 +241,13 @@
debuggable: {
cflags: ["-DROOT_POSSIBLE"],
},
+
+ malloc_not_svelte: {
+ cflags: ["-DUSE_SCUDO"],
+ whole_static_libs: ["libscudo"],
+ srcs: ["libdebuggerd/scudo.cpp"],
+ header_libs: ["scudo_headers"],
+ },
},
}
@@ -316,10 +318,6 @@
"gwp_asan_headers",
],
- include_dirs: [
- "external/scudo/standalone/include",
- ],
-
local_include_dirs: [
"libdebuggerd",
],
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index ff03bcd..ee64c3d 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -57,10 +57,13 @@
#include "libdebuggerd/backtrace.h"
#include "libdebuggerd/gwp_asan.h"
#include "libdebuggerd/open_files_list.h"
-#include "libdebuggerd/scudo.h"
#include "libdebuggerd/utility.h"
#include "util.h"
+#if defined(USE_SCUDO)
+#include "libdebuggerd/scudo.h"
+#endif
+
#include "gwp_asan/common.h"
#include "gwp_asan/crash_handler.h"
@@ -115,8 +118,26 @@
return "";
}
-static void dump_probable_cause(log_t* log, const siginfo_t* si, unwindstack::Maps* maps,
- unwindstack::Regs* regs) {
+static void dump_probable_cause(log_t* log, unwindstack::Unwinder* unwinder,
+ const ProcessInfo& process_info, const ThreadInfo& main_thread) {
+#if defined(USE_SCUDO)
+ ScudoCrashData scudo_crash_data(unwinder->GetProcessMemory().get(), process_info);
+ if (scudo_crash_data.CrashIsMine()) {
+ scudo_crash_data.DumpCause(log, unwinder);
+ return;
+ }
+#endif
+
+ GwpAsanCrashData gwp_asan_crash_data(unwinder->GetProcessMemory().get(), process_info,
+ main_thread);
+ if (gwp_asan_crash_data.CrashIsMine()) {
+ gwp_asan_crash_data.DumpCause(log);
+ return;
+ }
+
+ unwindstack::Maps* maps = unwinder->GetMaps();
+ unwindstack::Regs* regs = main_thread.registers.get();
+ const siginfo_t* si = main_thread.siginfo;
std::string cause;
if (si->si_signo == SIGSEGV && si->si_code == SEGV_MAPERR) {
if (si->si_addr < reinterpret_cast<void*>(4096)) {
@@ -395,22 +416,9 @@
dump_signal_info(log, thread_info, process_info, unwinder->GetProcessMemory().get());
}
- std::unique_ptr<GwpAsanCrashData> gwp_asan_crash_data;
- std::unique_ptr<ScudoCrashData> scudo_crash_data;
if (primary_thread) {
- gwp_asan_crash_data = std::make_unique<GwpAsanCrashData>(unwinder->GetProcessMemory().get(),
- process_info, thread_info);
- scudo_crash_data =
- std::make_unique<ScudoCrashData>(unwinder->GetProcessMemory().get(), process_info);
- }
+ dump_probable_cause(log, unwinder, process_info, thread_info);
- if (primary_thread && gwp_asan_crash_data->CrashIsMine()) {
- gwp_asan_crash_data->DumpCause(log);
- } else if (thread_info.siginfo && !(primary_thread && scudo_crash_data->CrashIsMine())) {
- dump_probable_cause(log, thread_info.siginfo, unwinder->GetMaps(), thread_info.registers.get());
- }
-
- if (primary_thread) {
dump_abort_message(log, unwinder->GetProcessMemory().get(), process_info.abort_msg_address);
}
@@ -432,16 +440,17 @@
}
if (primary_thread) {
- if (gwp_asan_crash_data->HasDeallocationTrace()) {
- gwp_asan_crash_data->DumpDeallocationTrace(log, unwinder);
+ GwpAsanCrashData gwp_asan_crash_data(unwinder->GetProcessMemory().get(), process_info,
+ thread_info);
+
+ if (gwp_asan_crash_data.HasDeallocationTrace()) {
+ gwp_asan_crash_data.DumpDeallocationTrace(log, unwinder);
}
- if (gwp_asan_crash_data->HasAllocationTrace()) {
- gwp_asan_crash_data->DumpAllocationTrace(log, unwinder);
+ if (gwp_asan_crash_data.HasAllocationTrace()) {
+ gwp_asan_crash_data.DumpAllocationTrace(log, unwinder);
}
- scudo_crash_data->DumpCause(log, unwinder);
-
unwindstack::Maps* maps = unwinder->GetMaps();
dump_memory_and_code(log, maps, unwinder->GetProcessMemory().get(),
thread_info.registers.get());
diff --git a/debuggerd/libdebuggerd/tombstone_proto.cpp b/debuggerd/libdebuggerd/tombstone_proto.cpp
index 99f636e..e8e2ae2 100644
--- a/debuggerd/libdebuggerd/tombstone_proto.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto.cpp
@@ -18,7 +18,9 @@
#include "libdebuggerd/tombstone.h"
#include "libdebuggerd/gwp_asan.h"
+#if defined(USE_SCUDO)
#include "libdebuggerd/scudo.h"
+#endif
#include <errno.h>
#include <fcntl.h>
@@ -186,11 +188,13 @@
static void dump_probable_cause(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
const ProcessInfo& process_info, const ThreadInfo& main_thread) {
+#if defined(USE_SCUDO)
ScudoCrashData scudo_crash_data(unwinder->GetProcessMemory().get(), process_info);
if (scudo_crash_data.CrashIsMine()) {
scudo_crash_data.AddCauseProtos(tombstone, unwinder);
return;
}
+#endif
GwpAsanCrashData gwp_asan_crash_data(unwinder->GetProcessMemory().get(), process_info,
main_thread);
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index 428a7f4..2bb9035 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -86,7 +86,9 @@
name: "vts_libdm_test",
defaults: ["libdm_test_defaults"],
test_suites: ["vts"],
- test_min_api_level: 29,
+ test_options: {
+ min_shipping_api_level: 29,
+ },
}
cc_fuzz {
diff --git a/fs_mgr/libfiemap/Android.bp b/fs_mgr/libfiemap/Android.bp
index d16b8d6..5deba65 100644
--- a/fs_mgr/libfiemap/Android.bp
+++ b/fs_mgr/libfiemap/Android.bp
@@ -90,7 +90,9 @@
test_suites: ["vts", "device-tests"],
auto_gen_config: true,
- test_min_api_level: 29,
+ test_options: {
+ min_shipping_api_level: 29,
+ },
require_root: true,
}
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index fc2d8a1..4b81c2c 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -105,7 +105,9 @@
defaults: ["liblp_test_defaults"],
test_suites: ["vts"],
auto_gen_config: true,
- test_min_api_level: 29,
+ test_options: {
+ min_shipping_api_level: 29,
+ },
require_root: true,
}
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index df00f45..5ab2ce2 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -251,7 +251,9 @@
"vts",
"device-tests"
],
- test_min_api_level: 29,
+ test_options: {
+ min_shipping_api_level: 29,
+ },
auto_gen_config: true,
require_root: true,
}
@@ -407,7 +409,9 @@
test_suites: [
"device-tests"
],
- test_min_api_level: 30,
+ test_options: {
+ min_shipping_api_level: 30,
+ },
auto_gen_config: true,
require_root: false,
host_supported: true,
diff --git a/fs_mgr/libsnapshot/cow_api_test.cpp b/fs_mgr/libsnapshot/cow_api_test.cpp
index 6066309..ba4044f 100644
--- a/fs_mgr/libsnapshot/cow_api_test.cpp
+++ b/fs_mgr/libsnapshot/cow_api_test.cpp
@@ -1171,18 +1171,18 @@
ASSERT_TRUE(writer.Initialize(cow_->fd));
ASSERT_TRUE(writer.AddSequenceData(6, sequence));
- ASSERT_TRUE(writer.AddCopy(6, 3));
+ ASSERT_TRUE(writer.AddCopy(6, 13));
ASSERT_TRUE(writer.AddZeroBlocks(12, 1));
ASSERT_TRUE(writer.AddZeroBlocks(8, 1));
ASSERT_TRUE(writer.AddZeroBlocks(11, 1));
- ASSERT_TRUE(writer.AddCopy(3, 5));
- ASSERT_TRUE(writer.AddCopy(2, 1));
+ ASSERT_TRUE(writer.AddCopy(3, 15));
+ ASSERT_TRUE(writer.AddCopy(2, 11));
ASSERT_TRUE(writer.AddZeroBlocks(4, 1));
ASSERT_TRUE(writer.AddZeroBlocks(9, 1));
- ASSERT_TRUE(writer.AddCopy(5, 6));
+ ASSERT_TRUE(writer.AddCopy(5, 16));
ASSERT_TRUE(writer.AddZeroBlocks(1, 1));
- ASSERT_TRUE(writer.AddCopy(10, 2));
- ASSERT_TRUE(writer.AddCopy(7, 4));
+ ASSERT_TRUE(writer.AddCopy(10, 12));
+ ASSERT_TRUE(writer.AddCopy(7, 14));
ASSERT_TRUE(writer.Finalize());
// New block in cow order is 6, 12, 8, 11, 3, 2, 4, 9, 5, 1, 10, 7
@@ -1219,12 +1219,12 @@
ASSERT_TRUE(writer.Initialize(cow_->fd));
- ASSERT_TRUE(writer.AddCopy(2, 1));
- ASSERT_TRUE(writer.AddCopy(10, 2));
- ASSERT_TRUE(writer.AddCopy(6, 3));
- ASSERT_TRUE(writer.AddCopy(7, 4));
- ASSERT_TRUE(writer.AddCopy(3, 5));
- ASSERT_TRUE(writer.AddCopy(5, 6));
+ ASSERT_TRUE(writer.AddCopy(2, 11));
+ ASSERT_TRUE(writer.AddCopy(10, 12));
+ ASSERT_TRUE(writer.AddCopy(6, 13));
+ ASSERT_TRUE(writer.AddCopy(7, 14));
+ ASSERT_TRUE(writer.AddCopy(3, 15));
+ ASSERT_TRUE(writer.AddCopy(5, 16));
ASSERT_TRUE(writer.AddZeroBlocks(12, 1));
ASSERT_TRUE(writer.AddZeroBlocks(8, 1));
ASSERT_TRUE(writer.AddZeroBlocks(11, 1));
@@ -1260,6 +1260,39 @@
ASSERT_TRUE(iter->Done());
}
+TEST_F(CowTest, InvalidMergeOrderTest) {
+ CowOptions options;
+ options.cluster_ops = 5;
+ options.num_merge_ops = 1;
+ std::string data = "This is some data, believe it";
+ data.resize(options.block_size, '\0');
+ auto writer = std::make_unique<CowWriter>(options);
+ CowReader reader;
+
+ ASSERT_TRUE(writer->Initialize(cow_->fd));
+
+ ASSERT_TRUE(writer->AddCopy(3, 2));
+ ASSERT_TRUE(writer->AddCopy(2, 1));
+ ASSERT_TRUE(writer->AddLabel(1));
+ ASSERT_TRUE(writer->Finalize());
+ ASSERT_TRUE(reader.Parse(cow_->fd));
+ ASSERT_TRUE(reader.VerifyMergeOps());
+
+ ASSERT_TRUE(writer->InitializeAppend(cow_->fd, 1));
+ ASSERT_TRUE(writer->AddCopy(4, 2));
+ ASSERT_TRUE(writer->Finalize());
+ ASSERT_TRUE(reader.Parse(cow_->fd));
+ ASSERT_FALSE(reader.VerifyMergeOps());
+
+ writer = std::make_unique<CowWriter>(options);
+ ASSERT_TRUE(writer->Initialize(cow_->fd));
+ ASSERT_TRUE(writer->AddCopy(2, 1));
+ ASSERT_TRUE(writer->AddXorBlocks(3, &data, data.size(), 1, 1));
+ ASSERT_TRUE(writer->Finalize());
+ ASSERT_TRUE(reader.Parse(cow_->fd));
+ ASSERT_FALSE(reader.VerifyMergeOps());
+}
+
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/cow_format.cpp b/fs_mgr/libsnapshot/cow_format.cpp
index 8e6bec7..94c4109 100644
--- a/fs_mgr/libsnapshot/cow_format.cpp
+++ b/fs_mgr/libsnapshot/cow_format.cpp
@@ -56,7 +56,10 @@
os << (int)op.compression << "?, ";
os << "data_length:" << op.data_length << ",\t";
os << "new_block:" << op.new_block << ",\t";
- os << "source:" << op.source << ")";
+ os << "source:" << op.source;
+ if (op.type == kCowXorOp)
+ os << " (block:" << op.source / BLOCK_SZ << " offset:" << op.source % BLOCK_SZ << ")";
+ os << ")";
return os;
}
diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp
index 773d978..e8f0153 100644
--- a/fs_mgr/libsnapshot/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/cow_reader.cpp
@@ -58,6 +58,7 @@
cow->last_label_ = last_label_;
cow->ops_ = ops_;
cow->merge_op_blocks_ = merge_op_blocks_;
+ cow->merge_op_start_ = merge_op_start_;
cow->block_map_ = block_map_;
cow->num_total_data_ops_ = num_total_data_ops_;
cow->num_ordered_ops_to_merge_ = num_ordered_ops_to_merge_;
@@ -468,8 +469,7 @@
num_total_data_ops_ = merge_op_blocks->size();
if (header_.num_merge_ops > 0) {
- merge_op_blocks->erase(merge_op_blocks->begin(),
- merge_op_blocks->begin() + header_.num_merge_ops);
+ merge_op_start_ = header_.num_merge_ops;
}
block_map_ = block_map;
@@ -477,6 +477,44 @@
return true;
}
+bool CowReader::VerifyMergeOps() {
+ auto itr = GetMergeOpIter(true);
+ std::unordered_map<uint64_t, CowOperation> overwritten_blocks;
+ while (!itr->Done()) {
+ CowOperation op = itr->Get();
+ uint64_t block;
+ bool offset;
+ if (op.type == kCowCopyOp) {
+ block = op.source;
+ offset = false;
+ } else if (op.type == kCowXorOp) {
+ block = op.source / BLOCK_SZ;
+ offset = (op.source % BLOCK_SZ) != 0;
+ } else {
+ itr->Next();
+ continue;
+ }
+
+ CowOperation* overwrite = nullptr;
+ if (overwritten_blocks.count(block)) {
+ overwrite = &overwritten_blocks[block];
+ LOG(ERROR) << "Invalid Sequence! Block needed for op:\n"
+ << op << "\noverwritten by previously merged op:\n"
+ << *overwrite;
+ }
+ if (offset && overwritten_blocks.count(block + 1)) {
+ overwrite = &overwritten_blocks[block + 1];
+ LOG(ERROR) << "Invalid Sequence! Block needed for op:\n"
+ << op << "\noverwritten by previously merged op:\n"
+ << *overwrite;
+ }
+ if (overwrite != nullptr) return false;
+ overwritten_blocks[op.new_block] = op;
+ itr->Next();
+ }
+ return true;
+}
+
bool CowReader::GetHeader(CowHeader* header) {
*header = header_;
return true;
@@ -530,7 +568,8 @@
public:
explicit CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
std::shared_ptr<std::vector<uint32_t>> merge_op_blocks,
- std::shared_ptr<std::unordered_map<uint32_t, int>> map);
+ std::shared_ptr<std::unordered_map<uint32_t, int>> map,
+ uint64_t start);
bool Done() override;
const CowOperation& Get() override;
@@ -541,20 +580,67 @@
std::shared_ptr<std::vector<uint32_t>> merge_op_blocks_;
std::shared_ptr<std::unordered_map<uint32_t, int>> map_;
std::vector<uint32_t>::reverse_iterator block_riter_;
+ uint64_t start_;
};
-CowRevMergeOpIter::CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
- std::shared_ptr<std::vector<uint32_t>> merge_op_blocks,
- std::shared_ptr<std::unordered_map<uint32_t, int>> map) {
+class CowMergeOpIter final : public ICowOpIter {
+ public:
+ explicit CowMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
+ std::shared_ptr<std::vector<uint32_t>> merge_op_blocks,
+ std::shared_ptr<std::unordered_map<uint32_t, int>> map, uint64_t start);
+
+ bool Done() override;
+ const CowOperation& Get() override;
+ void Next() override;
+
+ private:
+ std::shared_ptr<std::vector<CowOperation>> ops_;
+ std::shared_ptr<std::vector<uint32_t>> merge_op_blocks_;
+ std::shared_ptr<std::unordered_map<uint32_t, int>> map_;
+ std::vector<uint32_t>::iterator block_iter_;
+ uint64_t start_;
+};
+
+CowMergeOpIter::CowMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
+ std::shared_ptr<std::vector<uint32_t>> merge_op_blocks,
+ std::shared_ptr<std::unordered_map<uint32_t, int>> map,
+ uint64_t start) {
ops_ = ops;
merge_op_blocks_ = merge_op_blocks;
map_ = map;
+ start_ = start;
+
+ block_iter_ = merge_op_blocks->begin() + start;
+}
+
+bool CowMergeOpIter::Done() {
+ return block_iter_ == merge_op_blocks_->end();
+}
+
+void CowMergeOpIter::Next() {
+ CHECK(!Done());
+ block_iter_++;
+}
+
+const CowOperation& CowMergeOpIter::Get() {
+ CHECK(!Done());
+ return ops_->data()[map_->at(*block_iter_)];
+}
+
+CowRevMergeOpIter::CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
+ std::shared_ptr<std::vector<uint32_t>> merge_op_blocks,
+ std::shared_ptr<std::unordered_map<uint32_t, int>> map,
+ uint64_t start) {
+ ops_ = ops;
+ merge_op_blocks_ = merge_op_blocks;
+ map_ = map;
+ start_ = start;
block_riter_ = merge_op_blocks->rbegin();
}
bool CowRevMergeOpIter::Done() {
- return block_riter_ == merge_op_blocks_->rend();
+ return block_riter_ == merge_op_blocks_->rend() - start_;
}
void CowRevMergeOpIter::Next() {
@@ -571,8 +657,14 @@
return std::make_unique<CowOpIter>(ops_);
}
-std::unique_ptr<ICowOpIter> CowReader::GetRevMergeOpIter() {
- return std::make_unique<CowRevMergeOpIter>(ops_, merge_op_blocks_, block_map_);
+std::unique_ptr<ICowOpIter> CowReader::GetRevMergeOpIter(bool ignore_progress) {
+ return std::make_unique<CowRevMergeOpIter>(ops_, merge_op_blocks_, block_map_,
+ ignore_progress ? 0 : merge_op_start_);
+}
+
+std::unique_ptr<ICowOpIter> CowReader::GetMergeOpIter(bool ignore_progress) {
+ return std::make_unique<CowMergeOpIter>(ops_, merge_op_blocks_, block_map_,
+ ignore_progress ? 0 : merge_op_start_);
}
bool CowReader::GetRawBytes(uint64_t offset, void* buffer, size_t len, size_t* read) {
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 0786e82..143f73c 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -68,6 +68,7 @@
// Return the file footer.
virtual bool GetFooter(CowFooter* footer) = 0;
+ virtual bool VerifyMergeOps() = 0;
// Return the last valid label
virtual bool GetLastLabel(uint64_t* label) = 0;
@@ -75,8 +76,11 @@
// Return an iterator for retrieving CowOperation entries.
virtual std::unique_ptr<ICowOpIter> GetOpIter() = 0;
+ // Return an iterator for retrieving CowOperation entries in reverse merge order
+ virtual std::unique_ptr<ICowOpIter> GetRevMergeOpIter(bool ignore_progress) = 0;
+
// Return an iterator for retrieving CowOperation entries in merge order
- virtual std::unique_ptr<ICowOpIter> GetRevMergeOpIter() = 0;
+ virtual std::unique_ptr<ICowOpIter> GetMergeOpIter(bool ignore_progress) = 0;
// Get decoded bytes from the data section, handling any decompression.
// All retrieved data is passed to the sink.
@@ -98,7 +102,7 @@
virtual void Next() = 0;
};
-class CowReader : public ICowReader {
+class CowReader final : public ICowReader {
public:
CowReader();
~CowReader() { owned_fd_ = {}; }
@@ -109,6 +113,7 @@
bool Parse(android::base::borrowed_fd fd, std::optional<uint64_t> label = {});
bool InitForMerge(android::base::unique_fd&& fd);
+ bool VerifyMergeOps() override;
bool GetHeader(CowHeader* header) override;
bool GetFooter(CowFooter* footer) override;
@@ -120,7 +125,8 @@
// whose lifetime depends on the CowOpIter object; the return
// value of these will never be null.
std::unique_ptr<ICowOpIter> GetOpIter() override;
- std::unique_ptr<ICowOpIter> GetRevMergeOpIter() override;
+ std::unique_ptr<ICowOpIter> GetRevMergeOpIter(bool ignore_progress = false) override;
+ std::unique_ptr<ICowOpIter> GetMergeOpIter(bool ignore_progress = false) override;
bool ReadData(const CowOperation& op, IByteSink* sink) override;
@@ -152,6 +158,7 @@
std::optional<uint64_t> last_label_;
std::shared_ptr<std::vector<CowOperation>> ops_;
std::shared_ptr<std::vector<uint32_t>> merge_op_blocks_;
+ uint64_t merge_op_start_;
std::shared_ptr<std::unordered_map<uint32_t, int>> block_map_;
uint64_t num_total_data_ops_;
uint64_t num_ordered_ops_to_merge_;
diff --git a/fs_mgr/libsnapshot/inspect_cow.cpp b/fs_mgr/libsnapshot/inspect_cow.cpp
index 3c0ba16..548ba00 100644
--- a/fs_mgr/libsnapshot/inspect_cow.cpp
+++ b/fs_mgr/libsnapshot/inspect_cow.cpp
@@ -44,10 +44,13 @@
LOG(ERROR) << "\t -b Show data for failed decompress";
LOG(ERROR) << "\t -l Show ops";
LOG(ERROR) << "\t -m Show ops in reverse merge order";
- LOG(ERROR) << "\t -o Shows sequence op block order\n";
+ LOG(ERROR) << "\t -n Show ops in merge order";
+ LOG(ERROR) << "\t -a Include merged ops in any merge order listing";
+ LOG(ERROR) << "\t -o Shows sequence op block order";
+ LOG(ERROR) << "\t -v Verifies merge order has no conflicts\n";
}
-enum OpIter { Normal, RevMerge };
+enum OpIter { Normal, RevMerge, Merge };
struct Options {
bool silent;
@@ -55,7 +58,9 @@
bool show_ops;
bool show_bad;
bool show_seq;
+ bool verify_sequence;
OpIter iter_type;
+ bool include_merged;
};
// Sink that always appends to the end of a string.
@@ -132,11 +137,21 @@
}
}
+ if (opt.verify_sequence) {
+ if (reader.VerifyMergeOps()) {
+ std::cout << "\nMerge sequence is consistent.\n";
+ } else {
+ std::cout << "\nMerge sequence is inconsistent!\n";
+ }
+ }
+
std::unique_ptr<ICowOpIter> iter;
if (opt.iter_type == Normal) {
iter = reader.GetOpIter();
} else if (opt.iter_type == RevMerge) {
- iter = reader.GetRevMergeOpIter();
+ iter = reader.GetRevMergeOpIter(opt.include_merged);
+ } else if (opt.iter_type == Merge) {
+ iter = reader.GetMergeOpIter(opt.include_merged);
}
StringSink sink;
bool success = true;
@@ -188,7 +203,9 @@
opt.decompress = false;
opt.show_bad = false;
opt.iter_type = android::snapshot::Normal;
- while ((ch = getopt(argc, argv, "sdbmol")) != -1) {
+ opt.verify_sequence = false;
+ opt.include_merged = false;
+ while ((ch = getopt(argc, argv, "sdbmnolva")) != -1) {
switch (ch) {
case 's':
opt.silent = true;
@@ -202,12 +219,21 @@
case 'm':
opt.iter_type = android::snapshot::RevMerge;
break;
+ case 'n':
+ opt.iter_type = android::snapshot::Merge;
+ break;
case 'o':
opt.show_seq = true;
break;
case 'l':
opt.show_ops = true;
break;
+ case 'v':
+ opt.verify_sequence = true;
+ break;
+ case 'a':
+ opt.include_merged = true;
+ break;
default:
android::snapshot::usage();
}
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index 47268d4..6bd5323 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -128,7 +128,9 @@
"libstorage_literals_headers",
"libfiemap_headers",
],
- test_min_api_level: 30,
+ test_options: {
+ min_shipping_api_level: 30,
+ },
auto_gen_config: true,
require_root: false,
}
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index 2465669..eb0acb5 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -45,13 +45,14 @@
static const char *main_ctrl_name = "com.android.ipc-unittest.ctrl";
static const char* receiver_name = "com.android.trusty.memref.receiver";
-static const char *_sopts = "hsvD:t:r:m:b:";
+static const char* _sopts = "hsvDS:t:r:m:b:";
/* clang-format off */
static const struct option _lopts[] = {
{"help", no_argument, 0, 'h'},
{"silent", no_argument, 0, 's'},
{"variable",no_argument, 0, 'v'},
{"dev", required_argument, 0, 'D'},
+ {"srv", required_argument, 0, 'S'},
{"repeat", required_argument, 0, 'r'},
{"burst", required_argument, 0, 'b'},
{"msgsize", required_argument, 0, 'm'},
@@ -59,24 +60,25 @@
};
/* clang-format on */
-static const char *usage =
-"Usage: %s [options]\n"
-"\n"
-"options:\n"
-" -h, --help prints this message and exit\n"
-" -D, --dev name device name\n"
-" -t, --test name test to run\n"
-" -r, --repeat cnt repeat count\n"
-" -m, --msgsize size max message size\n"
-" -v, --variable variable message size\n"
-" -s, --silent silent\n"
-"\n"
-;
+static const char* usage =
+ "Usage: %s [options]\n"
+ "\n"
+ "options:\n"
+ " -h, --help prints this message and exit\n"
+ " -D, --dev name device name\n"
+ " -S, --srv name service name\n"
+ " -t, --test name test to run\n"
+ " -r, --repeat cnt repeat count\n"
+ " -b, --burst cnt burst count\n"
+ " -m, --msgsize size max message size\n"
+ " -v, --variable variable message size\n"
+ " -s, --silent silent\n"
+ "\n";
static const char* usage_long =
"\n"
"The following tests are available:\n"
- " connect - connect to datasink service\n"
+ " connect - connect to specified service, defaults to echo+datasink\n"
" connect_foo - connect to non existing service\n"
" burst_write - send messages to datasink service\n"
" echo - send/receive messages to echo service\n"
@@ -98,6 +100,7 @@
static uint opt_msgburst = 32;
static bool opt_variable = false;
static bool opt_silent = false;
+static char* srv_name = NULL;
static void print_usage_and_exit(const char *prog, int code, bool verbose)
{
@@ -120,6 +123,10 @@
dev_name = strdup(optarg);
break;
+ case 'S':
+ srv_name = strdup(optarg);
+ break;
+
case 't':
test_name = strdup(optarg);
break;
@@ -159,26 +166,37 @@
uint i;
int echo_fd;
int dsink_fd;
+ int custom_fd;
if (!opt_silent) {
printf("%s: repeat = %u\n", __func__, repeat);
}
for (i = 0; i < repeat; i++) {
- echo_fd = tipc_connect(dev_name, echo_name);
- if (echo_fd < 0) {
- fprintf(stderr, "Failed to connect to '%s' service\n", "echo");
- }
- dsink_fd = tipc_connect(dev_name, datasink_name);
- if (dsink_fd < 0) {
- fprintf(stderr, "Failed to connect to '%s' service\n", "datasink");
- }
+ if (srv_name) {
+ custom_fd = tipc_connect(dev_name, srv_name);
+ if (custom_fd < 0) {
+ fprintf(stderr, "Failed to connect to '%s' service\n", srv_name);
+ }
+ if (custom_fd >= 0) {
+ tipc_close(custom_fd);
+ }
+ } else {
+ echo_fd = tipc_connect(dev_name, echo_name);
+ if (echo_fd < 0) {
+ fprintf(stderr, "Failed to connect to '%s' service\n", "echo");
+ }
+ dsink_fd = tipc_connect(dev_name, datasink_name);
+ if (dsink_fd < 0) {
+ fprintf(stderr, "Failed to connect to '%s' service\n", "datasink");
+ }
- if (echo_fd >= 0) {
- tipc_close(echo_fd);
- }
- if (dsink_fd >= 0) {
- tipc_close(dsink_fd);
+ if (echo_fd >= 0) {
+ tipc_close(echo_fd);
+ }
+ if (dsink_fd >= 0) {
+ tipc_close(dsink_fd);
+ }
}
}
diff --git a/trusty/storage/proxy/rpmb.c b/trusty/storage/proxy/rpmb.c
index 48e1641..8b8aee2 100644
--- a/trusty/storage/proxy/rpmb.c
+++ b/trusty/storage/proxy/rpmb.c
@@ -179,8 +179,15 @@
io_hdrp->timeout = TIMEOUT;
}
-/* Returns false if the sense data was valid and no errors were present */
-static bool check_scsi_sense(const uint8_t* sense_buf, size_t len) {
+/**
+ * unexpected_scsi_sense - Check for unexpected codes in the sense buffer.
+ * @sense_buf: buffer containing sense data
+ * @len: length of @sense_buf
+ *
+ * Return: %true if the sense data is not valid or contains an unexpected sense
+ * code, %false otherwise.
+ */
+static bool unexpected_scsi_sense(const uint8_t* sense_buf, size_t len) {
uint8_t response_code = 0;
uint8_t sense_key = 0;
uint8_t additional_sense_code = 0;
@@ -189,14 +196,14 @@
if (!sense_buf || len == 0) {
ALOGE("Invalid SCSI sense buffer, length: %zu\n", len);
- return false;
+ return true;
}
response_code = 0x7f & sense_buf[0];
if (response_code < 0x70 || response_code > 0x73) {
ALOGE("Invalid SCSI sense response code: %hhu\n", response_code);
- return false;
+ return true;
}
if (response_code >= 0x72) {
@@ -234,13 +241,13 @@
case 0x0f: /* COMPLETED, not present in kernel headers */
ALOGD("SCSI success with sense data: key=%hhu, asc=%hhu, ascq=%hhu\n", sense_key,
additional_sense_code, additional_sense_code_qualifier);
- return true;
+ return false;
}
ALOGE("Unexpected SCSI sense data: key=%hhu, asc=%hhu, ascq=%hhu\n", sense_key,
additional_sense_code, additional_sense_code_qualifier);
log_buf(ANDROID_LOG_ERROR, "sense buffer: ", sense_buf, len);
- return false;
+ return true;
}
static void check_sg_io_hdr(const sg_io_hdr_t* io_hdrp) {
@@ -253,7 +260,7 @@
}
if (io_hdrp->masked_status != GOOD && io_hdrp->sb_len_wr > 0) {
- bool sense_error = check_scsi_sense(io_hdrp->sbp, io_hdrp->sb_len_wr);
+ bool sense_error = unexpected_scsi_sense(io_hdrp->sbp, io_hdrp->sb_len_wr);
if (sense_error) {
ALOGE("Unexpected SCSI sense. masked_status: %hhu, host_status: %hu, driver_status: "
"%hu\n",