Skip to content

Commit cd055ee

Browse files
committed
Save kernel logs to /cache/recovery
Bug: 18642766 Change-Id: I6c8b7d8f9ffb688d3afdfe0d47c4142e711e421d Signed-off-by: Patrick Tjin <[email protected]>
1 parent 37ad1f1 commit cd055ee

File tree

1 file changed

+60
-6
lines changed

1 file changed

+60
-6
lines changed

recovery.cpp

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <stdio.h>
2626
#include <stdlib.h>
2727
#include <string.h>
28+
#include <sys/klog.h>
2829
#include <sys/stat.h>
2930
#include <sys/types.h>
3031
#include <time.h>
@@ -76,6 +77,8 @@ static const char *CACHE_ROOT = "/cache";
7677
static const char *SDCARD_ROOT = "/sdcard";
7778
static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
7879
static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";
80+
static const char *LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
81+
#define KLOG_DEFAULT_LEN (64 * 1024)
7982

8083
#define KEEP_LOG_COUNT 10
8184

@@ -259,6 +262,44 @@ set_sdcard_update_bootloader_message() {
259262
set_bootloader_message(&boot);
260263
}
261264

265+
// read from kernel log into buffer and write out to file
266+
static void
267+
save_kernel_log(const char *destination) {
268+
int n;
269+
char *buffer;
270+
int klog_buf_len;
271+
FILE *log;
272+
273+
klog_buf_len = klogctl(KLOG_SIZE_BUFFER, 0, 0);
274+
if (klog_buf_len <= 0) {
275+
LOGE("Error getting klog size (%s), using default\n", strerror(errno));
276+
klog_buf_len = KLOG_DEFAULT_LEN;
277+
}
278+
279+
buffer = (char *)malloc(klog_buf_len);
280+
if (!buffer) {
281+
LOGE("Can't alloc %d bytes for klog buffer\n", klog_buf_len);
282+
return;
283+
}
284+
285+
n = klogctl(KLOG_READ_ALL, buffer, klog_buf_len);
286+
if (n < 0) {
287+
LOGE("Error in reading klog (%s)\n", strerror(errno));
288+
free(buffer);
289+
return;
290+
}
291+
292+
log = fopen_path(destination, "w");
293+
if (log == NULL) {
294+
LOGE("Can't open %s\n", destination);
295+
free(buffer);
296+
return;
297+
}
298+
fwrite(buffer, n, 1, log);
299+
check_and_fclose(log, destination);
300+
free(buffer);
301+
}
302+
262303
// How much of the temp log we have copied to the copy in cache.
263304
static long tmplog_offset = 0;
264305

@@ -306,8 +347,11 @@ copy_logs() {
306347
copy_log_file(TEMPORARY_LOG_FILE, LOG_FILE, true);
307348
copy_log_file(TEMPORARY_LOG_FILE, LAST_LOG_FILE, false);
308349
copy_log_file(TEMPORARY_INSTALL_FILE, LAST_INSTALL_FILE, false);
350+
save_kernel_log(LAST_KMSG_FILE);
309351
chmod(LOG_FILE, 0600);
310352
chown(LOG_FILE, 1000, 1000); // system user
353+
chmod(LAST_KMSG_FILE, 0600);
354+
chown(LAST_KMSG_FILE, 1000, 1000); // system user
311355
chmod(LAST_LOG_FILE, 0640);
312356
chmod(LAST_INSTALL_FILE, 0644);
313357
sync();
@@ -695,15 +739,26 @@ static void file_to_ui(const char* fn) {
695739
}
696740

697741
static void choose_recovery_file(Device* device) {
698-
int i;
742+
unsigned int i;
743+
unsigned int n;
699744
static const char** title_headers = NULL;
700745
char *filename;
701746
const char* headers[] = { "Select file to view",
702747
"",
703748
NULL };
704-
char* entries[KEEP_LOG_COUNT + 2];
749+
// "Go back" + LAST_KMSG_FILE + KEEP_LOG_COUNT + terminating NULL entry
750+
char* entries[KEEP_LOG_COUNT + 3];
705751
memset(entries, 0, sizeof(entries));
706752

753+
n = 0;
754+
entries[n++] = strdup("Go back");
755+
756+
// Add kernel kmsg file if available
757+
if ((ensure_path_mounted(LAST_KMSG_FILE) == 0) && (access(LAST_KMSG_FILE, R_OK) == 0)) {
758+
entries[n++] = strdup(LAST_KMSG_FILE);
759+
}
760+
761+
// Add LAST_LOG_FILE + LAST_LOG_FILE.x
707762
for (i = 0; i < KEEP_LOG_COUNT; i++) {
708763
char *filename;
709764
if (asprintf(&filename, (i==0) ? LAST_LOG_FILE : (LAST_LOG_FILE ".%d"), i) == -1) {
@@ -712,13 +767,12 @@ static void choose_recovery_file(Device* device) {
712767
}
713768
if ((ensure_path_mounted(filename) != 0) || (access(filename, R_OK) == -1)) {
714769
free(filename);
715-
entries[i+1] = NULL;
770+
entries[n++] = NULL;
716771
break;
717772
}
718-
entries[i+1] = filename;
773+
entries[n++] = filename;
719774
}
720775

721-
entries[0] = strdup("Go back");
722776
title_headers = prepend_title((const char**)headers);
723777

724778
while(1) {
@@ -727,7 +781,7 @@ static void choose_recovery_file(Device* device) {
727781
file_to_ui(entries[chosen_item]);
728782
}
729783

730-
for (i = 0; i < KEEP_LOG_COUNT + 1; i++) {
784+
for (i = 0; i < (sizeof(entries) / sizeof(*entries)); i++) {
731785
free(entries[i]);
732786
}
733787
}

0 commit comments

Comments
 (0)