summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--minadbd/README.md (renamed from minadbd/README.txt)2
-rw-r--r--recovery.cpp4
-rw-r--r--uncrypt/uncrypt.cpp41
3 files changed, 43 insertions, 4 deletions
diff --git a/minadbd/README.txt b/minadbd/README.md
index e69dc87c6..5a0a067de 100644
--- a/minadbd/README.txt
+++ b/minadbd/README.md
@@ -3,6 +3,6 @@ minadbd, and services.c has been modified as follows:
- all services removed
- all host mode support removed
- - sideload_service() added; this is the only service supported. It
+ - `sideload_service()` added; this is the only service supported. It
receives a single blob of data, writes it to a fixed filename, and
makes the process exit.
diff --git a/recovery.cpp b/recovery.cpp
index 5888c542a..fac241d63 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -322,7 +322,7 @@ static std::vector<std::string> get_args(const int argc, char** const argv) {
std::vector<std::string> args(argv, argv + argc);
// --- if arguments weren't supplied, look in the bootloader control block
- if (argc == 1) {
+ if (args.size() == 1) {
boot.recovery[sizeof(boot.recovery) - 1] = '\0'; // Ensure termination
std::string boot_recovery(boot.recovery);
std::vector<std::string> tokens = android::base::Split(boot_recovery, "\n");
@@ -338,7 +338,7 @@ static std::vector<std::string> get_args(const int argc, char** const argv) {
}
// --- if that doesn't work, try the command file (if we have /cache).
- if (argc == 1 && has_cache) {
+ if (args.size() == 1 && has_cache) {
std::string content;
if (ensure_path_mounted(COMMAND_FILE) == 0 &&
android::base::ReadFileToString(COMMAND_FILE, &content)) {
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 4ac516d21..a06384dd5 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -118,7 +118,8 @@
#include "error_code.h"
-#define WINDOW_SIZE 5
+static constexpr int WINDOW_SIZE = 5;
+static constexpr int FIBMAP_RETRY_LIMIT = 3;
// uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT.
//
@@ -233,6 +234,26 @@ static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::stri
return true;
}
+static int retry_fibmap(const int fd, const char* name, int* block, const int head_block) {
+ CHECK(block != nullptr);
+ for (size_t i = 0; i < FIBMAP_RETRY_LIMIT; i++) {
+ if (fsync(fd) == -1) {
+ PLOG(ERROR) << "failed to fsync \"" << name << "\"";
+ return kUncryptFileSyncError;
+ }
+ if (ioctl(fd, FIBMAP, block) != 0) {
+ PLOG(ERROR) << "failed to find block " << head_block;
+ return kUncryptIoctlError;
+ }
+ if (*block != 0) {
+ return kUncryptNoError;
+ }
+ sleep(1);
+ }
+ LOG(ERROR) << "fibmap of " << head_block << "always returns 0";
+ return kUncryptIoctlError;
+}
+
static int produce_block_map(const char* path, const char* map_file, const char* blk_dev,
bool encrypted, int socket) {
std::string err;
@@ -314,6 +335,15 @@ static int produce_block_map(const char* path, const char* map_file, const char*
PLOG(ERROR) << "failed to find block " << head_block;
return kUncryptIoctlError;
}
+
+ if (block == 0) {
+ LOG(ERROR) << "failed to find block " << head_block << ", retrying";
+ int error = retry_fibmap(fd, path, &block, head_block);
+ if (error != kUncryptNoError) {
+ return error;
+ }
+ }
+
add_block_to_ranges(ranges, block);
if (encrypted) {
if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
@@ -350,6 +380,15 @@ static int produce_block_map(const char* path, const char* map_file, const char*
PLOG(ERROR) << "failed to find block " << head_block;
return kUncryptIoctlError;
}
+
+ if (block == 0) {
+ LOG(ERROR) << "failed to find block " << head_block << ", retrying";
+ int error = retry_fibmap(fd, path, &block, head_block);
+ if (error != kUncryptNoError) {
+ return error;
+ }
+ }
+
add_block_to_ranges(ranges, block);
if (encrypted) {
if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,