From 0683b16573bfbe5451a53f414766d4d675736007 Mon Sep 17 00:00:00 2001 From: "Liu, Xinwu" Date: Mon, 2 Jul 2018 15:58:28 +0800 Subject: [PATCH] tools:acrn-crashlog: Get reboot reason in acrnprobe Get system reboot reason from kernel commandline. Signed-off-by: Liu, Xinwu Acked-by: Chen Gang --- .../acrnprobe/include/startupreason.h | 4 +- tools/acrn-crashlog/acrnprobe/sender.c | 8 +- tools/acrn-crashlog/acrnprobe/startupreason.c | 99 +++++++++++-------- 3 files changed, 65 insertions(+), 46 deletions(-) diff --git a/tools/acrn-crashlog/acrnprobe/include/startupreason.h b/tools/acrn-crashlog/acrnprobe/include/startupreason.h index 940a1e54f..07cfffaac 100644 --- a/tools/acrn-crashlog/acrnprobe/include/startupreason.h +++ b/tools/acrn-crashlog/acrnprobe/include/startupreason.h @@ -19,4 +19,6 @@ * limitations under the License. */ -extern void read_startupreason(char *startupreason); +#define REBOOT_REASON_SIZE 32 + +extern void read_startupreason(char *startupreason, const size_t limit); diff --git a/tools/acrn-crashlog/acrnprobe/sender.c b/tools/acrn-crashlog/acrnprobe/sender.c index 5b7c62f31..6a61c3443 100644 --- a/tools/acrn-crashlog/acrnprobe/sender.c +++ b/tools/acrn-crashlog/acrnprobe/sender.c @@ -601,7 +601,7 @@ static void telemd_send_reboot(void) { struct sender_t *telemd; char *class; - char reason[MAXLINESIZE]; + char reason[REBOOT_REASON_SIZE]; int ret; telemd = get_sender_by_name("telemd"); @@ -627,7 +627,7 @@ static void telemd_send_reboot(void) free(content); } - read_startupreason(reason); + read_startupreason(reason, sizeof(reason)); ret = asprintf(&class, "clearlinux/reboot/%s", reason); if (ret < 0) { LOGE("compute string failed, out of memory\n"); @@ -952,7 +952,7 @@ static void crashlog_send_uptime(void) static void crashlog_send_reboot(void) { - char reason[MAXLINESIZE]; + char reason[REBOOT_REASON_SIZE]; char *key; struct sender_t *crashlog; @@ -972,7 +972,7 @@ static void crashlog_send_reboot(void) free(key); } - read_startupreason(reason); + read_startupreason(reason, sizeof(reason)); key = generate_event_id("REBOOT", reason); if (key == NULL) { LOGE("generate event id failed, error (%s)\n", diff --git a/tools/acrn-crashlog/acrnprobe/startupreason.c b/tools/acrn-crashlog/acrnprobe/startupreason.c index bf1f42ac7..93babfae0 100644 --- a/tools/acrn-crashlog/acrnprobe/startupreason.c +++ b/tools/acrn-crashlog/acrnprobe/startupreason.c @@ -28,68 +28,85 @@ #include "startupreason.h" #include "log_sys.h" -#define MAX_KERNEL_COMMAND_LINE_SIZE 4096 #define CURRENT_KERNEL_CMDLINE "/proc/cmdline" -static int get_cmdline_bootreason(char *bootreason) +static int get_cmdline_bootreason(char *bootreason, const size_t limit) { - int res, len = MAX_KERNEL_COMMAND_LINE_SIZE; - char *p, *p1, *p2; - char *cmdline; - const char key[] = "bootreason="; + int res; + unsigned long size; + char *start, *p1, *p2, *end; + void *cmdline; + const char key[] = "ABL.reset="; - cmdline = malloc(len); - if (!cmdline) { - LOGE("failed to allocate memory to read %s\n", - CURRENT_KERNEL_CMDLINE); - return -1; - } - res = file_read_string(CURRENT_KERNEL_CMDLINE, cmdline, len); - if (res <= 0) { + res = read_file(CURRENT_KERNEL_CMDLINE, &size, &cmdline); + if (res < 0) { LOGE("failed to read file %s - %s\n", CURRENT_KERNEL_CMDLINE, strerror(errno)); - free(cmdline); return -1; } - p = strstr(cmdline, key); - if (!p) { + start = strstr(cmdline, key); + if (!start) { + LOGW("can't find reboot reason with key (%s) in cmdline\n", + key); free(cmdline); return 0; } - p += strlen(key); - p1 = strstr(p, " "); - p2 = strstr(p, "\n"); - if (p2 && !p1) - *p2 = '\0'; - else if (p2 && p2 < p1) - *p2 = '\0'; - else if (p1) - *p1 = '\0'; - strncpy(bootreason, p, strlen(p) + 1); + /* if the string contains ' ' or '\n', break it by '\0' */ + start += strlen(key); + p1 = strchr(start, ' '); + p2 = strchr(start, '\n'); + if (p2 && p1) + end = MIN(p1, p2); + else + end = MAX(p1, p2); + + if (end) + *end = 0; + + const size_t len = MIN(strlen(start), limit - 1); + + if (len > 0) + memcpy(bootreason, start, len + 1); + free(cmdline); - return strlen(bootreason); + return len; } -static void get_default_bootreason(char *bootreason) +static int get_default_bootreason(char *bootreason, const size_t limit) { - int ret; - unsigned int i; - char bootreason_prop[MAX_KERNEL_COMMAND_LINE_SIZE]; + int len; + int i; - ret = get_cmdline_bootreason(bootreason_prop); - if (ret <= 0) - return; + len = get_cmdline_bootreason(bootreason, limit); + if (len <= 0) + return len; - for (i = 0; i < strlen(bootreason_prop); i++) - bootreason[i] = toupper(bootreason_prop[i]); - bootreason[i] = '\0'; + for (i = 0; i < len; i++) + bootreason[i] = toupper(bootreason[i]); + + return len; } -void read_startupreason(char *startupreason) +void read_startupreason(char *startupreason, const size_t limit) { - strcpy(startupreason, "UNKNOWN"); - get_default_bootreason(startupreason); + int res; + static char reboot_reason_cache[REBOOT_REASON_SIZE]; + + if (!reboot_reason_cache[0]) { + /* fill cache */ + res = get_default_bootreason(reboot_reason_cache, + sizeof(reboot_reason_cache)); + if (res <= 0) + strncpy(reboot_reason_cache, "UNKNOWN", + sizeof(reboot_reason_cache)); + } + + const size_t len = MIN(strlen(reboot_reason_cache), limit - 1); + + memcpy(startupreason, reboot_reason_cache, len); + *(startupreason + len) = 0; + return; }