mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 04:02:05 +00:00
tools: acrn-crashlog: refine the log storage
1. remove watching TOMBSTONE in AaaG. 2. add a configurable parameter "foldersize" in MB, sender will drop all events when the storaged log size exceeds this parameter. Tracked-On:#1024 Signed-off-by: Liu, Xinwu <xinwu.liu@intel.com> Reviewed-by: Chen Gang <gang.c.chen@intel.com> Acked-by: Zhang Di <di.zhang@intel.com>
This commit is contained in:
parent
06efc58a7e
commit
3d1332f392
@ -124,6 +124,38 @@ static void watchdog_init(int timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_folder_space(struct sender_t *sender)
|
||||||
|
{
|
||||||
|
size_t dsize;
|
||||||
|
int cfg_size;
|
||||||
|
|
||||||
|
if (dir_size(sender->outdir, sender->outdir_len, &dsize) == -1) {
|
||||||
|
LOGE("failed to check outdir size, drop ev\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_atoi(sender->foldersize, sender->foldersize_len,
|
||||||
|
&cfg_size) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (dsize/MB >= (size_t)cfg_size) {
|
||||||
|
if (sender->suspending)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
LOGW("suspend (%s), since (%s: %ldM) meets quota (%dM)\n",
|
||||||
|
sender->name, sender->outdir, dsize/MB, cfg_size);
|
||||||
|
sender->suspending = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sender->suspending)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LOGW("resume (%s), %s: left space %ldM for storage\n",
|
||||||
|
sender->name, sender->outdir, cfg_size - dsize/MB);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process each event in event queue.
|
* Process each event in event queue.
|
||||||
* Note that currently event handler is single threaded.
|
* Note that currently event handler is single threaded.
|
||||||
@ -157,6 +189,9 @@ static void *event_handle(void *unused __attribute__((unused)))
|
|||||||
if (!sender)
|
if (!sender)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (check_folder_space(sender) == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (sender->send)
|
if (sender->send)
|
||||||
sender->send(e);
|
sender->send(e);
|
||||||
}
|
}
|
||||||
|
@ -123,11 +123,14 @@ struct sender_t {
|
|||||||
size_t maxlines_len;
|
size_t maxlines_len;
|
||||||
const char *spacequota;
|
const char *spacequota;
|
||||||
size_t spacequota_len;
|
size_t spacequota_len;
|
||||||
|
const char *foldersize;
|
||||||
|
size_t foldersize_len;
|
||||||
struct uptime_t *uptime;
|
struct uptime_t *uptime;
|
||||||
|
|
||||||
void (*send)(struct event_t *);
|
void (*send)(struct event_t *);
|
||||||
char *log_vmrecordid;
|
char *log_vmrecordid;
|
||||||
int sw_updated; /* each sender has their own record */
|
int sw_updated; /* each sender has their own record */
|
||||||
|
int suspending; /* drop all events while suspending */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct conf_t {
|
struct conf_t {
|
||||||
|
@ -36,6 +36,7 @@ static void print(void)
|
|||||||
print_id_item(maxcrashdirs, sender, id);
|
print_id_item(maxcrashdirs, sender, id);
|
||||||
print_id_item(maxlines, sender, id);
|
print_id_item(maxlines, sender, id);
|
||||||
print_id_item(spacequota, sender, id);
|
print_id_item(spacequota, sender, id);
|
||||||
|
print_id_item(foldersize, sender, id);
|
||||||
|
|
||||||
if (sender->uptime) {
|
if (sender->uptime) {
|
||||||
print_id_item(uptime->name, sender, id);
|
print_id_item(uptime->name, sender, id);
|
||||||
@ -678,6 +679,8 @@ static int parse_sender(xmlNodePtr cur, struct sender_t *sender)
|
|||||||
res = load_cur_content(cur, sender, maxlines);
|
res = load_cur_content(cur, sender, maxlines);
|
||||||
else if (name_is(cur, "spacequota"))
|
else if (name_is(cur, "spacequota"))
|
||||||
res = load_cur_content(cur, sender, spacequota);
|
res = load_cur_content(cur, sender, spacequota);
|
||||||
|
else if (name_is(cur, "foldersize"))
|
||||||
|
res = load_cur_content(cur, sender, foldersize);
|
||||||
else if (name_is(cur, "uptime"))
|
else if (name_is(cur, "uptime"))
|
||||||
res = parse_uptime(cur, sender);
|
res = parse_uptime(cur, sender);
|
||||||
|
|
||||||
|
@ -906,36 +906,33 @@ free_list:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#define DIR_SUCCESS (0)
|
||||||
* Find target file in specified dir.
|
#define DIR_ABORT (-1)
|
||||||
*
|
#define DIR_ERROR (-2)
|
||||||
* @param dir Where to start search.
|
static int dir_recursive(const char *path, size_t plen, int depth,
|
||||||
* @param dlen Length of dir.
|
int fn(const char *pdir, struct dirent *, void *arg),
|
||||||
* @param target_file Target file to search.
|
void *arg)
|
||||||
* @param tflen The length of target_file.
|
|
||||||
* @param depth Descend at most depth of directories below the starting dir.
|
|
||||||
* @param path[out] Searched file path in given dir.
|
|
||||||
* @param limit The number of files uplayer want to get.
|
|
||||||
*
|
|
||||||
* @return the count of searched files on success, or -1 on error.
|
|
||||||
*/
|
|
||||||
int find_file(const char *dir, size_t dlen, const char *target_file,
|
|
||||||
size_t tflen, int depth, char *path[], int limit)
|
|
||||||
{
|
{
|
||||||
int wdepth = 0;
|
int wdepth = 0;
|
||||||
int found = 0;
|
int ret = DIR_SUCCESS;
|
||||||
char wdir[PATH_MAX];
|
char wdir[PATH_MAX];
|
||||||
DIR **dp;
|
DIR **dp;
|
||||||
|
|
||||||
if (!dir || !target_file || !tflen || !path || limit <= 0)
|
if (!path)
|
||||||
return -1;
|
return DIR_ERROR;
|
||||||
if (dlen >= PATH_MAX)
|
if (plen >= PATH_MAX)
|
||||||
return -1;
|
return DIR_ERROR;
|
||||||
*(char *)mempcpy(wdir, dir, dlen) = '\0';
|
if (depth < -1)
|
||||||
|
return DIR_ERROR;
|
||||||
|
|
||||||
|
if (depth == -1)
|
||||||
|
depth = 1024;
|
||||||
|
|
||||||
|
*(char *)mempcpy(wdir, path, plen) = '\0';
|
||||||
dp = calloc(depth + 1, sizeof(DIR *));
|
dp = calloc(depth + 1, sizeof(DIR *));
|
||||||
if (!dp) {
|
if (!dp) {
|
||||||
LOGE("out of memory\n");
|
LOGE("out of memory\n");
|
||||||
return -1;
|
return DIR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (wdepth >= 0) {
|
while (wdepth >= 0) {
|
||||||
@ -947,6 +944,7 @@ int find_file(const char *dir, size_t dlen, const char *target_file,
|
|||||||
if (!dp[wdepth]) {
|
if (!dp[wdepth]) {
|
||||||
LOGE("failed to opendir (%s), error (%s)\n",
|
LOGE("failed to opendir (%s), error (%s)\n",
|
||||||
wdir, strerror(errno));
|
wdir, strerror(errno));
|
||||||
|
ret = DIR_ERROR;
|
||||||
goto fail_open;
|
goto fail_open;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -956,15 +954,11 @@ int find_file(const char *dir, size_t dlen, const char *target_file,
|
|||||||
!strcmp(dirp->d_name, ".."))
|
!strcmp(dirp->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strcmp(dirp->d_name, target_file)) {
|
ret = fn(wdir, dirp, arg);
|
||||||
if (asprintf(&path[found], "%s/%s", wdir,
|
if (ret == DIR_ABORT)
|
||||||
dirp->d_name) == -1) {
|
|
||||||
LOGE("out of memory\n");
|
|
||||||
goto fail_read;
|
|
||||||
}
|
|
||||||
if (++found == limit)
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
if (ret == DIR_ERROR)
|
||||||
|
goto fail_read;
|
||||||
|
|
||||||
if (dirp->d_type == DT_DIR && wdepth < depth) {
|
if (dirp->d_type == DT_DIR && wdepth < depth) {
|
||||||
/* search in subdir */
|
/* search in subdir */
|
||||||
@ -990,6 +984,7 @@ int find_file(const char *dir, size_t dlen, const char *target_file,
|
|||||||
} else {
|
} else {
|
||||||
LOGE("failed to readdir, (%s)\n",
|
LOGE("failed to readdir, (%s)\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
ret = DIR_ERROR;
|
||||||
goto fail_read;
|
goto fail_read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,7 +993,7 @@ end:
|
|||||||
while (wdepth >= 0)
|
while (wdepth >= 0)
|
||||||
closedir(dp[wdepth--]);
|
closedir(dp[wdepth--]);
|
||||||
free(dp);
|
free(dp);
|
||||||
return found;
|
return ret;
|
||||||
|
|
||||||
fail_read:
|
fail_read:
|
||||||
LOGE("failed to search in dir %s\n", wdir);
|
LOGE("failed to search in dir %s\n", wdir);
|
||||||
@ -1006,10 +1001,110 @@ fail_read:
|
|||||||
fail_open:
|
fail_open:
|
||||||
while (wdepth)
|
while (wdepth)
|
||||||
closedir(dp[--wdepth]);
|
closedir(dp[--wdepth]);
|
||||||
while (found)
|
|
||||||
free(path[--found]);
|
|
||||||
free(dp);
|
free(dp);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct find_file_data {
|
||||||
|
const char *target;
|
||||||
|
size_t tlen;
|
||||||
|
int limit;
|
||||||
|
char **path;
|
||||||
|
int found;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _get_file_path(const char *pdir, struct dirent *dirp, void *arg)
|
||||||
|
{
|
||||||
|
struct find_file_data *d = (struct find_file_data *)arg;
|
||||||
|
|
||||||
|
if (!strcmp(dirp->d_name, d->target)) {
|
||||||
|
if (asprintf(&d->path[d->found], "%s/%s", pdir,
|
||||||
|
dirp->d_name) == -1) {
|
||||||
|
LOGE("out of memory\n");
|
||||||
|
return DIR_ERROR;
|
||||||
|
}
|
||||||
|
if (++(d->found) == d->limit)
|
||||||
|
return DIR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DIR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find target file in specified dir.
|
||||||
|
*
|
||||||
|
* @param dir Where to start search.
|
||||||
|
* @param dlen Length of dir.
|
||||||
|
* @param target_file Target file to search.
|
||||||
|
* @param tflen The length of target_file.
|
||||||
|
* @param depth Descend at most depth of directories below the starting dir.
|
||||||
|
* @param path[out] Searched file path in given dir.
|
||||||
|
* @param limit The number of files uplayer want to get.
|
||||||
|
*
|
||||||
|
* @return the count of searched files on success, or -1 on error.
|
||||||
|
*/
|
||||||
|
int find_file(const char *dir, size_t dlen, const char *target_file,
|
||||||
|
size_t tflen, int depth, char *path[], int limit)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
struct find_file_data data = {
|
||||||
|
.target = target_file,
|
||||||
|
.tlen = tflen,
|
||||||
|
.limit = limit,
|
||||||
|
.path = path,
|
||||||
|
.found = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!dir || !target_file || !tflen || !path || limit <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
res = dir_recursive(dir, dlen, depth, _get_file_path, (void *)&data);
|
||||||
|
if (res == DIR_ABORT || res == DIR_SUCCESS)
|
||||||
|
return data.found;
|
||||||
|
|
||||||
|
if (res == DIR_ERROR) {
|
||||||
|
while (data.found)
|
||||||
|
free(path[--data.found]);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _count_file_size(const char *pdir, struct dirent *dirp, void *arg)
|
||||||
|
{
|
||||||
|
char file[PATH_MAX];
|
||||||
|
int res;
|
||||||
|
ssize_t fsize;
|
||||||
|
|
||||||
|
if (dirp->d_type != DT_REG && dirp->d_type != DT_DIR)
|
||||||
|
return DIR_SUCCESS;
|
||||||
|
|
||||||
|
res = snprintf(file, sizeof(file), "%s/%s", pdir, dirp->d_name);
|
||||||
|
if (s_not_expect(res, sizeof(file)))
|
||||||
|
return DIR_ERROR;
|
||||||
|
|
||||||
|
fsize = get_file_size(file);
|
||||||
|
if (fsize < 0)
|
||||||
|
return DIR_ERROR;
|
||||||
|
|
||||||
|
*(size_t *)arg += fsize;
|
||||||
|
|
||||||
|
return DIR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dir_size(const char *dir, size_t dlen, size_t *size)
|
||||||
|
{
|
||||||
|
if (!dir || !dlen || !size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
if (dir_recursive(dir, dlen, -1, _count_file_size,
|
||||||
|
(void *)size) != DIR_SUCCESS) {
|
||||||
|
LOGE("failed to recursive dir (%s)\n", dir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_file(const char *path, unsigned long *size, void **data)
|
int read_file(const char *path, unsigned long *size, void **data)
|
||||||
|
@ -40,7 +40,7 @@ struct mm_file_t {
|
|||||||
char *path;
|
char *path;
|
||||||
int fd;
|
int fd;
|
||||||
char *begin;
|
char *begin;
|
||||||
int size;
|
ssize_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ac_filter_data {
|
struct ac_filter_data {
|
||||||
@ -62,7 +62,7 @@ static inline int directory_exists(const char *path)
|
|||||||
return (stat(path, &info) == 0 && S_ISDIR(info.st_mode));
|
return (stat(path, &info) == 0 && S_ISDIR(info.st_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int get_file_size(const char *filepath)
|
static inline ssize_t get_file_size(const char *filepath)
|
||||||
{
|
{
|
||||||
struct stat info;
|
struct stat info;
|
||||||
|
|
||||||
@ -114,6 +114,7 @@ int dir_contains(const char *dir, const char *filename, size_t flen, int exact);
|
|||||||
int lsdir(const char *dir, char *fullname[], int limit);
|
int lsdir(const char *dir, char *fullname[], int limit);
|
||||||
int find_file(const char *dir, size_t dlen, const char *target_file,
|
int find_file(const char *dir, size_t dlen, const char *target_file,
|
||||||
size_t tflen, int depth, char *path[], int limit);
|
size_t tflen, int depth, char *path[], int limit);
|
||||||
|
int dir_size(const char *dir, size_t dlen, size_t *size);
|
||||||
int read_file(const char *path, unsigned long *size, void **data);
|
int read_file(const char *path, unsigned long *size, void **data);
|
||||||
int is_ac_filefmt(const char *file_fmt);
|
int is_ac_filefmt(const char *file_fmt);
|
||||||
int config_fmt_to_files(const char *file_fmt, char ***out);
|
int config_fmt_to_files(const char *file_fmt, char ***out);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<maxcrashdirs>1000</maxcrashdirs>
|
<maxcrashdirs>1000</maxcrashdirs>
|
||||||
<maxlines>5000</maxlines>
|
<maxlines>5000</maxlines>
|
||||||
<spacequota>90</spacequota>
|
<spacequota>90</spacequota>
|
||||||
|
<foldersize>200</foldersize>
|
||||||
<uptime>
|
<uptime>
|
||||||
<name>UPTIME</name>
|
<name>UPTIME</name>
|
||||||
<frequency>5</frequency>
|
<frequency>5</frequency>
|
||||||
@ -16,6 +17,7 @@
|
|||||||
<sender id="2" enable="true">
|
<sender id="2" enable="true">
|
||||||
<name>telemd</name>
|
<name>telemd</name>
|
||||||
<outdir>/var/log/acrnprobe</outdir>
|
<outdir>/var/log/acrnprobe</outdir>
|
||||||
|
<foldersize>10</foldersize>
|
||||||
<uptime>
|
<uptime>
|
||||||
<name>UPTIME</name>
|
<name>UPTIME</name>
|
||||||
<frequency>5</frequency>
|
<frequency>5</frequency>
|
||||||
@ -56,10 +58,9 @@
|
|||||||
<name>VM1</name>
|
<name>VM1</name>
|
||||||
<channel>polling</channel>
|
<channel>polling</channel>
|
||||||
<interval>60</interval>
|
<interval>60</interval>
|
||||||
<syncevent id="1">CRASH/TOMBSTONE</syncevent>
|
<syncevent id="1">CRASH/UIWDT</syncevent>
|
||||||
<syncevent id="2">CRASH/UIWDT</syncevent>
|
<syncevent id="2">CRASH/IPANIC</syncevent>
|
||||||
<syncevent id="3">CRASH/IPANIC</syncevent>
|
<syncevent id="3">REBOOT</syncevent>
|
||||||
<syncevent id="4">REBOOT</syncevent>
|
|
||||||
</vm>
|
</vm>
|
||||||
</vms>
|
</vms>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user