tools: acrn-crashlog: replace debugfs with api

Replace debugfs with api in loop.c.
There is no functional change.

Signed-off-by: Liu, Xinwu <xinwu.liu@intel.com>
Acked-by: Chen Gang <gang.c.chen@intel.com>
This commit is contained in:
Liu, Xinwu 2018-07-18 12:47:19 +08:00 committed by lijinxia
parent ea8cb410c5
commit a4aed4535a
9 changed files with 69 additions and 130 deletions

View File

@ -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]);
}
}

View File

@ -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) {

View File

@ -9,6 +9,7 @@
#include <stdio.h>
#include <sys/queue.h>
#include <openssl/sha.h>
#include <ext2fs/ext2fs.h>
#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];
};

View File

@ -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))

View File

@ -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 {

View File

@ -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,

View File

@ -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) {

View File

@ -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

View File

@ -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, ...);