summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaya Sugiura <ssugiura@jp.adit-jv.com>2020-07-31 18:13:14 +0900
committerSaya Sugiura <39760799+ssugiura@users.noreply.github.com>2021-01-06 09:27:28 +0900
commit0955febc56bf8ad49b0eabd7fc7970fd852becde (patch)
tree1abe6949ed4510bfa8cdbb97425a044a9c3ed6a1
parent9ed8fa6b42954562eba6f93c1c1734c7e0e70019 (diff)
downloadDLT-daemon-0955febc56bf8ad49b0eabd7fc7970fd852becde.tar.gz
logstorage: Handle wrap-around
In case there is wrap-around, the newest file must be decided based on the biggest wrap_id and corresponding working filename. Signed-off-by: Bui Nguyen Quoc Thanh <thanh.buinguyenquoc@vn.bosch.com> Signed-off-by: Dinh Cong Toan(RBVH/ECM12) <Toan.DinhCong@vn.bosch.com>
-rw-r--r--src/offlinelogstorage/dlt_offline_logstorage.c43
-rw-r--r--src/offlinelogstorage/dlt_offline_logstorage.h22
-rw-r--r--src/offlinelogstorage/dlt_offline_logstorage_behavior.c139
-rw-r--r--src/offlinelogstorage/dlt_offline_logstorage_behavior.h4
-rw-r--r--src/offlinelogstorage/dlt_offline_logstorage_behavior_internal.h2
5 files changed, 158 insertions, 52 deletions
diff --git a/src/offlinelogstorage/dlt_offline_logstorage.c b/src/offlinelogstorage/dlt_offline_logstorage.c
index 124b7a4..94364d6 100644
--- a/src/offlinelogstorage/dlt_offline_logstorage.c
+++ b/src/offlinelogstorage/dlt_offline_logstorage.c
@@ -2114,30 +2114,26 @@ int dlt_logstorage_write(DltLogStorage *handle,
uconfig,
handle->device_mount_point,
size1 + size2 + size3,
- tmp->newest_file);
+ tmp);
- /* In case the strategy is other than ON_MSG and UNSET,
- * in the very first time of preparation, the working file name
- * is not created yet. So check strategy and update it later in
- * step prepare_on_msg.
- */
- if (!config[i]->working_file_name) {
- if (config[i]->sync == DLT_LOGSTORAGE_SYNC_UNSET ||
- config[i]->sync == DLT_LOGSTORAGE_SYNC_ON_MSG) {
+ if (config[i]->sync == DLT_LOGSTORAGE_SYNC_UNSET ||
+ config[i]->sync == DLT_LOGSTORAGE_SYNC_ON_MSG) {
+ /* It is abnormal if working file is still NULL after preparation. */
+ if (!config[i]->working_file_name) {
dlt_vlog(LOG_ERR, "Failed to prepare working file for %s\n",
config[i]->file_name);
return -1;
}
- }
- else {
- if ((tmp->newest_file == NULL ||
- strcmp(config[i]->working_file_name, tmp->newest_file) != 0)) {
-
+ else {
+ /* After preparation phase, update newest file info
+ * it means there is new file created, newest file info must be updated.
+ */
if (tmp->newest_file) {
free(tmp->newest_file);
tmp->newest_file = NULL;
}
tmp->newest_file = strdup(config[i]->working_file_name);
+ tmp->wrap_id = config[i]->wrap_id;
}
}
@@ -2153,6 +2149,25 @@ int dlt_logstorage_write(DltLogStorage *handle,
size3);
if (ret == 0) {
+ /* In case of behavior CACHED_BASED, the newest file info
+ * must be updated right after writing phase.
+ * That is because in writing phase, it could also perform
+ * sync to file which actions could impact to the log file info.
+ * If both working file name and newest file name are unavailable,
+ * it means the sync to file is not performed yet, wait for next times.
+ */
+ if (config[i]->sync != DLT_LOGSTORAGE_SYNC_ON_MSG &&
+ config[i]->sync != DLT_LOGSTORAGE_SYNC_UNSET) {
+ if (config[i]->working_file_name) {
+ if (tmp->newest_file) {
+ free(tmp->newest_file);
+ tmp->newest_file = NULL;
+ }
+ tmp->newest_file = strdup(config[i]->working_file_name);
+ tmp->wrap_id = config[i]->wrap_id;
+ }
+ }
+
/* flush to be sure log is stored on device */
ret = config[i]->dlt_logstorage_sync(config[i],
uconfig,
diff --git a/src/offlinelogstorage/dlt_offline_logstorage.h b/src/offlinelogstorage/dlt_offline_logstorage.h
index c9bc93b..b4acbfa 100644
--- a/src/offlinelogstorage/dlt_offline_logstorage.h
+++ b/src/offlinelogstorage/dlt_offline_logstorage.h
@@ -143,6 +143,16 @@ typedef struct DltLogStorageFileList
struct DltLogStorageFileList *next; /* Pointer to next */
} DltLogStorageFileList;
+typedef struct DltNewestFileName DltNewestFileName;
+
+struct DltNewestFileName
+{
+ char *file_name; /* The unique name of file in whole a dlt_logstorage.conf */
+ char *newest_file; /* The real newest name of file which is associated with filename.*/
+ unsigned int wrap_id; /* Identifier of wrap around happened for this file_name */
+ DltNewestFileName *next; /* Pointer to next */
+};
+
typedef struct DltLogStorageFilterConfig DltLogStorageFilterConfig;
struct DltLogStorageFilterConfig
@@ -154,6 +164,7 @@ struct DltLogStorageFilterConfig
int reset_log_level; /* reset Log level to be sent on disconnect */
char *file_name; /* File name for log storage configured for filter */
char *working_file_name; /* Current open log file name */
+ unsigned int wrap_id; /* Identifier of wrap around happened for this filter */
unsigned int file_size; /* MAX File size of storage file configured for filter */
unsigned int num_files; /* MAX number of storage files configured for filters */
int sync; /* Sync strategy */
@@ -163,7 +174,7 @@ struct DltLogStorageFilterConfig
DltLogStorageUserConfig *file_config,
char *dev_path,
int log_msg_size,
- char *newest_file);
+ DltNewestFileName *newest_file_info);
int (*dlt_logstorage_write)(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
char *dev_path,
@@ -196,15 +207,6 @@ struct DltLogStorageFilterList
DltLogStorageFilterList *next; /* Pointer to next */
};
-typedef struct DltNewestFileName DltNewestFileName;
-
-struct DltNewestFileName
-{
- char *file_name; /* The unique name of file in whole a dlt_logstorage.conf */
- char *newest_file; /* The real newest name of file which is associated with filename.*/
- DltNewestFileName *next; /* Pointer to next */
-};
-
typedef struct
{
DltLogStorageFilterList *config_list; /* List of all filters */
diff --git a/src/offlinelogstorage/dlt_offline_logstorage_behavior.c b/src/offlinelogstorage/dlt_offline_logstorage_behavior.c
index edef482..ac3b372 100644
--- a/src/offlinelogstorage/dlt_offline_logstorage_behavior.c
+++ b/src/offlinelogstorage/dlt_offline_logstorage_behavior.c
@@ -116,14 +116,15 @@ void dlt_logstorage_log_file_name(char *log_file_name,
* Sort the filenames with index based ascending order (bubble sort)
*
* @param head Log filename list
- * @ return None
+ * @ return The last (biggest) index
*/
-void dlt_logstorage_sort_file_name(DltLogStorageFileList **head)
+unsigned int dlt_logstorage_sort_file_name(DltLogStorageFileList **head)
{
int done = 0;
+ unsigned int max_idx = 0;
if ((head == NULL) || (*head == NULL) || ((*head)->next == NULL))
- return;
+ return 0;
while (!done) {
/* "source" of the pointer to the current node in the list struct */
@@ -134,7 +135,9 @@ void dlt_logstorage_sort_file_name(DltLogStorageFileList **head)
done = 1;
while (nx) {
+ max_idx = nx->idx;
if (nd->idx > nx->idx) {
+ max_idx = nd->idx;
nd->next = nx->next;
nx->next = nd;
*pv = nx;
@@ -147,6 +150,8 @@ void dlt_logstorage_sort_file_name(DltLogStorageFileList **head)
nx = nx->next;
}
}
+
+ return max_idx;
}
/**
@@ -268,6 +273,7 @@ int dlt_logstorage_storage_dir_info(DltLogStorageUserConfig *file_config,
int i = 0;
int cnt = 0;
int ret = 0;
+ unsigned int max_idx = 0;
struct dirent **files = { 0 };
unsigned int current_idx = 0;
DltLogStorageFileList *n = NULL;
@@ -346,8 +352,17 @@ int dlt_logstorage_storage_dir_info(DltLogStorageUserConfig *file_config,
}
if (ret == 0) {
- dlt_logstorage_sort_file_name(&config->records);
- dlt_logstorage_rearrange_file_name(&config->records);
+ max_idx = dlt_logstorage_sort_file_name(&config->records);
+
+ /* Fault tolerance:
+ * In case there are some log files are removed but
+ * the index is still not reaching maxcounter, no need
+ * to perform rearrangement of filename.
+ * This would help the log keeps growing until maxcounter is reached and
+ * the maximum number of log files could be obtained.
+ */
+ if (max_idx == file_config->logfile_maxcounter)
+ dlt_logstorage_rearrange_file_name(&config->records);
}
/* free scandir result */
@@ -443,21 +458,26 @@ int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config,
(*tmp)->next = NULL;
}
else {
- /* newest file available*/
strcat(absolute_file_path, storage_path);
- strcat(absolute_file_path, (*newest)->name);
- if (config->working_file_name != NULL) {
- free(config->working_file_name);
- config->working_file_name = NULL;
+ /* newest file available
+ * Since the working file is already updated from newest file info
+ * So if there is already wrap-up, the newest file will be the working file
+ */
+ if ((config->wrap_id == 0) || (config->working_file_name == NULL)) {
+ if (config->working_file_name != NULL) {
+ free(config->working_file_name);
+ config->working_file_name = NULL;
+ }
+ config->working_file_name = strdup((*newest)->name);
}
- config->working_file_name = strdup((*newest)->name);
+ strcat(absolute_file_path, config->working_file_name);
ret = stat(absolute_file_path, &s);
/* if size is enough, open it */
- if ((ret == 0) && (s.st_size + msg_size < (int)config->file_size)) {
+ if ((ret == 0) && (s.st_size + msg_size <= (int) config->file_size)) {
config->log = fopen(absolute_file_path, "a+");
config->current_write_file_offset = s.st_size;
}
@@ -467,13 +487,15 @@ int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config,
/* get index of newest log file */
idx = dlt_logstorage_get_idx_of_log_file(file_config,
- (*newest)->name);
+ config->working_file_name);
idx += 1;
/* wrap around if max index is reached or an error occurred
* while calculating index from file name */
- if ((idx > file_config->logfile_maxcounter) || (idx == 0))
+ if ((idx > file_config->logfile_maxcounter) || (idx == 0)) {
idx = 1;
+ config->wrap_id += 1;
+ }
dlt_logstorage_log_file_name(file_name,
file_config,
@@ -492,6 +514,14 @@ int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config,
config->working_file_name = strdup(file_name);
}
+ /* If there is already wrap-up, check the existence of file
+ * remove it and reopen it.
+ * In this case number of log file won't be increased*/
+ if (config->wrap_id && stat(absolute_file_path, &s) == 0) {
+ remove(absolute_file_path);
+ num_log_files -= 1;
+ }
+
config->log = fopen(absolute_file_path, "a+");
/* Add file to file list */
@@ -520,6 +550,7 @@ int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config,
strcat(absolute_file_path, (*head)->name);
remove(absolute_file_path);
free((*head)->name);
+ (*head)->name = NULL;
*head = n->next;
n->next = NULL;
free(n);
@@ -528,8 +559,21 @@ int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config,
}
if (config->log == NULL) {
- dlt_log(LOG_ERR,
- "dlt_logstorage_create_log_file: Unable to open log file.\n");
+ if (*tmp != NULL) {
+ if ((*tmp)->name != NULL) {
+ free((*tmp)->name);
+ (*tmp)->name = NULL;
+ }
+ free(*tmp);
+ *tmp = NULL;
+ }
+
+ if (config->working_file_name != NULL) {
+ free(config->working_file_name);
+ config->working_file_name = NULL;
+ }
+
+ dlt_vlog(LOG_ERR, "%s: Unable to open log file.\n", __func__);
return -1;
}
@@ -745,25 +789,37 @@ DLT_STATIC int dlt_logstorage_sync_to_file(DltLogStorageFilterConfig *config,
* @param file_config User configurations for log file
* @param dev_path Storage device path
* @param log_msg_size Size of log message
- * @param newest_file Name of newest file for corresponding filename
+ * @param newest_file_info Info of newest file for corresponding filename
* @return 0 on success, -1 on error
*/
int dlt_logstorage_prepare_on_msg(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
char *dev_path,
int log_msg_size,
- char *newest_file)
+ DltNewestFileName *newest_file_info)
{
int ret = 0;
struct stat s;
- if ((config == NULL) || (file_config == NULL) || (dev_path == NULL)) {
+ if ((config == NULL) || (file_config == NULL) || (dev_path == NULL) ||
+ (newest_file_info == NULL)) {
dlt_vlog(LOG_INFO, "Wrong paratemters\n");
return -1;
}
/* This is for ON_MSG/UNSET strategy */
- if (config->log == NULL) { /* open a new log file */
+ if (config->log == NULL) {
+ /* Sync the wrap id and working file name before opening log file */
+ if (config->wrap_id < newest_file_info->wrap_id) {
+ config->wrap_id = newest_file_info->wrap_id;
+ if (config->working_file_name) {
+ free(config->working_file_name);
+ config->working_file_name = NULL;
+ }
+ config->working_file_name = strdup(newest_file_info->newest_file);
+ }
+
+ /* open a new log file */
ret = dlt_logstorage_open_log_file(config,
file_config,
dev_path,
@@ -775,10 +831,24 @@ int dlt_logstorage_prepare_on_msg(DltLogStorageFilterConfig *config,
if (ret == 0) {
/* check if adding new data do not exceed max file size */
+ /* Check if wrap id needs to be updated*/
if ((s.st_size + log_msg_size > (int)config->file_size) ||
- strcmp(config->working_file_name, newest_file) != 0) {
+ (strcmp(config->working_file_name, newest_file_info->newest_file) != 0) ||
+ (config->wrap_id < newest_file_info->wrap_id)) {
+
fclose(config->log);
config->log = NULL;
+
+ /* Sync the wrap id and working file name before opening log file */
+ if (config->wrap_id <= newest_file_info->wrap_id) {
+ config->wrap_id = newest_file_info->wrap_id;
+ if (config->working_file_name) {
+ free(config->working_file_name);
+ config->working_file_name = NULL;
+ }
+ config->working_file_name = strdup(newest_file_info->newest_file);
+ }
+
ret = dlt_logstorage_open_log_file(config,
file_config,
dev_path,
@@ -896,19 +966,38 @@ int dlt_logstorage_sync_on_msg(DltLogStorageFilterConfig *config,
* @param file_config User configurations for log file
* @param dev_path Storage device path
* @param log_msg_size Size of log message
- * @param newest_file Name of newest file for corresponding filename
+ * @param newest_file_info Info of newest files for corresponding filename
* @return 0 on success, -1 on error
*/
int dlt_logstorage_prepare_msg_cache(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
char *dev_path,
int log_msg_size,
- char *newest_file )
+ DltNewestFileName *newest_file_info )
{
- (void) newest_file;
- if ((config == NULL) || (file_config == NULL) || (dev_path == NULL))
+ if ((config == NULL) || (file_config == NULL) ||
+ (dev_path == NULL) || (newest_file_info == NULL))
return -1;
+ /* check if newest file info is available
+ * + working file name is NULL => update directly to newest file
+ * + working file name is not NULL: check if
+ * ++ wrap_ids are different from each other or
+ * ++ newest file name <> working file name
+ */
+ if (newest_file_info->newest_file) {
+ if (config->working_file_name &&
+ ((config->wrap_id != newest_file_info->wrap_id) ||
+ (strcmp(newest_file_info->newest_file, config->working_file_name) != 0))) {
+ free(config->working_file_name);
+ config->working_file_name = NULL;
+ }
+ if (config->working_file_name == NULL) {
+ config->working_file_name = strdup(newest_file_info->newest_file);
+ config->wrap_id = newest_file_info->wrap_id;
+ }
+ }
+
/* Combinations allowed: on Daemon_Exit with on Demand,File_Size with Daemon_Exit
* File_Size with on Demand, Specific_Size with Daemon_Exit,Specific_Size with on Demand
* Combination not allowed : File_Size with Specific_Size
diff --git a/src/offlinelogstorage/dlt_offline_logstorage_behavior.h b/src/offlinelogstorage/dlt_offline_logstorage_behavior.h
index cb94aa7..1ed5919 100644
--- a/src/offlinelogstorage/dlt_offline_logstorage_behavior.h
+++ b/src/offlinelogstorage/dlt_offline_logstorage_behavior.h
@@ -55,7 +55,7 @@ int dlt_logstorage_prepare_on_msg(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
char *dev_path,
int log_msg_size,
- char *newest_file);
+ DltNewestFileName *newest_file_info);
int dlt_logstorage_write_on_msg(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
char *dev_path,
@@ -78,7 +78,7 @@ int dlt_logstorage_prepare_msg_cache(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
char *dev_path,
int log_msg_size,
- char *newest_file);
+ DltNewestFileName *newest_file_info);
int dlt_logstorage_write_msg_cache(DltLogStorageFilterConfig *config,
DltLogStorageUserConfig *file_config,
diff --git a/src/offlinelogstorage/dlt_offline_logstorage_behavior_internal.h b/src/offlinelogstorage/dlt_offline_logstorage_behavior_internal.h
index c059fbd..b493db4 100644
--- a/src/offlinelogstorage/dlt_offline_logstorage_behavior_internal.h
+++ b/src/offlinelogstorage/dlt_offline_logstorage_behavior_internal.h
@@ -54,7 +54,7 @@ void dlt_logstorage_log_file_name(char *log_file_name,
char *name,
int idx);
-void dlt_logstorage_sort_file_name(DltLogStorageFileList **head);
+unsigned int dlt_logstorage_sort_file_name(DltLogStorageFileList **head);
void dlt_logstorage_rearrange_file_name(DltLogStorageFileList **head);