Merge "Move load & restore logs to logging.cpp"
am: 3aff98aee8
Change-Id: I7da098091879ca823be31bd12b60dc12d5c45145
This commit is contained in:
@@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
struct selabel_handle;
|
struct selabel_handle;
|
||||||
|
|
||||||
void SetWipeDataSehandle(selabel_handle* handle);
|
|
||||||
|
|
||||||
// Returns true on success.
|
// Returns true on success.
|
||||||
bool WipeCache(RecoveryUI* ui, const std::function<bool()>& confirm);
|
bool WipeCache(RecoveryUI* ui, const std::function<bool()>& confirm);
|
||||||
|
|
||||||
|
|||||||
+4
-71
@@ -16,14 +16,11 @@
|
|||||||
|
|
||||||
#include "install/wipe_data.h"
|
#include "install/wipe_data.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
@@ -39,20 +36,6 @@ constexpr const char* CACHE_ROOT = "/cache";
|
|||||||
constexpr const char* DATA_ROOT = "/data";
|
constexpr const char* DATA_ROOT = "/data";
|
||||||
constexpr const char* METADATA_ROOT = "/metadata";
|
constexpr const char* METADATA_ROOT = "/metadata";
|
||||||
|
|
||||||
constexpr const char* CACHE_LOG_DIR = "/cache/recovery";
|
|
||||||
|
|
||||||
static struct selabel_handle* sehandle;
|
|
||||||
|
|
||||||
void SetWipeDataSehandle(selabel_handle* handle) {
|
|
||||||
sehandle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct saved_log_file {
|
|
||||||
std::string name;
|
|
||||||
struct stat sb;
|
|
||||||
std::string data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
|
static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
|
||||||
bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
|
bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
|
||||||
bool is_data = (strcmp(volume, DATA_ROOT) == 0);
|
bool is_data = (strcmp(volume, DATA_ROOT) == 0);
|
||||||
@@ -61,43 +44,10 @@ static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
|
|||||||
ui->SetProgressType(RecoveryUI::INDETERMINATE);
|
ui->SetProgressType(RecoveryUI::INDETERMINATE);
|
||||||
|
|
||||||
std::vector<saved_log_file> log_files;
|
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 (i.e. "/cache/recovery/last_*") and the
|
||||||
// (i.e. "/cache/recovery/last_*") and the current log
|
// current log ("/cache/recovery/log") into memory, so we can restore them after the reformat.
|
||||||
// ("/cache/recovery/log") into memory, so we can restore them after
|
log_files = ReadLogFilesToMemory();
|
||||||
// the reformat.
|
|
||||||
|
|
||||||
ensure_path_mounted(volume);
|
|
||||||
|
|
||||||
struct dirent* de;
|
|
||||||
std::unique_ptr<DIR, decltype(&closedir)> d(opendir(CACHE_LOG_DIR), closedir);
|
|
||||||
if (d) {
|
|
||||||
while ((de = readdir(d.get())) != nullptr) {
|
|
||||||
if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0) {
|
|
||||||
std::string path = android::base::StringPrintf("%s/%s", CACHE_LOG_DIR, de->d_name);
|
|
||||||
|
|
||||||
struct stat sb;
|
|
||||||
if (stat(path.c_str(), &sb) == 0) {
|
|
||||||
// truncate files to 512kb
|
|
||||||
if (sb.st_size > (1 << 19)) {
|
|
||||||
sb.st_size = 1 << 19;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string data(sb.st_size, '\0');
|
|
||||||
FILE* f = fopen(path.c_str(), "rbe");
|
|
||||||
fread(&data[0], 1, data.size(), f);
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
log_files.emplace_back(saved_log_file{ path, sb, data });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
PLOG(ERROR) << "Failed to opendir " << CACHE_LOG_DIR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->Print("Formatting %s...\n", volume);
|
ui->Print("Formatting %s...\n", volume);
|
||||||
@@ -128,24 +78,7 @@ static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_cache) {
|
if (is_cache) {
|
||||||
// Re-create the log dir and write back the log entries.
|
RestoreLogFilesAfterFormat(log_files);
|
||||||
if (ensure_path_mounted(CACHE_LOG_DIR) == 0 &&
|
|
||||||
mkdir_recursively(CACHE_LOG_DIR, 0777, false, sehandle) == 0) {
|
|
||||||
for (const auto& log : log_files) {
|
|
||||||
if (!android::base::WriteStringToFile(log.data, log.name, log.sb.st_mode, log.sb.st_uid,
|
|
||||||
log.sb.st_gid)) {
|
|
||||||
PLOG(ERROR) << "Failed to write to " << log.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PLOG(ERROR) << "Failed to mount / create " << CACHE_LOG_DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any part of the log we'd copied to cache is now gone.
|
|
||||||
// Reset the pointer so we copy from the beginning of the temp
|
|
||||||
// log.
|
|
||||||
reset_tmplog_offset();
|
|
||||||
copy_logs(true /* save_current_log */, true /* has_cache */, sehandle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (result == 0);
|
return (result == 0);
|
||||||
|
|||||||
@@ -18,9 +18,11 @@
|
|||||||
#define _LOGGING_H
|
#define _LOGGING_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <log/log_id.h>
|
#include <log/log_id.h>
|
||||||
|
|
||||||
@@ -28,6 +30,14 @@ static constexpr int KEEP_LOG_COUNT = 10;
|
|||||||
|
|
||||||
struct selabel_handle;
|
struct selabel_handle;
|
||||||
|
|
||||||
|
struct saved_log_file {
|
||||||
|
std::string name;
|
||||||
|
struct stat sb;
|
||||||
|
std::string data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void SetLoggingSehandle(selabel_handle* handle);
|
||||||
|
|
||||||
ssize_t logbasename(log_id_t id, char prio, const char* filename, const char* buf, size_t len,
|
ssize_t logbasename(log_id_t id, char prio, const char* filename, const char* buf, size_t len,
|
||||||
void* arg);
|
void* arg);
|
||||||
|
|
||||||
@@ -48,4 +58,8 @@ void reset_tmplog_offset();
|
|||||||
|
|
||||||
void save_kernel_log(const char* destination);
|
void save_kernel_log(const char* destination);
|
||||||
|
|
||||||
|
std::vector<saved_log_file> ReadLogFilesToMemory();
|
||||||
|
|
||||||
|
bool RestoreLogFilesAfterFormat(const std::vector<saved_log_file>& log_files);
|
||||||
|
|
||||||
#endif //_LOGGING_H
|
#endif //_LOGGING_H
|
||||||
|
|||||||
+90
-10
@@ -16,17 +16,22 @@
|
|||||||
|
|
||||||
#include "otautil/logging.h"
|
#include "otautil/logging.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/klog.h>
|
#include <sys/klog.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/parseint.h>
|
#include <android-base/parseint.h>
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
|
#include <android-base/unique_fd.h>
|
||||||
#include <private/android_filesystem_config.h> /* for AID_SYSTEM */
|
#include <private/android_filesystem_config.h> /* for AID_SYSTEM */
|
||||||
#include <private/android_logger.h> /* private pmsg functions */
|
#include <private/android_logger.h> /* private pmsg functions */
|
||||||
#include <selinux/label.h>
|
#include <selinux/label.h>
|
||||||
@@ -35,13 +40,21 @@
|
|||||||
#include "otautil/paths.h"
|
#include "otautil/paths.h"
|
||||||
#include "otautil/roots.h"
|
#include "otautil/roots.h"
|
||||||
|
|
||||||
static constexpr const char* LOG_FILE = "/cache/recovery/log";
|
constexpr const char* LOG_FILE = "/cache/recovery/log";
|
||||||
static constexpr const char* LAST_INSTALL_FILE = "/cache/recovery/last_install";
|
constexpr const char* LAST_INSTALL_FILE = "/cache/recovery/last_install";
|
||||||
static constexpr const char* LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
|
constexpr const char* LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
|
||||||
static constexpr const char* LAST_LOG_FILE = "/cache/recovery/last_log";
|
constexpr const char* LAST_LOG_FILE = "/cache/recovery/last_log";
|
||||||
|
|
||||||
static const std::string LAST_KMSG_FILTER = "recovery/last_kmsg";
|
constexpr const char* LAST_KMSG_FILTER = "recovery/last_kmsg";
|
||||||
static const std::string LAST_LOG_FILTER = "recovery/last_log";
|
constexpr const char* LAST_LOG_FILTER = "recovery/last_log";
|
||||||
|
|
||||||
|
constexpr const char* CACHE_LOG_DIR = "/cache/recovery";
|
||||||
|
|
||||||
|
static struct selabel_handle* logging_sehandle;
|
||||||
|
|
||||||
|
void SetLoggingSehandle(selabel_handle* handle) {
|
||||||
|
logging_sehandle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
// fopen(3)'s the given file, by mounting volumes and making parent dirs as necessary. Returns the
|
// fopen(3)'s the given file, by mounting volumes and making parent dirs as necessary. Returns the
|
||||||
// file pointer, or nullptr on error.
|
// file pointer, or nullptr on error.
|
||||||
@@ -74,8 +87,8 @@ void check_and_fclose(FILE* fp, const std::string& name) {
|
|||||||
ssize_t logbasename(log_id_t /* id */, char /* prio */, const char* filename, const char* /* buf */,
|
ssize_t logbasename(log_id_t /* id */, char /* prio */, const char* filename, const char* /* buf */,
|
||||||
size_t len, void* arg) {
|
size_t len, void* arg) {
|
||||||
bool* do_rotate = static_cast<bool*>(arg);
|
bool* do_rotate = static_cast<bool*>(arg);
|
||||||
if (LAST_KMSG_FILTER.find(filename) != std::string::npos ||
|
if (std::string(LAST_KMSG_FILTER).find(filename) != std::string::npos ||
|
||||||
LAST_LOG_FILTER.find(filename) != std::string::npos) {
|
std::string(LAST_LOG_FILTER).find(filename) != std::string::npos) {
|
||||||
*do_rotate = true;
|
*do_rotate = true;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
@@ -92,8 +105,8 @@ ssize_t logrotate(log_id_t id, char prio, const char* filename, const char* buf,
|
|||||||
size_t dot = name.find_last_of('.');
|
size_t dot = name.find_last_of('.');
|
||||||
std::string sub = name.substr(0, dot);
|
std::string sub = name.substr(0, dot);
|
||||||
|
|
||||||
if (LAST_KMSG_FILTER.find(sub) == std::string::npos &&
|
if (std::string(LAST_KMSG_FILTER).find(sub) == std::string::npos &&
|
||||||
LAST_LOG_FILTER.find(sub) == std::string::npos) {
|
std::string(LAST_LOG_FILTER).find(sub) == std::string::npos) {
|
||||||
return __android_log_pmsg_file_write(id, prio, filename, buf, len);
|
return __android_log_pmsg_file_write(id, prio, filename, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,3 +256,70 @@ void save_kernel_log(const char* destination) {
|
|||||||
buffer.resize(n);
|
buffer.resize(n);
|
||||||
android::base::WriteStringToFile(buffer, destination);
|
android::base::WriteStringToFile(buffer, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<saved_log_file> ReadLogFilesToMemory() {
|
||||||
|
ensure_path_mounted("/cache");
|
||||||
|
|
||||||
|
struct dirent* de;
|
||||||
|
std::unique_ptr<DIR, decltype(&closedir)> d(opendir(CACHE_LOG_DIR), closedir);
|
||||||
|
if (!d) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
PLOG(ERROR) << "Failed to opendir " << CACHE_LOG_DIR;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<saved_log_file> log_files;
|
||||||
|
while ((de = readdir(d.get())) != nullptr) {
|
||||||
|
if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0) {
|
||||||
|
std::string path = android::base::StringPrintf("%s/%s", CACHE_LOG_DIR, de->d_name);
|
||||||
|
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(path.c_str(), &sb) != 0) {
|
||||||
|
PLOG(ERROR) << "Failed to stat " << path;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Truncate files to 512kb
|
||||||
|
size_t read_size = std::min<size_t>(sb.st_size, 1 << 19);
|
||||||
|
std::string data(read_size, '\0');
|
||||||
|
|
||||||
|
android::base::unique_fd log_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY)));
|
||||||
|
if (log_fd == -1 || !android::base::ReadFully(log_fd, data.data(), read_size)) {
|
||||||
|
PLOG(ERROR) << "Failed to read log file " << path;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_files.emplace_back(saved_log_file{ path, sb, data });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return log_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RestoreLogFilesAfterFormat(const std::vector<saved_log_file>& log_files) {
|
||||||
|
// Re-create the log dir and write back the log entries.
|
||||||
|
if (ensure_path_mounted(CACHE_LOG_DIR) != 0) {
|
||||||
|
PLOG(ERROR) << "Failed to mount " << CACHE_LOG_DIR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mkdir_recursively(CACHE_LOG_DIR, 0777, false, logging_sehandle) != 0) {
|
||||||
|
PLOG(ERROR) << "Failed to create " << CACHE_LOG_DIR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& log : log_files) {
|
||||||
|
if (!android::base::WriteStringToFile(log.data, log.name, log.sb.st_mode, log.sb.st_uid,
|
||||||
|
log.sb.st_gid)) {
|
||||||
|
PLOG(ERROR) << "Failed to write to " << log.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any part of the log we'd copied to cache is now gone.
|
||||||
|
// Reset the pointer so we copy from the beginning of the temp
|
||||||
|
// log.
|
||||||
|
reset_tmplog_offset();
|
||||||
|
copy_logs(true /* save_current_log */, true /* has_cache */, logging_sehandle);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -435,7 +435,7 @@ int main(int argc, char** argv) {
|
|||||||
ui->Print("Warning: No file_contexts\n");
|
ui->Print("Warning: No file_contexts\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SetWipeDataSehandle(sehandle);
|
SetLoggingSehandle(sehandle);
|
||||||
|
|
||||||
std::atomic<Device::BuiltinAction> action;
|
std::atomic<Device::BuiltinAction> action;
|
||||||
std::thread listener_thread(ListenRecoverySocket, ui, std::ref(action));
|
std::thread listener_thread(ListenRecoverySocket, ui, std::ref(action));
|
||||||
|
|||||||
Reference in New Issue
Block a user