From d2200fc25e3ae0c04e349a80b979476ee156d215 Mon Sep 17 00:00:00 2001 From: "Narasimhaiah Suprathik (RBEI/ECF3)" Date: Mon, 7 Dec 2020 16:27:57 +0530 Subject: lib: Add MaxFileSize handling Signed-Off By: Saya Sugiura --- doc/dlt_example_user.md | 12 ++++++-- include/dlt/dlt_types.h | 1 + include/dlt/dlt_user.h.in | 9 ++++++ src/examples/dlt-example-user.c | 19 ++++++++++-- src/lib/dlt_user.c | 64 +++++++++++++++++++++++++++++++++++++---- 5 files changed, 94 insertions(+), 11 deletions(-) diff --git a/doc/dlt_example_user.md b/doc/dlt_example_user.md index d2f9af6..0aa9d0e 100644 --- a/doc/dlt_example_user.md +++ b/doc/dlt_example_user.md @@ -6,7 +6,7 @@ # SYNOPSIS -**dlt-example-user** \[**-h**\] \[**-g**\] \[**-a**\] \[**-k**\] \[**-d** delay\] \[**-f** filename\] \[**-n** count\] \[**-m** mode\] \[**-l** level\] \[**-A** appID\] \[**-C** contextID\] \[**-t** timeout\] \[**-s** size\] message +**dlt-example-user** \[**-h**\] \[**-g**\] \[**-a**\] \[**-k**\] \[**-d** delay\] \[**-f** filename\] \[**-S** filesize\] \[**-n** count\] \[**-m** mode\] \[**-l** level\] \[**-A** appID\] \[**-C** contextID\] \[**-t** timeout\] \[**-s** size\] message # DESCRIPTION @@ -38,6 +38,10 @@ Sends the given message as DLT messages to DLT daemon or prints the raw DLT mess : Use local log file instead of sending to daemon. +-S + +: Set maximum size of local log file (Default: UINT\_MAX). + -n : Number of messages to be generated (Default: 10). @@ -81,6 +85,10 @@ Send 100 DLT messages every second:: dlt-example-user -n 100 -d 1000 HelloWorld +Send "HelloWorld" can log to local file with maximum size 1000 bytes:: + + dlt-example-user -f helloworld.dlt -S 1000 HelloWorld + # EXIT STATUS Non zero is returned in case of failure. @@ -103,4 +111,4 @@ See Github issue: # SEE ALSO -**dlt-daemon(1)** \ No newline at end of file +**dlt-daemon(1)** diff --git a/include/dlt/dlt_types.h b/include/dlt/dlt_types.h index 2880c89..6dd92d2 100644 --- a/include/dlt/dlt_types.h +++ b/include/dlt/dlt_types.h @@ -83,6 +83,7 @@ typedef unsigned int speed_t; */ typedef enum { + DLT_RETURN_FILESZERR = -8, DLT_RETURN_LOGGING_DISABLED = -7, DLT_RETURN_USER_BUFFER_FULL = -6, DLT_RETURN_WRONG_PARAMETER = -5, diff --git a/include/dlt/dlt_user.h.in b/include/dlt/dlt_user.h.in index b4d508d..30eb234 100644 --- a/include/dlt/dlt_user.h.in +++ b/include/dlt/dlt_user.h.in @@ -211,6 +211,7 @@ typedef struct pthread_t dlt_segmented_nwt_handle; /**< thread handle of segmented sending */ #endif int8_t dlt_is_file; /**< Target of logging: 1 to file, 0 to daemon */ + unsigned int filesize_max; /**< Maximum size of existing file in case dlt_is_file=1 */ dlt_ll_ts_type *dlt_ll_ts; /** [MAX_DLT_LL_TS_ENTRIES]; < Internal management struct for all * contexts */ @@ -820,6 +821,14 @@ DltReturnValue dlt_init(); */ DltReturnValue dlt_init_file(const char *name); +/** + * Set maximum file size if lib is configured to write only to file. + * This function has to be called after dlt_init_file(). + * @param filesize maximum file size + * @return Value from DltReturnValue enum + */ +DltReturnValue dlt_set_filesize_max(unsigned int filesize); + /** * Terminate the user lib. * This function has to be called when finishing using the DLT user lib. diff --git a/src/examples/dlt-example-user.c b/src/examples/dlt-example-user.c index 6ede605..8c79c42 100644 --- a/src/examples/dlt-example-user.c +++ b/src/examples/dlt-example-user.c @@ -98,6 +98,7 @@ void usage() printf("Options:\n"); printf(" -d delay Milliseconds to wait between sending messages (Default: 500)\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); + printf(" -S filesize Set maximum size of local log file (Default: UINT_MAX)\n"); printf(" -n count Number of messages to be generated (Default: 10)\n"); printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); @@ -130,6 +131,7 @@ int main(int argc, char *argv[]) #endif /* DLT_TEST_ENABLE */ char *dvalue = 0; char *fvalue = 0; + unsigned int filesize = 0; char *nvalue = 0; char *mvalue = 0; char *message = 0; @@ -152,10 +154,10 @@ int main(int argc, char *argv[]) opterr = 0; #ifdef DLT_TEST_ENABLE - while ((c = getopt (argc, argv, "vgakcd:f:n:m:z:r:s:l:t:A:C:")) != -1) + while ((c = getopt (argc, argv, "vgakcd:f:S:n:m:z:r:s:l:t:A:C:")) != -1) #else - while ((c = getopt (argc, argv, "vgakd:f:n:m:l:r:t:A:C:")) != -1) + while ((c = getopt (argc, argv, "vgakd:f:S:n:m:l:r:t:A:C:")) != -1) #endif /* DLT_TEST_ENABLE */ { switch (c) { @@ -201,6 +203,11 @@ int main(int argc, char *argv[]) fvalue = optarg; break; } + case 'S': + { + filesize = atoi(optarg); + break; + } case 'n': { nvalue = optarg; @@ -238,7 +245,8 @@ int main(int argc, char *argv[]) } case '?': { - if ((optopt == 'd') || (optopt == 'f') || (optopt == 'n') || (optopt == 'l') || (optopt == 't')) + if ((optopt == 'd') || (optopt == 'f') || (optopt == 'n') || + (optopt == 'l') || (optopt == 't') || (optopt == 'S')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); @@ -279,6 +287,11 @@ int main(int argc, char *argv[]) return -1; } + if (filesize != 0) { + if (dlt_set_filesize_max(filesize) < 0) + return -1; + } + dlt_with_session_id(1); dlt_with_timestamp(1); dlt_with_ecu_id(1); diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index 778ea8f..d2ef613 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -91,6 +91,7 @@ static DltUser dlt_user; static bool dlt_user_initialised = false; static int dlt_user_freeing = 0; +static bool dlt_user_file_reach_max = false; #ifdef DLT_LIB_USE_FIFO_IPC static char dlt_user_dir[DLT_PATH_MAX]; @@ -459,6 +460,9 @@ DltReturnValue dlt_init(void) } dlt_user.dlt_is_file = 0; + dlt_user.filesize_max = UINT_MAX; + dlt_user_file_reach_max = false; + dlt_user.overflow = 0; dlt_user.overflow_counter = 0; #ifdef DLT_SHM_ENABLE @@ -546,16 +550,39 @@ DltReturnValue dlt_init_file(const char *name) dlt_user.dlt_is_file = 1; /* open DLT output file */ - dlt_user.dlt_log_handle = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ + dlt_user.dlt_log_handle = open(name, O_WRONLY | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (dlt_user.dlt_log_handle == -1) { dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "Log file %s cannot be opened!\n", name); + dlt_user.dlt_is_file = 0; return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } +DltReturnValue dlt_set_filesize_max(unsigned int filesize) +{ + if (dlt_user.dlt_is_file == 0) + { + dlt_vlog(LOG_ERR, "%s: Library is not configured to log to file\n", + __func__); + return DLT_LOG_ERROR; + } + + if (filesize == 0) { + dlt_user.filesize_max = UINT_MAX; + } + else { + dlt_user.filesize_max = filesize; + } + dlt_vlog(LOG_DEBUG, "%s: Defined filesize_max is [%d]\n", __func__, + dlt_user.filesize_max); + + return DLT_RETURN_OK; +} + #ifdef DLT_NETWORK_TRACE_ENABLE DltReturnValue dlt_init_message_queue(void) { @@ -3756,11 +3783,36 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) } if (dlt_user.dlt_is_file) { - /* log to file */ - ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size); - return ret; - } - else { + if (dlt_user_file_reach_max) { + return DLT_RETURN_FILESZERR; + } + else { + /* Get file size */ + struct stat st; + fstat(dlt_user.dlt_log_handle, &st); + dlt_vlog(LOG_DEBUG, "%s: Current file size=[%d]\n", __func__, + st.st_size); + + /* Check filesize */ + /* Return error if the file size has reached to maximum */ + unsigned int msg_size = st.st_size + (unsigned int) msg.headersize + + (unsigned int) log->size; + if (msg_size > dlt_user.filesize_max) { + dlt_user_file_reach_max = true; + dlt_vlog(LOG_ERR, + "%s: File size (%d bytes) reached to defined maximum size (%d bytes)\n", + __func__, st.st_size, dlt_user.filesize_max); + return DLT_RETURN_FILESZERR; + } + else { + /* log to file */ + ret = dlt_user_log_out2(dlt_user.dlt_log_handle, + msg.headerbuffer, msg.headersize, + log->buffer, log->size); + return ret; + } + } + } else { if (dlt_user.overflow_counter) { if (dlt_user_log_send_overflow() == DLT_RETURN_OK) { dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "%u messages discarded!\n", dlt_user.overflow_counter); -- cgit v1.2.1