mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-05 05:32:05 +00:00
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:
parent
ea8cb410c5
commit
a4aed4535a
@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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, ...);
|
||||
|
Loading…
Reference in New Issue
Block a user