-
Notifications
You must be signed in to change notification settings - Fork 380
sys/log, fs/fcb: Add support for trailers per entry in logs for fcb #3400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,6 +77,46 @@ struct log_storage_info { | |
| }; | ||
| #endif | ||
|
|
||
| #if MYNEWT_VAL(LOG_FLAGS_TRAILER) | ||
|
|
||
| #define LOG_TRAILER_LEN_SIZE 2 | ||
|
|
||
| /** @typedef log_trailer_free_func_t | ||
| * @brief Callback that frees the trailer buffer, to be called by user of the | ||
| * library once append returns, either successfully or unsuccessfully | ||
| * | ||
| * @param log The log the trailer is being appended to | ||
| * @param om mbuf pointer to be freed | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success, non-zero on failure | ||
| */ | ||
| typedef int log_trailer_free_func_t(struct log *log, struct os_mbuf *om, void *arg); | ||
|
|
||
| /** @typedef log_trailer_get_data_func_t | ||
| * @brief Callback that is executed each time the corresponding log entry is | ||
| * appended to | ||
| * | ||
| * @param log The log the trailer needs to be appended to | ||
| * @param om mbuf pointer to be set to mbuf which contains | ||
| * trailer data | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success, non-zero on failure | ||
| */ | ||
| typedef int log_trailer_get_data_func_t(struct log *log, struct os_mbuf **om, void *arg); | ||
|
|
||
| /** @typedef log_trailer_reset_data_func_t | ||
| * @brief Callback used to reset trailer data per log | ||
| * | ||
| * @param log The log the trailer is to be read from | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success, non-zero on failure. | ||
| */ | ||
| typedef int log_trailer_reset_data_func_t(struct log *log, void *arg); | ||
| #endif | ||
|
|
||
| typedef int (*log_walk_func_t)(struct log *, struct log_offset *log_offset, | ||
| const void *dptr, uint16_t len); | ||
|
|
||
|
|
@@ -99,6 +139,7 @@ typedef int (*lh_append_mbuf_body_func_t)(struct log *log, | |
| typedef int (*lh_walk_func_t)(struct log *, | ||
| log_walk_func_t walk_func, struct log_offset *log_offset); | ||
| typedef int (*lh_flush_func_t)(struct log *); | ||
| typedef uint16_t (*lh_read_entry_len_func_t)(struct log *log, const void *dptr); | ||
| #if MYNEWT_VAL(LOG_STORAGE_INFO) | ||
| typedef int (*lh_storage_info_func_t)(struct log *, struct log_storage_info *); | ||
| #endif | ||
|
|
@@ -118,6 +159,7 @@ struct log_handler { | |
| lh_walk_func_t log_walk; | ||
| lh_walk_func_t log_walk_sector; | ||
| lh_flush_func_t log_flush; | ||
| lh_read_entry_len_func_t log_read_entry_len; | ||
| #if MYNEWT_VAL(LOG_STORAGE_INFO) | ||
| lh_storage_info_func_t log_storage_info; | ||
| #endif | ||
|
|
@@ -131,8 +173,9 @@ struct log_handler { | |
| /* Image hash length to be looged */ | ||
| #define LOG_IMG_HASHLEN 4 | ||
|
|
||
| /* Flags used to indicate type of data in reserved payload*/ | ||
| /* Flags used to indicate type of data in reserved payload */ | ||
| #define LOG_FLAGS_IMG_HASH (1 << 0) | ||
| #define LOG_FLAGS_TRAILER (1 << 1) | ||
|
|
||
| #if MYNEWT_VAL(LOG_VERSION) == 3 | ||
| struct log_entry_hdr { | ||
|
|
@@ -204,6 +247,20 @@ STATS_SECT_END | |
| #define LOG_STATS_INCN(log, name, cnt) | ||
| #endif | ||
|
|
||
| #if MYNEWT_VAL(LOG_FLAGS_TRAILER) | ||
| /* Trailer support callbacks */ | ||
| struct log_trailer_handler { | ||
| /* Frees the trailer buffer */ | ||
| log_trailer_free_func_t *lth_trailer_free; | ||
| /* Trailer append callback used to append trailer to the log entry */ | ||
| log_trailer_get_data_func_t *lth_trailer_get_data; | ||
| /* Trailer reset data callback used to reset the trailer data | ||
| * per log which is defined by the application registering these callbacks | ||
| */ | ||
| log_trailer_reset_data_func_t *lth_trailer_reset_data; | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think anyone can figure out how to use these callbacks. What is the difference between and so on...
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think what you have in mind in this context is the "user data" that was supposed to be provided when registering callbacks. In that context, some kind of flush callback probably would make sense, but there's no "user data" in this PR so not sure what you want to reset.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, we do need to flush the data. So, do you have an alternate approach in mind ? |
||
| #endif | ||
|
|
||
| struct log { | ||
| const char *l_name; | ||
| const struct log_handler *l_log; | ||
|
|
@@ -219,6 +276,23 @@ struct log { | |
| #if MYNEWT_VAL(LOG_STATS) | ||
| STATS_SECT_DECL(logs) l_stats; | ||
| #endif | ||
| #if MYNEWT_VAL(LOG_INIT_CB) | ||
| /* Custom log init callback to be called by the last hdr | ||
| * read function to read custom data from log entries | ||
| * at init | ||
| */ | ||
| log_walk_func_t l_init_cb; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make this also a syscfg and disabled by default
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| #endif | ||
|
|
||
| #if MYNEWT_VAL(LOG_FLAGS_TRAILER) | ||
| /* Log trailer support */ | ||
| /* Void argument for callbacks registeration */ | ||
| void *l_tr_arg; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this argument shall be passed to all callbacks, otherwise it doesn't make any sense
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, it is part of the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the whole point of user data for callbacks is that it's passed as an argument to each callback. application code (e.g. callbacks) should not access members of log structure directly.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| /* Trailer mbuf */ | ||
| struct os_mbuf *l_tr_om; | ||
| /* Trailer handler with callbacks */ | ||
| struct log_trailer_handler *l_th; | ||
| #endif | ||
| }; | ||
|
|
||
| /* Log system level functions (for all logs.) */ | ||
|
|
@@ -514,6 +588,121 @@ void log_printf(struct log *log, uint8_t module, uint8_t level, | |
| int log_read(struct log *log, const void *dptr, void *buf, uint16_t off, | ||
| uint16_t len); | ||
|
|
||
| #if MYNEWT_VAL(LOG_INIT_CB) | ||
| /** | ||
| * Reads entry length from the specified log. | ||
| * | ||
| * @return The number of bytes of entry length; 0 on failure. | ||
| */ | ||
| uint16_t | ||
| log_read_entry_len(struct log *log, const void *dptr); | ||
|
|
||
| #if MYNEWT_VAL(LOG_FLAGS_TRAILER) | ||
|
|
||
| /** | ||
| * @brief Read log trailer of a specific entry | ||
| * | ||
| * @param log The log to read trailer data from | ||
| * @param dptr Data pointer to the log entry | ||
| * @param buf Pointer to the buffer to read the trailer into | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| uint16_t | ||
| log_read_trailer(struct log *log, const void *dptr, uint8_t *buf); | ||
|
|
||
| /**Add commentMore actions | ||
| * @brief Returns trailer data in an mbuf specified by the caller | ||
| * | ||
| * @param log The log to append to | ||
| * @param om mbuf pointer to be set to buffer which contains | ||
| * trailer data | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| static inline int | ||
| log_trailer_get_data(struct log *log, struct os_mbuf **om, void *arg) | ||
| { | ||
| if (log->l_th && log->l_th->lth_trailer_get_data) { | ||
| return log->l_th->lth_trailer_get_data(log, om, arg); | ||
| } | ||
| return SYS_ENOTSUP; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Callback that frees the trailer buffer, to be called by user of the library | ||
| * once append returns, either successfully or unsuccessfully | ||
| * | ||
| * @param log The log the trailer is being appended to | ||
| * @param om mbuf pointer to be freed | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| static inline int | ||
| log_trailer_free(struct log *log, struct os_mbuf *om, void *arg) | ||
| { | ||
| if (log->l_th && log->l_th->lth_trailer_free) { | ||
| return log->l_th->lth_trailer_free(log, om, arg); | ||
| } | ||
| return SYS_ENOTSUP; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Resets the trailer data in the log, calling user callback | ||
| * | ||
| * @param log The log to reset. | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| static inline int | ||
| log_trailer_reset_data(struct log *log, void *arg) | ||
| { | ||
| if (log->l_th && log->l_th->lth_trailer_reset_data) { | ||
| return log->l_th->lth_trailer_reset_data(log, arg); | ||
| } | ||
| return SYS_ENOTSUP; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Register trailer callbacks | ||
| * | ||
| * @param log The log to read from. | ||
| * @param lth The trailer handler to register. | ||
| * @param arg Argument to be passed to the trailer handler | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| static inline void | ||
| log_trailer_cbs_register(struct log *log, struct log_trailer_handler *lth, | ||
| void *arg) | ||
| { | ||
| if (!lth || !log) { | ||
| return; | ||
| } | ||
|
|
||
| log->l_th = lth; | ||
| log->l_tr_arg = arg; | ||
| } | ||
| #endif | ||
|
|
||
| /** | ||
| * @brief Register Log init callback to be called by log_read_last_hdr | ||
| * while reading the last log entry at init | ||
| * | ||
| * @param log The log to register. | ||
| * @param cb The callback to associate with the log. | ||
| * | ||
| */ | ||
| static inline void | ||
| log_register_init_cb(struct log *log, log_walk_func_t cb) | ||
| { | ||
| log->l_init_cb = cb; | ||
| } | ||
| #endif | ||
|
|
||
| /** | ||
| * @brief Reads a single log entry header. | ||
| * | ||
|
|
@@ -531,7 +720,7 @@ int log_read_hdr(struct log *log, const void *dptr, struct log_entry_hdr *hdr); | |
| * @brief Reads the header length | ||
| * | ||
| * @param hdr Ptr to the header | ||
| * | ||
| * | ||
| * @return Length of the header | ||
| */ | ||
| uint16_t | ||
|
|
@@ -738,6 +927,21 @@ int log_set_watermark(struct log *log, uint32_t index); | |
| int | ||
| log_fill_current_img_hash(struct log_entry_hdr *hdr); | ||
|
|
||
| /** | ||
| * @brief Reads the final log entry's header and processes trailer if the flag | ||
| * indicates so from the specified log only if the log supports trailers | ||
| * and mynewt val LOG_FLAGS_TRAILER is 1 | ||
| * | ||
| * @param log The log to read from. | ||
| * @param out_hdr On success, the last entry header gets written | ||
| * here. | ||
| * @param trailer_exists Pointer to a boolean | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| int log_read_last_hdr_trailer(struct log *log, struct log_entry_hdr *out_hdr, | ||
| bool *trailer_exists); | ||
|
|
||
| /* Handler exports */ | ||
| #if MYNEWT_VAL(LOG_CONSOLE) | ||
| extern const struct log_handler log_console_handler; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in some other comment, there's no "user data" in the callback registration API.