inspect_cow: Add an --extract-to argument.
This adds an --extract-to argument to inspect_cow to verify that full OTA snapshots contain correct data. It does not yet work for ordered ops. Test: inspect_cow Bug: N/A Change-Id: I9014da3e83fd4fb5ea54ac1d36e527b3e3e6c9d5 Change-Id: I7e256e8ddec626980cdcf8680bbeac3c2e9d8de1
This commit is contained in:
parent
e877885533
commit
8a28163d33
1 changed files with 26 additions and 3 deletions
|
|
@ -22,6 +22,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <gflags/gflags.h>
|
||||
|
|
@ -38,11 +39,13 @@ DEFINE_bool(show_merged, false,
|
|||
DEFINE_bool(verify_merge_sequence, false, "Verify merge order sequencing");
|
||||
DEFINE_bool(show_merge_sequence, false, "Show merge order sequence");
|
||||
DEFINE_bool(show_raw_ops, false, "Show raw ops directly from the underlying parser");
|
||||
DEFINE_string(extract_to, "", "Extract the COW contents to the given file");
|
||||
|
||||
namespace android {
|
||||
namespace snapshot {
|
||||
|
||||
using android::base::borrowed_fd;
|
||||
using android::base::unique_fd;
|
||||
|
||||
void MyLogger(android::base::LogId, android::base::LogSeverity severity, const char*, const char*,
|
||||
unsigned int, const char* message) {
|
||||
|
|
@ -53,7 +56,7 @@ void MyLogger(android::base::LogId, android::base::LogSeverity severity, const c
|
|||
}
|
||||
}
|
||||
|
||||
static void ShowBad(CowReader& reader, const struct CowOperation* op) {
|
||||
static void ShowBad(CowReader& reader, const CowOperation* op) {
|
||||
size_t count;
|
||||
auto buffer = std::make_unique<uint8_t[]>(op->data_length);
|
||||
|
||||
|
|
@ -104,12 +107,21 @@ static bool ShowRawOpStream(borrowed_fd fd) {
|
|||
}
|
||||
|
||||
static bool Inspect(const std::string& path) {
|
||||
android::base::unique_fd fd(open(path.c_str(), O_RDONLY));
|
||||
unique_fd fd(open(path.c_str(), O_RDONLY));
|
||||
if (fd < 0) {
|
||||
PLOG(ERROR) << "open failed: " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
unique_fd extract_to;
|
||||
if (!FLAGS_extract_to.empty()) {
|
||||
extract_to.reset(open(FLAGS_extract_to.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0664));
|
||||
if (extract_to < 0) {
|
||||
PLOG(ERROR) << "could not open " << FLAGS_extract_to << " for writing";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CowReader reader;
|
||||
|
||||
auto start_time = std::chrono::steady_clock::now();
|
||||
|
|
@ -186,12 +198,23 @@ static bool Inspect(const std::string& path) {
|
|||
|
||||
if (!FLAGS_silent && FLAGS_show_ops) std::cout << *op << "\n";
|
||||
|
||||
if (FLAGS_decompress && op->type == kCowReplaceOp && op->compression != kCowCompressNone) {
|
||||
if ((FLAGS_decompress || extract_to >= 0) && op->type == kCowReplaceOp) {
|
||||
if (reader.ReadData(op, buffer.data(), buffer.size()) < 0) {
|
||||
std::cerr << "Failed to decompress for :" << *op << "\n";
|
||||
success = false;
|
||||
if (FLAGS_show_bad_data) ShowBad(reader, op);
|
||||
}
|
||||
if (extract_to >= 0) {
|
||||
off_t offset = uint64_t(op->new_block) * header.block_size;
|
||||
if (!android::base::WriteFullyAtOffset(extract_to, buffer.data(), buffer.size(),
|
||||
offset)) {
|
||||
PLOG(ERROR) << "failed to write block " << op->new_block;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (extract_to >= 0 && !IsMetadataOp(*op) && op->type != kCowZeroOp) {
|
||||
PLOG(ERROR) << "Cannot extract op yet: " << *op;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op->type == kCowSequenceOp && FLAGS_show_merge_sequence) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue