diff --git a/tools/acrn-crashlog/acrnprobe/channels.c b/tools/acrn-crashlog/acrnprobe/channels.c index 872507ff1..8599d04f1 100644 --- a/tools/acrn-crashlog/acrnprobe/channels.c +++ b/tools/acrn-crashlog/acrnprobe/channels.c @@ -20,6 +20,8 @@ #include "fsutils.h" #include "strutils.h" #include "channels.h" +#include "startupreason.h" +#include "probeutils.h" #include "log_sys.h" #define POLLING_TIMER_SIG 0xCEAC @@ -105,11 +107,13 @@ static void channel_oneshot(struct channel_t *cnl) LOGD("initializing channel %s ...\n", cname); + if (!is_boot_id_changed()) + return; + e = create_event(REBOOT, cname, NULL, 0, NULL); if (e) event_enqueue(e); - for_each_crash(id, crash, conf) { if (!crash || !is_root_crash(crash)) continue; @@ -117,13 +121,26 @@ static void channel_oneshot(struct channel_t *cnl) if (strcmp(crash->channel, cname)) continue; - if (crash->trigger && - !strcmp("file", crash->trigger->type) && - file_exists(crash->trigger->path)) { - e = create_event(CRASH, cname, (void *)crash, - 0, crash->trigger->path); - if (e) - event_enqueue(e); + if (!crash->trigger) + continue; + + if (!strcmp("file", crash->trigger->type)) { + if (file_exists(crash->trigger->path)) { + e = create_event(CRASH, cname, (void *)crash, + 0, crash->trigger->path); + if (e) + event_enqueue(e); + } + } else if (!strcmp("rebootreason", crash->trigger->type)) { + char rreason[REBOOT_REASON_SIZE]; + + read_startupreason(rreason, sizeof(rreason)); + if (!strcmp(rreason, crash->content[0])) { + e = create_event(CRASH, cname, (void *)crash, + 0, crash->trigger->path); + if (e) + event_enqueue(e); + } } } diff --git a/tools/acrn-crashlog/acrnprobe/include/probeutils.h b/tools/acrn-crashlog/acrnprobe/include/probeutils.h index 1ee423757..f8d89681f 100644 --- a/tools/acrn-crashlog/acrnprobe/include/probeutils.h +++ b/tools/acrn-crashlog/acrnprobe/include/probeutils.h @@ -40,5 +40,6 @@ void generate_crashfile(char *dir, char *event, char *hashkey, char *type, char *data0, char *data1, char *data2); char *generate_log_dir(enum e_dir_mode mode, char *hashkey); +int is_boot_id_changed(void); #endif diff --git a/tools/acrn-crashlog/acrnprobe/probeutils.c b/tools/acrn-crashlog/acrnprobe/probeutils.c index 41dccc742..5710973f4 100644 --- a/tools/acrn-crashlog/acrnprobe/probeutils.c +++ b/tools/acrn-crashlog/acrnprobe/probeutils.c @@ -38,14 +38,21 @@ #define STATS_CURRENT_LOG "currentstatslog" #define VM_CURRENT_LOG "currentvmlog" +#define BOOTID_NODE "/proc/sys/kernel/random/boot_id" +#define BOOTID_LOG "currentbootid" + unsigned long long get_uptime(void) { - static long long time_ns = -1; - struct timespec ts; + long long time_ns; + struct timespec ts; + int res; - clock_gettime(CLOCK_BOOTTIME, &ts); - time_ns = (long long)ts.tv_sec * 1000000000LL + - (long long)ts.tv_nsec; + res = clock_gettime(CLOCK_BOOTTIME, &ts); + if (res == -1) + return res; + + time_ns = (long long)ts.tv_sec * 1000000000LL + + (long long)ts.tv_nsec; return time_ns; } @@ -56,6 +63,8 @@ int get_uptime_string(char *newuptime, int *hours) int seconds, minutes; tm = get_uptime(); + if (tm == -1) + return -1; /* seconds */ *hours = (int)(tm / 1000000000LL); @@ -444,3 +453,41 @@ char *generate_log_dir(enum e_dir_mode mode, char *hashkey) return strdup(path); } + +int is_boot_id_changed(void) +{ + void *boot_id; + void *logged_boot_id; + char logged_boot_id_path[PATH_MAX]; + unsigned long size; + struct sender_t *crashlog; + int res; + int result = 1; /* returns changed by default */ + + crashlog = get_sender_by_name("crashlog"); + if (!crashlog) + return result; + + res = read_file(BOOTID_NODE, &size, &boot_id); + if (res == -1) + return result; + + snprintf(logged_boot_id_path, sizeof(logged_boot_id_path), "%s/%s", + crashlog->outdir, BOOTID_LOG); + if (file_exists(logged_boot_id_path)) { + res = read_file(logged_boot_id_path, &size, &logged_boot_id); + if (res == -1) + goto out; + + if (!strcmp((char *)logged_boot_id, (char *)boot_id)) + result = 0; + + free(logged_boot_id); + } + + if (result) + overwrite_file(logged_boot_id_path, boot_id); +out: + free(boot_id); + return result; +} diff --git a/tools/acrn-crashlog/data/acrnprobe.service b/tools/acrn-crashlog/data/acrnprobe.service index 611d3b410..257a51e02 100644 --- a/tools/acrn-crashlog/data/acrnprobe.service +++ b/tools/acrn-crashlog/data/acrnprobe.service @@ -2,6 +2,7 @@ Description=ACRN crashlog probe Requires=telemd.socket Requires=usercrash_s +After=acrnlog.service After=usercrash.service After=prepare.service diff --git a/tools/acrn-crashlog/data/acrnprobe.xml b/tools/acrn-crashlog/data/acrnprobe.xml index a2e51c02b..7f0532534 100644 --- a/tools/acrn-crashlog/data/acrnprobe.xml +++ b/tools/acrn-crashlog/data/acrnprobe.xml @@ -27,8 +27,8 @@ t_pstore - file - /sys/fs/pstore/console-ramoops + node + /sys/fs/pstore/console-ramoops-0 t_boot @@ -40,6 +40,15 @@ dir /var/log/usercrashes + + t_rebootreason + rebootreason + + + t_acrnlog_last + file + /tmp/acrnlog/acrnlog_last.[*] + @@ -57,8 +66,8 @@ pstore - file - /sys/fs/pstore/console-ramoops + node + /sys/fs/pstore/console-ramoops-0 kmsg @@ -90,34 +99,66 @@ + UNKNOWN + t_rebootreason + oneshot + WARM + pstore + acrnlog_last + + + SWWDT_UNHANDLE + t_rebootreason + oneshot + WATCHDOG + pstore + acrnlog_last + + + HWWDT_UNHANDLE + t_rebootreason + oneshot + GLOBAL + pstore + acrnlog_last + + + ACRNCRASH + t_acrnlog_last + = Unhandled exception: + + IPANIC t_pstore - oneshot - pstore + + Kernel panic - not syncing: + BUG: unable to handle kernel kernel BUG at EIP is at Comm: - - IPANIC_SWWDT - BUG: soft lockup - CPU# + + ACRNCRASH + t_acrnlog_last + = Unhandled exception: - - IPANIC_SWWDT_FAKE - EIP: panic_dbg_set - RIP: panic_dbg_set + + SWWDT_IPANIC + t_pstore + + Kernel panic - not syncing: + BUG: unable to handle kernel + kernel BUG at + EIP is at + Comm: - + USERCRASH t_usercrash inotify kmsg syslog - - IPANIC_HWWDT - Watchdog detected hard LOCKUP on cpu - @@ -132,6 +173,4 @@ - -