From a4aed4535abffb2e3ad325a4b7aaf27288b213d2 Mon Sep 17 00:00:00 2001 From: "Liu, Xinwu" Date: Wed, 18 Jul 2018 12:47:19 +0800 Subject: [PATCH] tools: acrn-crashlog: replace debugfs with api Replace debugfs with api in loop.c. There is no functional change. Signed-off-by: Liu, Xinwu Acked-by: Chen Gang --- .../acrn-crashlog/acrnprobe/android_events.c | 131 ++++++------------ .../acrnprobe/crash_reclassify.c | 4 + .../acrnprobe/include/load_conf.h | 4 +- tools/acrn-crashlog/acrnprobe/probeutils.c | 4 +- tools/acrn-crashlog/acrnprobe/property.c | 3 +- tools/acrn-crashlog/acrnprobe/sender.c | 39 ++---- tools/acrn-crashlog/acrnprobe/startupreason.c | 4 + tools/acrn-crashlog/common/cmdutils.c | 9 -- tools/acrn-crashlog/common/include/cmdutils.h | 1 - 9 files changed, 69 insertions(+), 130 deletions(-) diff --git a/tools/acrn-crashlog/acrnprobe/android_events.c b/tools/acrn-crashlog/acrnprobe/android_events.c index 94d982cdf..0b830e2cb 100644 --- a/tools/acrn-crashlog/acrnprobe/android_events.c +++ b/tools/acrn-crashlog/acrnprobe/android_events.c @@ -24,7 +24,12 @@ #define ANDROID_DATA_PAR_NAME "data" #define ANDROID_EVT_KEY_LEN 20 +/* TODO: hardcoding the img path here means that only one Android Guest OS + * is supoorted at this moment. To support multiple Android Guest OS, this + * path should be moved to structure vm_t and configurable. + */ static const char *android_img = "/data/android/android.img"; +static const char *android_histpath = "logs/history_event"; char *loop_dev; /* Find the head of str, caller must guarantee that 'str' is not in @@ -211,43 +216,41 @@ static int refresh_key_synced_stage2(const struct mm_file_t *m_vm_records, static int get_vm_history(struct vm_t *vm, const struct sender_t *sender, void **data) { - char vm_history[PATH_MAX]; unsigned long size; int ret; int sid; - if (!vm || !sender) + if (!vm || !sender || !data) return -1; sid = sender_id(sender); if (sid == -1) return -1; - snprintf(vm_history, sizeof(vm_history), "/tmp/%s_%s", - "vm_hist", vm->name); + ret = e2fs_read_file_by_fpath(vm->datafs, android_histpath, + data, &size); + if (ret == -1) { + LOGE("failed to get vm_history from (%s).\n", vm->name); + *data = NULL; + return -1; + } + if (!size) { + LOGE("empty vm_history from (%s).\n", vm->name); + *data = NULL; + return -1; + } - if (get_file_size(vm_history) == (int)vm->history_size[sid]) + if (size == vm->history_size[sid]) return 0; - if (*data) - free(*data); - ret = read_full_binary_file(vm_history, &size, data); - if (ret) { - LOGE("read (%s) with error (%s)\n", vm_history, - strerror(errno)); - *data = NULL; - return ret; - } - ret = strcnt(*data, '\n'); - if (ret > VM_WARNING_LINES) { - LOGW("File too large, (%d) lines in (%s)\n", - ret, vm_history); - } + if (ret > VM_WARNING_LINES) + LOGW("File too large, (%d) lines in (%s) of (%s)\n", + ret, android_histpath, vm->name); vm->history_size[sid] = size; - return size; + return 0; } static void sync_lines_stage1(const struct sender_t *sender, const void *data[]) @@ -269,9 +272,6 @@ static void sync_lines_stage1(const struct sender_t *sender, const void *data[]) if (!vm) continue; - if (!vm->online) - continue; - if (vm->last_synced_line_key[sid][0]) { start = strstr(data[id], vm->last_synced_line_key[sid]); @@ -358,9 +358,6 @@ static void sync_lines_stage2(const struct sender_t *sender, const void *data[], if (!vm) continue; - if (!vm->online) - continue; - if (strcmp(vm->name, vm_name)) continue; @@ -416,9 +413,6 @@ static void get_last_line_synced(const struct sender_t *sender) if (!vm) continue; - if (!vm->online) - continue; - /* generally only exec for each vm once */ if (vm->last_synced_line_key[sid][0]) continue; @@ -501,58 +495,6 @@ static char *setup_loop_dev(void) return loop_dev; } -static int ping_vm_fs(char *loop_dev) -{ - int id; - int res; - int count = 0; - struct vm_t *vm; - struct mm_file_t *vm_hist; - char vm_history[PATH_MAX]; - char cmd[512]; - const char prefix[] = "#V1.0 CURRENTUPTIME"; - - /* ensure history_event in uos available */ - for_each_vm(id, vm, conf) { - if (!vm) - continue; - - snprintf(vm_history, sizeof(vm_history), "/tmp/%s_%s", - "vm_hist", vm->name); - snprintf(cmd, sizeof(cmd), - "dump logs/history_event %s", vm_history); - - res = remove(vm_history); - if (res == -1 && errno != ENOENT) - LOGE("remove %s failed\n", vm_history); - - res = debugfs_cmd(loop_dev, cmd, NULL); - if (res) { - vm->online = 0; - continue; - } - - vm_hist = mmap_file(vm_history); - if (vm_hist == NULL) { - vm->online = 0; - LOGE("%s(%s) unavailable\n", vm->name, vm_history); - continue; - } - - if (vm_hist->size && - !strncmp(vm_hist->begin, prefix, strlen(prefix))) { - vm->online = 1; - count++; - } else { - vm->online = 0; - LOGE("%s(%s) unavailable\n", vm->name, vm_history); - } - - unmap_file(vm_hist); - } - return count; -} - /* This function searches all android vms' new events and call the fn for * each event. * @@ -562,10 +504,10 @@ static int ping_vm_fs(char *loop_dev) void refresh_vm_history(const struct sender_t *sender, int (*fn)(const char*, const struct vm_t *)) { - int ret; + int res; int id; struct vm_t *vm; - static void *data[VM_MAX]; + void *data[VM_MAX]; if (!loop_dev) { loop_dev = setup_loop_dev(); @@ -574,24 +516,31 @@ void refresh_vm_history(const struct sender_t *sender, LOGI("setup loop dev successful\n"); } - if (sender_id(sender) == 0) { - ret = ping_vm_fs(loop_dev); - if (!ret) - return; - } - get_last_line_synced(sender); for_each_vm(id, vm, conf) { if (!vm) continue; - if (!vm->online) + data[id] = 0; + res = e2fs_open(loop_dev, &vm->datafs); + if (res == -1) continue; - get_vm_history(vm, sender, &data[id]); + get_vm_history(vm, sender, (void *)&vm->history_data); + data[id] = vm->history_data; } sync_lines_stage2(sender, (const void **)data, fn); sync_lines_stage1(sender, (const void **)data); + for_each_vm(id, vm, conf) { + if (!vm) + continue; + + e2fs_close(vm->datafs); + + if (data[id]) + free(data[id]); + } + } diff --git a/tools/acrn-crashlog/acrnprobe/crash_reclassify.c b/tools/acrn-crashlog/acrnprobe/crash_reclassify.c index a966f2b4d..8c8aa8dbe 100644 --- a/tools/acrn-crashlog/acrnprobe/crash_reclassify.c +++ b/tools/acrn-crashlog/acrnprobe/crash_reclassify.c @@ -238,6 +238,8 @@ static struct crash_t *crash_find_matched_child(const struct crash_t *crash, trfiles[i], strerror(errno)); continue; } + if (!size) + continue; if (crash_match_content(child, content)) { free(content); matched_child = child; @@ -316,6 +318,8 @@ static struct crash_t *crash_reclassify_by_content(const struct crash_t *rcrash, trfiles[count - 1], strerror(errno)); goto free_files; } + if (!size) + goto free_files; res = get_data(content, ret_crash, data0, data1, data2); if (res < 0) { diff --git a/tools/acrn-crashlog/acrnprobe/include/load_conf.h b/tools/acrn-crashlog/acrnprobe/include/load_conf.h index b1d28f3e5..f353e6a4a 100644 --- a/tools/acrn-crashlog/acrnprobe/include/load_conf.h +++ b/tools/acrn-crashlog/acrnprobe/include/load_conf.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "event_queue.h" #define CONTENT_MAX 10 @@ -34,8 +35,9 @@ struct vm_t { char *interval; char *syncevent[VM_EVENT_TYPE_MAX]; - int online; + ext2_filsys datafs; unsigned long history_size[SENDER_MAX]; + char *history_data; char last_synced_line_key[SENDER_MAX][SHA_DIGEST_LENGTH + 1]; }; diff --git a/tools/acrn-crashlog/acrnprobe/probeutils.c b/tools/acrn-crashlog/acrnprobe/probeutils.c index 5710973f4..3f0ffedae 100644 --- a/tools/acrn-crashlog/acrnprobe/probeutils.c +++ b/tools/acrn-crashlog/acrnprobe/probeutils.c @@ -469,14 +469,14 @@ int is_boot_id_changed(void) return result; res = read_file(BOOTID_NODE, &size, &boot_id); - if (res == -1) + if (res == -1 || !size) 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) + if (res == -1 || !size) goto out; if (!strcmp((char *)logged_boot_id, (char *)boot_id)) diff --git a/tools/acrn-crashlog/acrnprobe/property.c b/tools/acrn-crashlog/acrnprobe/property.c index d83284295..27224dd2c 100644 --- a/tools/acrn-crashlog/acrnprobe/property.c +++ b/tools/acrn-crashlog/acrnprobe/property.c @@ -86,6 +86,7 @@ static int get_buildversion(struct sender_t *sender) ret = file_read_string(logbuildid, lastbuild, VERSION_SIZE); if (ret == -ENOENT || + !ret || (ret > 0 && strcmp(currentbuild, lastbuild))) { /* build changed or file not found, overwrite it */ ret = overwrite_file(logbuildid, gbuildversion); @@ -97,7 +98,7 @@ static int get_buildversion(struct sender_t *sender) sender->sw_updated = 1; ret = 0; - } else if (ret <= 0) { + } else if (ret < 0) { LOGE("Cannot read %s, error (%s)\n", logbuildid, strerror(errno)); } else { diff --git a/tools/acrn-crashlog/acrnprobe/sender.c b/tools/acrn-crashlog/acrnprobe/sender.c index c18a4f7d2..2e064764d 100644 --- a/tools/acrn-crashlog/acrnprobe/sender.c +++ b/tools/acrn-crashlog/acrnprobe/sender.c @@ -23,6 +23,7 @@ #include "property.h" #include "startupreason.h" #include "log_sys.h" +#include "loop.h" #ifdef HAVE_TELEMETRICS_CLIENT #include "telemetry.h" @@ -899,10 +900,10 @@ static int crashlog_new_vmevent(const char *line_to_sync, char *vmlogpath = NULL; char *key; char *log; - char *cmd; int ret = VMEVT_HANDLED; int res; int quota; + int cnt; char *dir; /* VM events in history_event like this: @@ -951,35 +952,23 @@ static int crashlog_new_vmevent(const char *line_to_sync, */ log = strstr(rest, "/logs/"); if (log) { - res = asprintf(&vmlogpath, "%s", log + 1); - if (res < 0) { - LOGE("compute string failed, out of memory\n"); - remove(dir); - ret = VMEVT_DEFER; - goto free_dir; - } - - res = asprintf(&cmd, "rdump %s %s", vmlogpath, dir); - if (res < 0) { - LOGE("compute string failed, out of memory\n"); - free(vmlogpath); - remove(dir); - ret = VMEVT_DEFER; - goto free_dir; - } - - res = debugfs_cmd(loop_dev, cmd, NULL); - if (res) { - LOGE("debugfs cmd %s failed (%d)\n", cmd, res); + vmlogpath = log + 1; + res = e2fs_dump_dir_by_dpath(vm->datafs, vmlogpath, dir, &cnt); + if (res == -1) { + if (cnt) { + LOGE("dump (%s) abort at (%d)\n", vmlogpath, + cnt); + ret = VMEVT_DEFER; + } else { + LOGW("(%s) is missing\n", vmlogpath); + ret = VMEVT_HANDLED; /* missing logdir */ + } res = remove(dir); if (res == -1 && errno != ENOENT) LOGE("remove %s faield (%d)\n", dir, -errno); - ret = VMEVT_DEFER; + goto free_dir; } - - free(cmd); - free(vmlogpath); } generate_crashfile(dir, event, key, type, vm->name, diff --git a/tools/acrn-crashlog/acrnprobe/startupreason.c b/tools/acrn-crashlog/acrnprobe/startupreason.c index 93babfae0..9c29b2a62 100644 --- a/tools/acrn-crashlog/acrnprobe/startupreason.c +++ b/tools/acrn-crashlog/acrnprobe/startupreason.c @@ -44,6 +44,10 @@ static int get_cmdline_bootreason(char *bootreason, const size_t limit) CURRENT_KERNEL_CMDLINE, strerror(errno)); return -1; } + if (!size) { + LOGW("empty file (%s)\n", CURRENT_KERNEL_CMDLINE); + return 0; + } start = strstr(cmdline, key); if (!start) { diff --git a/tools/acrn-crashlog/common/cmdutils.c b/tools/acrn-crashlog/common/cmdutils.c index d2b62480f..29539c443 100644 --- a/tools/acrn-crashlog/common/cmdutils.c +++ b/tools/acrn-crashlog/common/cmdutils.c @@ -103,15 +103,6 @@ int execv_out2file(char * const argv[], const char *outfile) return -1; } -int debugfs_cmd(const char *loop_dev, const char *cmd, const char *outfile) -{ - const char *argv[5] = {"debugfs", "-R", NULL, NULL, 0}; - - argv[2] = cmd; - argv[3] = loop_dev; - return execv_out2file((char * const *)argv, outfile); -} - /** * Execute a command described in format string, and redirect the output * to specified file. The file will be created/truncated if it diff --git a/tools/acrn-crashlog/common/include/cmdutils.h b/tools/acrn-crashlog/common/include/cmdutils.h index 682568cb5..fe1898916 100644 --- a/tools/acrn-crashlog/common/include/cmdutils.h +++ b/tools/acrn-crashlog/common/include/cmdutils.h @@ -4,6 +4,5 @@ */ int execv_out2file(char * const argv[], const char *outfile); -int debugfs_cmd(const char *loop_dev, const char *cmd, const char *outfile); int exec_out2file(const char *outfile, const char *fmt, ...); char *exec_out2mem(const char *fmt, ...);