tools: acrn-crashlog: Limit the log size of kmsg

Dmesg collects too much log when kernel meets log storm.
This patch reads kernel log from "/dev/kmsg" intead of dmesg and limits
the generated log size.

Tracked-On: #1024
Signed-off-by: Liu, Xinwu <xinwu.liu@intel.com>
Reviewed-by: Zhi Jin <zhi.jin@intel.com>
Acked-by: Chen, Gang <gang.c.chen@intel.com>
This commit is contained in:
Liu, Xinwu 2019-01-08 16:22:17 +08:00 committed by acrnsi
parent 156ea70821
commit d5b578fd84
6 changed files with 58 additions and 27 deletions

View File

@ -57,6 +57,8 @@ struct log_t {
size_t path_len; size_t path_len;
const char *lines; const char *lines;
size_t lines_len; size_t lines_len;
const char *sizelimit;
size_t sizelimit_len;
void (*get)(struct log_t *, void *); void (*get)(struct log_t *, void *);
}; };

View File

@ -73,6 +73,7 @@ static void print(void)
print_id_item(type, log, id); print_id_item(type, log, id);
print_id_item(lines, log, id); print_id_item(lines, log, id);
print_id_item(path, log, id); print_id_item(path, log, id);
print_id_item(sizelimit, log, id);
} }
for_each_info(id, info, conf) { for_each_info(id, info, conf) {
@ -466,6 +467,8 @@ static int parse_log(xmlNodePtr cur, struct log_t *log)
res = load_cur_content(cur, log, path); res = load_cur_content(cur, log, path);
else if (name_is(cur, "lines")) else if (name_is(cur, "lines"))
res = load_cur_content(cur, log, lines); res = load_cur_content(cur, log, lines);
else if (name_is(cur, "sizelimit"))
res = load_cur_content(cur, log, sizelimit);
if (res) if (res)
return -1; return -1;

View File

@ -123,9 +123,10 @@ static void get_log_file(const char *despath, const char *srcpath,
get_log_file_complete(despath, srcpath); get_log_file_complete(despath, srcpath);
} }
static void get_log_node(const char *despath, const char *nodepath) static void get_log_node(const char *despath, const char *nodepath,
size_t sizelimit)
{ {
const int res = do_copy_eof(nodepath, despath); const int res = do_copy_limit(nodepath, despath, sizelimit);
if (res < 0) { if (res < 0) {
LOGE("copy (%s) failed, error (%s)\n", nodepath, LOGE("copy (%s) failed, error (%s)\n", nodepath,
@ -156,8 +157,17 @@ static void get_log_by_type(const char *despath, const struct log_t *log,
if (cfg_atoi(log->lines, log->lines_len, &lines) == -1) if (cfg_atoi(log->lines, log->lines_len, &lines) == -1)
return; return;
get_log_file(despath, srcpath, lines); get_log_file(despath, srcpath, lines);
} else if (!strcmp("node", log->type)) } else if (!strcmp("node", log->type)) {
get_log_node(despath, log->path); int size;
if (!log->sizelimit)
size = 0;
else
if (cfg_atoi(log->sizelimit, log->sizelimit_len,
&size) == -1)
return;
get_log_node(despath, log->path, (size_t)(size * 1024 * 1024));
}
else if (!strcmp("cmd", log->type)) else if (!strcmp("cmd", log->type))
get_log_cmd(despath, log->path); get_log_cmd(despath, log->path);
} }

View File

@ -528,45 +528,58 @@ int file_update_int(const char *filename, unsigned int current,
* *
* @param src Path of source file. * @param src Path of source file.
* @param dest Path of destin file. * @param dest Path of destin file.
* @param limitsize Bytes will copy from src at most.
* *
* @return 0 if successful, or a negative value if not. * @return 0 if successful, or -1 if not.
*/ */
int do_copy_eof(const char *src, const char *des) int do_copy_limit(const char *src, const char *des, size_t limitsize)
{ {
char buffer[CPBUFFERSIZE]; char buffer[CPBUFFERSIZE];
int rc = 0; int rc = 0;
int fd1 = -1, fd2 = -1; int fd1;
struct stat info; int fd2;
int r_count, w_count = 0; size_t dsize = 0;
size_t rbsize = CPBUFFERSIZE;
ssize_t r_count;
ssize_t w_count;
if (src == NULL || des == NULL) if (src == NULL || des == NULL)
return -EINVAL; return -1;
if (stat(src, &info) < 0) { fd1 = open(src, O_RDONLY | O_NONBLOCK);
LOGE("can not open file: %s\n", src); if (fd1 < 0) {
return -errno; LOGE("failed to open file: %s, err: %s\n", src,
strerror(errno));
return -1;
} }
fd1 = open(src, O_RDONLY);
if (fd1 < 0)
return -errno;
fd2 = open(des, O_WRONLY | O_CREAT | O_TRUNC, 0660); fd2 = open(des, O_WRONLY | O_CREAT | O_TRUNC, 0660);
if (fd2 < 0) { if (fd2 < 0) {
LOGE("can not open file: %s\n", des); LOGE("failed to open file: %s, err: %s\n", des,
strerror(errno));
close(fd1); close(fd1);
return -errno; return -1;
} }
/* Start copy loop */ /* Start copy loop */
while (1) { while (1) {
if (limitsize > 0) {
if (dsize >= limitsize)
break;
rbsize = MIN(limitsize - dsize, CPBUFFERSIZE);
}
/* Read data from src */ /* Read data from src */
r_count = read(fd1, buffer, CPBUFFERSIZE); r_count = read(fd1, buffer, rbsize);
if (r_count < 0) { if (r_count < 0) {
if (errno == EAGAIN) {
break;
} else {
LOGE("read failed, err:%s\n", strerror(errno)); LOGE("read failed, err:%s\n", strerror(errno));
rc = -1; rc = -1;
break; break;
} }
}
if (r_count == 0) if (r_count == 0)
break; break;
@ -579,11 +592,13 @@ int do_copy_eof(const char *src, const char *des)
break; break;
} }
if (r_count != w_count) { if (r_count != w_count) {
LOGE("write failed, r_count:%d w_count:%d\n", LOGE("write failed, r_count:%zd w_count:%zd\n",
r_count, w_count); r_count, w_count);
rc = -1; rc = -1;
break; break;
} }
dsize += w_count;
} }
if (fd1 >= 0) if (fd1 >= 0)

View File

@ -92,7 +92,7 @@ void file_reset_init(const char *filename);
int file_read_int(const char *filename, unsigned int *pcurrent); int file_read_int(const char *filename, unsigned int *pcurrent);
int file_update_int(const char *filename, unsigned int current, int file_update_int(const char *filename, unsigned int current,
unsigned int max); unsigned int max);
int do_copy_eof(const char *src, const char *des); int do_copy_limit(const char *src, const char *des, size_t limitsize);
int space_available(const char *path, int quota); int space_available(const char *path, int quota);
int count_lines_in_file(const char *filename); int count_lines_in_file(const char *filename);
int read_full_binary_file(const char *path, unsigned long *size, int read_full_binary_file(const char *path, unsigned long *size,

View File

@ -72,8 +72,9 @@
</log> </log>
<log id='2' enable='true'> <log id='2' enable='true'>
<name>kmsg</name> <name>kmsg</name>
<type>cmd</type> <type>node</type>
<path>dmesg</path> <path>/dev/kmsg</path>
<sizelimit>2</sizelimit>
</log> </log>
<log id='3' enable='true'> <log id='3' enable='true'>
<name>cmdline</name> <name>cmdline</name>