Merge "recovery: Clean up the log saving while wiping." am: 28bbe029b6 am: 7294a8830b

am: 495478e853

Change-Id: I6d64980838979f65a6240e5e95d54ea733e8cc58
This commit is contained in:
Tao Bao
2016-12-13 22:55:08 +00:00
committed by android-build-merger
+31 -41
View File
@@ -512,12 +512,11 @@ static void finish_recovery() {
sync(); // For good measure. sync(); // For good measure.
} }
typedef struct _saved_log_file { struct saved_log_file {
char* name; std::string name;
struct stat st; struct stat sb;
unsigned char* data; std::string data;
struct _saved_log_file* next; };
} saved_log_file;
static bool erase_volume(const char* volume) { static bool erase_volume(const char* volume) {
bool is_cache = (strcmp(volume, CACHE_ROOT) == 0); bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
@@ -526,7 +525,7 @@ static bool erase_volume(const char* volume) {
ui->SetBackground(RecoveryUI::ERASING); ui->SetBackground(RecoveryUI::ERASING);
ui->SetProgressType(RecoveryUI::INDETERMINATE); ui->SetProgressType(RecoveryUI::INDETERMINATE);
saved_log_file* head = NULL; std::vector<saved_log_file> log_files;
if (is_cache) { if (is_cache) {
// If we're reformatting /cache, we load any past logs // If we're reformatting /cache, we load any past logs
@@ -536,39 +535,32 @@ static bool erase_volume(const char* volume) {
ensure_path_mounted(volume); ensure_path_mounted(volume);
DIR* d;
struct dirent* de; struct dirent* de;
d = opendir(CACHE_LOG_DIR); std::unique_ptr<DIR, decltype(&closedir)> d(opendir(CACHE_LOG_DIR), closedir);
if (d) { if (d) {
char path[PATH_MAX]; while ((de = readdir(d.get())) != nullptr) {
strcpy(path, CACHE_LOG_DIR);
strcat(path, "/");
int path_len = strlen(path);
while ((de = readdir(d)) != NULL) {
if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0) { if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0) {
saved_log_file* p = (saved_log_file*) malloc(sizeof(saved_log_file)); std::string path = android::base::StringPrintf("%s/%s", CACHE_LOG_DIR, de->d_name);
strcpy(path+path_len, de->d_name);
p->name = strdup(path); struct stat sb;
if (stat(path, &(p->st)) == 0) { if (stat(path.c_str(), &sb) == 0) {
// truncate files to 512kb // truncate files to 512kb
if (p->st.st_size > (1 << 19)) { if (sb.st_size > (1 << 19)) {
p->st.st_size = 1 << 19; sb.st_size = 1 << 19;
} }
p->data = (unsigned char*) malloc(p->st.st_size);
FILE* f = fopen(path, "rb"); std::string data(sb.st_size, '\0');
fread(p->data, 1, p->st.st_size, f); FILE* f = fopen(path.c_str(), "rb");
fread(&data[0], 1, data.size(), f);
fclose(f); fclose(f);
p->next = head;
head = p; log_files.emplace_back(saved_log_file{ path, sb, data });
} else {
free(p);
} }
} }
} }
closedir(d);
} else { } else {
if (errno != ENOENT) { if (errno != ENOENT) {
printf("opendir failed: %s\n", strerror(errno)); PLOG(ERROR) << "Failed to opendir " << CACHE_LOG_DIR;
} }
} }
} }
@@ -600,19 +592,17 @@ static bool erase_volume(const char* volume) {
} }
if (is_cache) { if (is_cache) {
while (head) { // Re-create the log dir and write back the log entries.
FILE* f = fopen_path(head->name, "wb"); if (ensure_path_mounted(CACHE_LOG_DIR) == 0 &&
if (f) { dirCreateHierarchy(CACHE_LOG_DIR, 0777, nullptr, false, sehandle) == 0) {
fwrite(head->data, 1, head->st.st_size, f); for (const auto& log : log_files) {
fclose(f); if (!android::base::WriteStringToFile(log.data, log.name, log.sb.st_mode, log.sb.st_uid,
chmod(head->name, head->st.st_mode); log.sb.st_gid)) {
chown(head->name, head->st.st_uid, head->st.st_gid); PLOG(ERROR) << "Failed to write to " << log.name;
} }
free(head->name); }
free(head->data); } else {
saved_log_file* temp = head->next; PLOG(ERROR) << "Failed to mount / create " << CACHE_LOG_DIR;
free(head);
head = temp;
} }
// Any part of the log we'd copied to cache is now gone. // Any part of the log we'd copied to cache is now gone.