Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/zephyr/logging/log_backend_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@
#ifndef ZEPHYR_LOG_BACKEND_FS_H_
#define ZEPHYR_LOG_BACKEND_FS_H_

#include <zephyr/sys/hash_map.h>

struct file_list_item {
sys_snode_t node;
uint32_t bid;
uint64_t ts;
};

const struct log_backend *log_backend_fs_get(void);
uint32_t log_backend_fs_get_boot_id(void);
int log_backend_fs_clear_logs(bool activate);
struct file_list_item *log_backend_fs_flist_get_next(struct file_list_item *item);
int log_backend_fs_flist_get_max_ts(struct sys_hashmap *map);

#endif /* ZEPHYR_LOG_BACKEND_FS_H_ */
73 changes: 67 additions & 6 deletions subsys/logging/backends/log_backend_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,7 @@ struct logfs_msg {
#define MSG_SIZE 4

sys_slist_t file_list = SYS_SLIST_STATIC_INIT(&file_list);

struct file_list_item {
sys_snode_t node;
uint32_t bid;
uint64_t ts;
};
struct k_mutex file_list_lock;

K_MSGQ_DEFINE(log_msgq, sizeof(struct logfs_msg), MSG_SIZE, 1);
K_THREAD_STACK_DEFINE(logfs_queue_stack_area, CONFIG_LOG_BACKEND_FS_STACK_SIZE);
Expand Down Expand Up @@ -156,8 +151,12 @@ static int file_list_add_item(uint32_t boot_id, uint64_t timestamp)
item->bid = boot_id;
item->ts = timestamp;

k_mutex_lock(&file_list_lock, K_FOREVER);

sys_slist_append(&file_list, &item->node);

k_mutex_unlock(&file_list_lock);

return 0;
}

Expand Down Expand Up @@ -197,6 +196,34 @@ static int file_list_update(void)
return cnt;
}

int log_backend_fs_flist_get_max_ts(struct sys_hashmap *map)
{
struct file_list_item *pn;
struct file_list_item *cur = NULL;
uint64_t ts;

k_mutex_lock(&file_list_lock, K_FOREVER);

cur = SYS_SLIST_PEEK_HEAD_CONTAINER(&file_list, cur, node);
if (cur == NULL) {
k_mutex_unlock(&file_list_lock);
return -ENODATA;
}

sys_hashmap_clear(map, NULL, NULL);
sys_hashmap_insert(map, cur->bid, cur->ts, NULL);

SYS_SLIST_FOR_EACH_CONTAINER(&file_list, pn, node) {
if (!sys_hashmap_get(map, pn->bid, &ts) || pn->ts > ts) {
sys_hashmap_insert(map, pn->bid, pn->ts, NULL);
}
}

k_mutex_unlock(&file_list_lock);

return 0;
}

static struct file_list_item *file_list_get_oldest_file(void)
{
struct file_list_item *pn;
Expand All @@ -216,6 +243,34 @@ static struct file_list_item *file_list_get_oldest_file(void)
return cur;
}

struct file_list_item *log_backend_fs_flist_get_next(struct file_list_item *item)
{
struct file_list_item *pn, *next = item;

k_mutex_lock(&file_list_lock, K_FOREVER);

SYS_SLIST_FOR_EACH_CONTAINER(&file_list, pn, node) {
if (pn->bid >= item->bid) {
if ((next == item && (pn->bid > item->bid || pn->ts > item->ts)) ||
(pn->bid < next->bid && pn->bid > item->bid) ||
(pn->bid == next->bid && pn->bid > item->bid && pn->ts < next->ts) ||
(pn->bid == item->bid && pn->bid < next->bid && pn->ts > item->ts) ||
(pn->bid == item->bid && pn->bid == next->bid && pn->ts < next->ts &&
pn->ts > item->ts)) {
next = pn;
}
}
Comment on lines +253 to +262

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand this condition correctly, it can be simplified by checking if pn is newer than item and older than next:

if ((pn->bid > item->bid || (pn->bid == item->bid && pn->ts > item->ts)) &&
    (pn->bid < next->bid || (pn->bid == next->bid && pn->ts < next->ts)))

Regardless, I'd recommend make file_list ordered by bid/ts in file_list_add_item to speed up this search. This should also make implementation of log_backend_fs_flist_get_max_ts simpler.

}

k_mutex_unlock(&file_list_lock);

if (next == item) {
return NULL;
}

return next;
}

#if !defined(CONFIG_LOG_BACKEND_FS_TIME_BASED_ROTATION)
static int check_log_file_exist(int num)
{
Expand Down Expand Up @@ -792,6 +847,12 @@ static void log_backend_fs_init(const struct log_backend *const backend)
K_THREAD_STACK_SIZEOF(logfs_queue_stack_area), THREAD_PRIORITY, &cfg);
k_work_init(&logfs_msg_work, logfs_consumer);

rc = k_mutex_init(&file_list_lock);
if (rc != 0) {
printf("%s: mutex init failed, rc = %d\n", __func__, rc);
return;
}

if (backend_state == BACKEND_FS_NOT_INITIALIZED) {
if (check_log_volume_available()) {
/* will try to re-init later */
Expand Down