More functions converted to use threaded file handling.
- get_number_of_log_files_hdl()
- Cleaning up init handling
diff --git a/osaf/services/saf/logsv/lgs/lgs.h
b/osaf/services/saf/logsv/lgs/lgs.h
--- a/osaf/services/saf/logsv/lgs/lgs.h
+++ b/osaf/services/saf/logsv/lgs/lgs.h
@@ -121,5 +121,6 @@ extern SaAisErrorT lgs_imm_activate_fop(
extern void lgs_imm_impl_set(lgs_cb_t *cb);
extern SaAisErrorT lgs_imm_init(lgs_cb_t *cb);
extern const void *lgs_imm_logconf_get(lgs_logconfGet_t param, bool *noteflag);
+extern void lgs_imm_rootpathconf_set(char *root_path_str);
#endif /* ifndef __LGS_H */
diff --git a/osaf/services/saf/logsv/lgs/lgs_cb.h
b/osaf/services/saf/logsv/lgs/lgs_cb.h
--- a/osaf/services/saf/logsv/lgs/lgs_cb.h
+++ b/osaf/services/saf/logsv/lgs/lgs_cb.h
@@ -20,6 +20,8 @@
#include <saLog.h>
#include <saImmOi.h>
+#include <mbcsv_papi.h>
+#include <ncs_edu_pub.h>
#include "lgs_stream.h"
/* Default HA state assigned locally during lgs initialization */
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.h
b/osaf/services/saf/logsv/lgs/lgs_evt.h
--- a/osaf/services/saf/logsv/lgs/lgs_evt.h
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.h
@@ -19,6 +19,10 @@
#define LGS_EVT_H
#include <rda_papi.h>
+#include <mds_papi.h>
+#include <lgsv_msg.h>
+
+#include "lgs_cb.h"
typedef enum lgsv_lgs_evt_type {
LGSV_LGS_LGSV_MSG = 0,
diff --git a/osaf/services/saf/logsv/lgs/lgs_file.c
b/osaf/services/saf/logsv/lgs/lgs_file.c
--- a/osaf/services/saf/logsv/lgs/lgs_file.c
+++ b/osaf/services/saf/logsv/lgs/lgs_file.c
@@ -56,9 +56,9 @@ struct file_communicate {
bool timeout_f; /* True if API has got a timeout. Thread shall not
answer */
lgsf_treq_t request_code; /* Request code from API */
int return_code; /* Return code from handlers */
- uint32_t indata_size;
+ size_t indata_size;
void *indata; /* In-parameters for handlers */
- uint32_t outdata_size;
+ size_t outdata_size;
void *outdata; /* Out data from handlers */
};
@@ -123,6 +123,8 @@ static void *file_hndl_thread(void *nopa
void *outbuf;
uint32_t max_outsize;
+ gnolfh_in_t *lldtestpar1;
+
TRACE("LLDTEST: %s - is started",__FUNCTION__);
osaf_mutex_lock_ordie(&lgs_ftcom_mutex); /* LOCK */
@@ -160,13 +162,9 @@ static void *file_hndl_thread(void *nopa
*/
osaf_mutex_unlock_ordie(&lgs_ftcom_mutex); /* UNLOCK */
switch (lgs_com_data.request_code) {
- case LGSF_LLDTEST_SLOW:
- TRACE("LLDTEST: %s - LLDTEST_SLOW
received",__FUNCTION__);
- hndl_rc = lldtest_hdl_slow(inbuf, outbuf,
max_outsize);
- break;
- case LGSF_LLDTEST_NORMAL:
- TRACE("LLDTEST: %s - LLDTEST_NORMAL
received",__FUNCTION__);
- hndl_rc = lldtest_hdl_normal(inbuf, outbuf,
max_outsize);
+ case LGSF_FILEOPEN:
+ TRACE("LLDTEST: %s - LGSF_FILEOPEN
received",__FUNCTION__);
+ hndl_rc = fileopen_hdl(inbuf, outbuf,
max_outsize);
break;
case LGSF_FILECLOSE:
TRACE("LLDTEST: %s - LGSF_FILECLOSE
received",__FUNCTION__);
@@ -176,6 +174,20 @@ static void *file_hndl_thread(void *nopa
TRACE("LLDTEST: %s - LGSF_DELETE_FILE
received",__FUNCTION__);
hndl_rc = delete_file_hdl(inbuf, outbuf,
max_outsize);
break;
+ case LGSF_GET_NUM_LOGFILES:
+ TRACE("LLDTEST: %s - LGSF_GET_NUM_LOGFILES
received",__FUNCTION__);
+ lldtestpar1 = (gnolfh_in_t *) inbuf;
+ TRACE("LLDTEST from inbuf");
+ TRACE("LLDTEST: lldtestpar1->file_name
\"%s\"",lldtestpar1->file_name);
+ TRACE("LLDTEST: lldtestpar1->logsv_root_dir
\"%s\"",lldtestpar1->logsv_root_dir);
+ TRACE("LLDTEST: lldtestpar1->pathName
\"%s\"",lldtestpar1->pathName);
+
+ hndl_rc = get_number_of_log_files_hdl(inbuf,
outbuf, max_outsize);
+ break;
+ case LGSF_MAKELOGDIR:
+ TRACE("LLDTEST: %s - LGSF_MAKELOGDIR
received",__FUNCTION__);
+ hndl_rc = make_log_dir_hdl(inbuf, outbuf,
max_outsize);
+ break;
default:
break;
}
@@ -217,9 +229,9 @@ static void *file_hndl_thread(void *nopa
*
* @param
*/
-static void start_file_thread(void)
+static int start_file_thread(void)
{
- int rc;
+ int rc = 0;
int tbd_inpar=1;
pthread_t thread;
@@ -227,26 +239,46 @@ static void start_file_thread(void)
/* Init thread handling */
rc = pthread_mutex_init(&lgs_ftcom_mutex, NULL);
- if (rc != 0) osaf_abort(rc);
+ if (rc != 0) {
+ LOG_ER("pthread_mutex_init fail %s",strerror(errno));
+ goto done;
+ }
pthread_cond_init (&request_cv,NULL);
- if (rc != 0) osaf_abort(rc);
+ if (rc != 0) {
+ LOG_ER("pthread_cond_init fail %s",strerror(errno));
+ goto done;
+ }
pthread_cond_init (&answer_cv,NULL);
- if (rc != 0) osaf_abort(rc);
+ if (rc != 0) {
+ LOG_ER("pthread_cond_init fail %s",strerror(errno));
+ goto done;
+ }
/* Create thread.
*/
rc = pthread_create(&thread, NULL, file_hndl_thread, (void *)
&tbd_inpar);
- if (rc != 0) osaf_abort(rc);
+ if (rc != 0) {
+ LOG_ER("pthread_create fail %s",strerror(errno));
+ goto done;
+ }
TRACE_LEAVE2("LLDTEST");
+done:
+ return rc;
}
/**
* Initialize threaded file handling
*/
-void lgs_file_init(void)
+uint32_t lgs_file_init(void)
{
- start_file_thread();
+ uint32_t rc = NCSCC_RC_SUCCESS;
+
+ if (start_file_thread() != 0) {
+ rc = NCSCC_RC_FAILURE;
+ }
+
+ return rc;
}
/**
@@ -263,6 +295,8 @@ lgsf_retcode_t log_file_api(lgsf_apipar_
struct timespec timeout_time, start_time, end_time;
uint64_t stime_ms, etime_ms, dtime_ms;
+ gnolfh_in_t *lldtestpar;
+
TRACE_ENTER2("LLDTEST");
osaf_mutex_lock_ordie(&lgs_ftcom_mutex); /* LOCK */
@@ -287,14 +321,14 @@ lgsf_retcode_t log_file_api(lgsf_apipar_
}
lgs_com_data.indata_size = apipar_in->data_in_size;
-#if 1 /* REMOVE */
- if (lgs_com_data.request_code == LGSF_DELETE_FILE) {
- TRACE("LLDTEST: indata - %s",(char*)lgs_com_data.indata);
- TRACE("LLDTEST: indata_size = %d, strlen(indata) = %ld",
- lgs_com_data.indata_size,
- strlen(lgs_com_data.indata));
+ if (lgs_com_data.request_code == LGSF_GET_NUM_LOGFILES) {
+ lldtestpar = (gnolfh_in_t *) lgs_com_data.indata;
+ TRACE("LLDTEST: From lgs_com_data.indata");
+ TRACE("LLDTEST: apipar_in->data_in_size =
%ld",apipar_in->data_in_size);
+ TRACE("LLDTEST: lldtestpar->file_name
\"%s\"",lldtestpar->file_name);
+ TRACE("LLDTEST: lldtestpar->logsv_root_dir
\"%s\"",lldtestpar->logsv_root_dir);
+ TRACE("LLDTEST: lldtestpar->pathName
\"%s\"",lldtestpar->pathName);
}
-#endif
if (apipar_in->data_out_size != 0) {
lgs_com_data.outdata = malloc(apipar_in->data_out_size);
@@ -385,57 +419,3 @@ char *lgsf_retcode_str(lgsf_retcode_t rc
}
return "dummy";
}
-
-/*****************************************************************************
- * API functions
- *****************************************************************************/
-
-void lldtest_function_slow(void)
-{
- lgsf_apipar_t apipar;
- char tst_str_tohdl[] = "LLDTEST: Slow function in_string";
- char tst_str_frhdl[256];
- uint32_t tohdl_size;
- lgsf_retcode_t api_rc;
-
- TRACE_ENTER2("LLDTEST");
- tohdl_size = strlen(tst_str_tohdl)+1;
-
- /* Fill in API structure */
- apipar.req_code_in = LGSF_LLDTEST_SLOW;
- apipar.data_in_size = tohdl_size;
- apipar.data_in = (void*) tst_str_tohdl;
- apipar.data_out_size = 256;
- apipar.data_out = (void*) tst_str_frhdl;
-
- api_rc = log_file_api(&apipar);
-
- TRACE("LLDTEST: Out data fr hdl - %s, hdl_rc = %d, api_rc = %d",
- (char*) apipar.data_out, apipar.hdl_ret_code_out, api_rc);
- TRACE_LEAVE2("LLDTEST");
-}
-
-void lldtest_function_normal(void)
-{
- lgsf_apipar_t apipar;
- char tst_str_tohdl[] = "LLDTEST: Normal function in_string";
- char tst_str_frhdl[256];
- uint32_t tohdl_size;
- lgsf_retcode_t api_rc;
-
- TRACE_ENTER2("LLDTEST");
- tohdl_size = strlen(tst_str_tohdl)+1;
-
- /* Fill in API structure */
- apipar.req_code_in = LGSF_LLDTEST_NORMAL;
- apipar.data_in_size = tohdl_size;
- apipar.data_in = (void*) tst_str_tohdl;
- apipar.data_out_size = 256;
- apipar.data_out = (void*) tst_str_frhdl;
-
- api_rc = log_file_api(&apipar);
-
- TRACE("LLDTEST: Out data fr hdl - %s, hdl_rc = %d, api_rc = %d",
- (char*) apipar.data_out, apipar.hdl_ret_code_out, api_rc);
- TRACE_LEAVE2("LLDTEST");
-}
diff --git a/osaf/services/saf/logsv/lgs/lgs_file.h
b/osaf/services/saf/logsv/lgs/lgs_file.h
--- a/osaf/services/saf/logsv/lgs/lgs_file.h
+++ b/osaf/services/saf/logsv/lgs/lgs_file.h
@@ -19,6 +19,8 @@
#define LGS_FILE_H
#include <stdint.h>
+#include <limits.h>
+#include <stddef.h>
#ifdef __cplusplus
extern "C" {
@@ -33,10 +35,11 @@ typedef enum {
}lgsf_retcode_t;
typedef enum {
- LGSF_LLDTEST_SLOW,
- LGSF_LLDTEST_NORMAL,
+ LGSF_FILEOPEN,
LGSF_FILECLOSE,
LGSF_DELETE_FILE,
+ LGSF_GET_NUM_LOGFILES,
+ LGSF_MAKELOGDIR,
LGSF_NOREQ
}lgsf_treq_t;
@@ -44,9 +47,9 @@ typedef enum {
typedef struct {
lgsf_treq_t req_code_in;/* Invokes the correct handler */
int hdl_ret_code_out; /* Return code from handler */
- uint32_t data_in_size; /* Size of in-data buffer */
+ size_t data_in_size; /* Size of in-data buffer */
void *data_in; /* Buffer containing in data for the handler */
- uint32_t data_out_size; /* Size of out-data buffer */
+ size_t data_out_size; /* Size of out-data buffer */
void *data_out; /* Buffer containing out data from the handler */
}lgsf_apipar_t;
@@ -57,24 +60,59 @@ typedef struct {
* Defines for in and out parameters for each handler
*****************************************************************************/
+/* fileopen_hdl
+ * Inpar char str[]
+ * No typedef needed
+ * Ret code file descriptor or -1 if error
+ * Outpar int errno_save
+ * No typedef needed
+ */
+
/* fileclose_hdl
* Inpar int fd
* No typedef needed
+ * No out parameters
*/
/* delete_file_hdl
- * Inpar char *str
+ * Inpar char str[]
* No typedef needed
+ * No out parameters
*/
+/* make_log_dir_hdl
+ * Ret code -1 if error
+ * Out parameter is a string of max PATH_MAX
+ * Parameter data_out_size must be set to PATH_MAX
+ */
+typedef struct {
+ char root_dir[PATH_MAX+1]; /* Implementer defined root directory */
+ char rel_path[PATH_MAX+1]; /* Path to create */
+}mld_in_t;
+
+/* get_number_of_log_files_hdl
+ */
+typedef struct {
+ /* File name prefix (name part before time stamps) */
+ char file_name[NAME_MAX+1];
+ /* logsv_root_dir + pathName makes up the path to the log files
+ * Note: The whole path cannot be a longer string than PATH_MAX
+ */
+ char logsv_root_dir[PATH_MAX+1];
+ char pathName[PATH_MAX+1];
+}gnolfh_in_t;
+
+/* parameter [out]
+ * char str[PATH_MAX + NAME_MAX]
+ * No typdef needed
+ * Out parameter is a string of max PATH_MAX + NAME_MAX length
+ * Parameter data_out_size must be set to PATH_MAX + NAME_MAX.
+ */
char *lgsf_retcode_str(lgsf_retcode_t rc);
-void lgs_file_init(void);
+uint32_t lgs_file_init(void);
lgsf_retcode_t log_file_api(lgsf_apipar_t *param_in);
-void lldtest_function_slow(void); /* LLDTEST */
-void lldtest_function_normal(void); /* LLDTEST */
-
#ifdef __cplusplus
}
#endif
diff --git a/osaf/services/saf/logsv/lgs/lgs_filehdl.c
b/osaf/services/saf/logsv/lgs/lgs_filehdl.c
--- a/osaf/services/saf/logsv/lgs/lgs_filehdl.c
+++ b/osaf/services/saf/logsv/lgs/lgs_filehdl.c
@@ -31,13 +31,20 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
+#include <limits.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
#include <unistd.h> /* LLDTEST */
+#include <configmake.h>
#include <logtrace.h>
-#include <errno.h>
+#include <ncsgl_defs.h>
+#include <osaf_utility.h>
-#include "osaf_utility.h"
+#include "lgs_util.h"
#include "lgs_file.h"
@@ -48,48 +55,129 @@
*****************************************************************************/
/**
- * LLDTEST: For test of lgs_file. To Be Removed
- * @param indata
- * @param outdata
- * @param outsize_in
- * @return
+ * Make directory. Handles creation of directory path.
+ * Creates the relative in the directory given by the root path. If the root
+ * path does not exist/is not available a root path is created based on the
+ * default path taken from the configuration define PKGLOGDIR.
+ * Settings: Read, Write, Exec for User, Group, Other
+ *
+ * @param indata[in], Type mld_in_t
+ * @param outdata[out], char *, new root dir if changed otherwise '\0'
+ * @param max_outsize[in]
+ * @return (-1) if error
*/
-int lldtest_hdl_slow(void *indata, void *outdata, uint32_t outsize_in)
+int make_log_dir_hdl(void *indata, void *outdata, size_t max_outsize)
{
- int rc=54;
- char *testdata_in;
+ int rc = 0;
+ int mldh_rc = 0;
+ mld_in_t *params_in = (mld_in_t *) indata;
+ char *out_path = (char *) outdata;
- char outstr[] = "LLDTEST str out";
- testdata_in = (char *)indata;
- memcpy(outdata, outstr, sizeof(outstr));
+ char *relpath = params_in->rel_path;
+ char *rootpath = params_in->root_dir;
+ char dir_to_make[PATH_MAX + PATH_MAX+2];
+ char mpath[PATH_MAX+1];
+ char *spath_p;
+ char *epath_p;
+ struct stat statbuf;
- TRACE("LLDTEST: %s -- indata %s, Max outsize=%d, outdata size=%ld",
- __FUNCTION__, testdata_in, outsize_in, sizeof(outstr));
- sleep(1);
+ TRACE_ENTER2("LLDTEST");
+ LOG_NO("LLDTEST make_log_dir_hdl >>");
- return rc;
+ /* Guaranty that both rootpath and relpath is terminated within max
size */
+ rootpath[PATH_MAX] = '\0';
+ relpath[PATH_MAX] = '\0';
+ dir_to_make[0] = '\0';
+
+ /* (TBD Fix a better handling)
+ * Create root directory if not exists.
+ * Create the default root path regardless of what is set in the
+ * configuration object.
+ */
+ out_path[0] = '\0';
+ if (lstat(rootpath, &statbuf) != 0) {
+#if 0 /* Cannot be handled in logservice for now. Quick fix for #3094 */
+ rootpath = PKGLOGDIR;
+ strncpy(out_path, rootpath, max_outsize);
+#endif
+ LOG_NO("LLDTEST: LOG Root path does not exist. Will be
creeated");
+ }
+
+ TRACE("LLDTEST: rootpath \"%s\"",rootpath);
+ TRACE("LLDTEST: relpath \"%s\"",relpath);
+ /* Create complete path string */
+ strcpy(dir_to_make, rootpath);
+ TRACE("LLDTEST: rootpath len=%ld",strlen(rootpath));
+ TRACE("LLDTEST: last char \'%c\'",dir_to_make[strlen(rootpath)-1]);
+ if (dir_to_make[strlen(rootpath)-1] != '/') { /* End root path with '/'
*/
+ dir_to_make[strlen(rootpath)] = '/';
+ dir_to_make[strlen(rootpath)+1] = '\0';
+ }
+ TRACE("LLDTEST: (1) dir_to_make \"%s\"",dir_to_make);
+ while (*relpath == '/') relpath++; /* Remove preceding '/' */
+ strcat(dir_to_make, relpath); /* Concatenate complete path */
+ TRACE("LLDTEST: (2) dir_to_make \"%s\"",dir_to_make);
+
+ /* Create the path */
+ spath_p = epath_p = dir_to_make;
+ while ((epath_p = strchr(epath_p, '/')) != NULL) {
+ epath_p++;
+ strncpy(mpath, spath_p, (epath_p - spath_p));
+ rc = mkdir(mpath, S_IRWXU | S_IRWXG | S_IRWXO);
+ if ((rc != 0) && (errno != EEXIST)) {
+ LOG_ER("%s: Making directory error
%s",__FUNCTION__,strerror(errno));
+ mldh_rc = -1;
+ goto done;
+ }
+ }
+ strcpy(mpath, spath_p);
+ rc = mkdir(mpath, S_IRWXU | S_IRWXG | S_IRWXO);
+ if ((rc != 0) && (errno != EEXIST)) {
+ LOG_ER("%s: Making directory error
%s",__FUNCTION__,strerror(errno));
+ mldh_rc = -1;
+ goto done;
+ }
+ TRACE("LLDTEST: Dir \"%s\" created",mpath);
+
+done:
+ LOG_NO("LLDTEST make_log_dir_hdl <<");
+ TRACE_LEAVE2("LLDTEST: %u", mldh_rc);
+ return mldh_rc;
}
/**
- * LLDTEST: For test of lgs_file. To Be Removed
- * @param indata
- * @param outdata
- * @param outsize_in
- * @return
+ * Open/create a file for append
+ * @param indata[in], Null-terminated string containing filename to open
+ * @param outdata[out], int errno, 0 if no error
+ * @param max_outsize[in], always sizeof(int)
+ * @return file descriptor or -1 if error
*/
-int lldtest_hdl_normal(void *indata, void *outdata, uint32_t outsize_in)
+int fileopen_hdl(void *indata, void *outdata, size_t max_outsize)
{
- int rc=55;
- char *testdata_in;
+ int fd_out;
+ int errno_save = 0;
+ char *filepath = (char *) indata;
+ int *errno_out_p = (int *) outdata;
- char outstr[] = "LLDTEST str out";
- testdata_in = (char *)indata;
- memcpy(outdata, outstr, sizeof(outstr));
+ TRACE_ENTER2("LLDTEST1");
+ TRACE("LLDTEST1: Open filepath \"%s\"",filepath);
- TRACE("LLDTEST: %s -- indata %s, Max outsize=%d, outdata size=%ld",
- __FUNCTION__, testdata_in, outsize_in, sizeof(outstr));
-
- return rc;
+open_retry:
+ fd_out = open(filepath, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR
| S_IRGRP);
+
+ if (fd_out == -1) {
+ if (errno == EINTR)
+ goto open_retry;
+ /* save errno for caller logging */
+ errno_save = errno;
+ /* Do not log with higher severity here to avoid flooding the
log.
+ * Can be called in context of log_stream_write */
+ LOG_IN("%s: Could not open: %s - %s", __FUNCTION__, filepath,
strerror(errno));
+ }
+
+ *errno_out_p = errno_save;
+ TRACE_LEAVE2("LLDTEST1");
+ return fd_out;
}
/**
@@ -99,7 +187,7 @@ int lldtest_hdl_normal(void *indata, voi
* @param max_outsize[in], must be set to 0
* @return (-1) if error
*/
-int fileclose_hdl(void *indata, void *outdata, uint32_t max_outsize)
+int fileclose_hdl(void *indata, void *outdata, size_t max_outsize)
{
int rc = 0;
int fd;
@@ -127,7 +215,7 @@ close_retry:
* @param max_outsize[in], must be set to 0
* @return (-1) if error
*/
-int delete_file_hdl(void *indata, void *outdata, uint32_t max_outsize)
+int delete_file_hdl(void *indata, void *outdata, size_t max_outsize)
{
int rc = 0;
char *pathname = (char *) indata;
@@ -147,3 +235,143 @@ int delete_file_hdl(void *indata, void *
return rc;
}
+/******************************************************************************
+ * Utility functions for get_number_of_log_files_hdl
+ */
+static int check_oldest(char *line, char *fname_prefix, int fname_prefix_size,
int *old_date, int *old_time)
+{
+ int date, time, c, d;
+ date = time = c = d = 0;
+ int len = 0;
+ char name_format[NAME_MAX+1];
+ char time_stamps[] = "_%d_%d_%d_%d.log";
+
+ len = strlen(time_stamps);
+ len += fname_prefix_size;
+
+ strncpy(name_format, fname_prefix, fname_prefix_size);
+ name_format[fname_prefix_size] = '\0';
+ TRACE_3("fname: %s", name_format);
+ strncat(name_format, time_stamps, NAME_MAX);
+ if (sscanf(line, name_format, &date, &time, &c, &d) == 4) {
+ TRACE_3("line: arg1: %d 2: %d 3: %d 4: %d ok", date, time, c,
d);
+ if (date < *old_date || *old_date == -1) {
+ *old_date = date;
+ *old_time = time;
+ return 1;
+ } else if ((date == *old_date) && (time < *old_time)) {
+ *old_date = date;
+ *old_time = time;
+ return 1;
+ }
+ } else if (sscanf(line, name_format, &date, &time) == 2) {
+ TRACE_3("line: arg1: %d 2: %d ok", date, time);
+ if (date < *old_date || *old_date == -1) {
+ *old_date = date;
+ *old_time = time;
+ return 1;
+ } else if ((date == *old_date) && (time < *old_time)) {
+ *old_date = date;
+ *old_time = time;
+ return 1;
+ }
+ } else {
+ TRACE_3("no match");
+ }
+ return 0;
+}
+
+/* Filter function used by scandir. */
+static char file_prefix[NAME_MAX];
+static int filter_func(const struct dirent *finfo)
+{
+ int ret;
+ ret = strncmp(file_prefix, finfo->d_name, strlen(file_prefix));
+ return !ret;
+}
+
+/**
+ * Return number of log files in a dir and the name of the oldest file.
+ * @param indata, see gnolfh_in_t
+ * @param outdata, char *oldest_file
+ * @param max_outsize, Max size for oldest_file string
+ *
+ * @return int, number of logfiles or -1 if error
+ */
+int get_number_of_log_files_hdl(void *indata, void *outdata, size_t
max_outsize)
+{
+ struct dirent **namelist;
+ int n, old_date = -1, old_time = -1, old_ind = -1, files, i, failed = 0;
+ char path[PATH_MAX];
+ gnolfh_in_t *params_in;
+ char *oldest_file;
+ int rc;
+
+ TRACE_ENTER2("LLDTEST");
+
+ params_in = (gnolfh_in_t *) indata;
+ oldest_file = (char *) outdata;
+
+ /* Initialize the filter */
+ strncpy(file_prefix, params_in->file_name, NAME_MAX);
+
+ n = snprintf(path, PATH_MAX, "%s/%s",
+ params_in->logsv_root_dir, params_in->pathName);
+ if (n >= PATH_MAX) {
+ LOG_ER("Parameter error: Path is longer than PATH_MAX");
+ rc = -1;
+ goto done_exit;
+ }
+
+ files = n = scandir(path, &namelist, filter_func, alphasort);
+ if (n == -1 && errno == ENOENT) {
+ rc = 0;
+ TRACE("LLDTEST: %s - 2",__FUNCTION__);
+ goto done_exit;
+ }
+
+ if (n < 0) {
+ LOG_ER("scandir:%s %s", strerror(errno), path);
+ rc = -1;
+ goto done_exit;
+ }
+
+ if (n == 0) {
+ rc = files;
+ goto done_exit;
+ }
+
+ while (n--) {
+ TRACE_3("%s", namelist[n]->d_name);
+ if (check_oldest(namelist[n]->d_name, params_in->file_name,
+ strlen(params_in->file_name), &old_date,
&old_time)) {
+ old_ind = n;
+ } else {
+ failed++; /* wrong format */
+ }
+ }
+ if (old_ind != -1) {
+ TRACE_1(" oldest: %s", namelist[old_ind]->d_name);
+ n = snprintf(oldest_file, max_outsize, "%s/%s",
+ path, namelist[old_ind]->d_name);
+ if (n >= max_outsize) {
+ LOG_ER("Error: outdata out of limits");
+ rc = -1;
+ goto done_free;
+ } else {
+ rc = (files - failed);
+ }
+ } else {
+ TRACE("Only file/files with wrong format found");
+ }
+
+done_free:
+ /* Free scandir allocated memory */
+ for (i = 0; i < files; i++)
+ free(namelist[i]);
+ free(namelist);
+
+done_exit:
+ TRACE_LEAVE2("LLDTEST");
+ return rc;
+}
diff --git a/osaf/services/saf/logsv/lgs/lgs_filehdl.h
b/osaf/services/saf/logsv/lgs/lgs_filehdl.h
--- a/osaf/services/saf/logsv/lgs/lgs_filehdl.h
+++ b/osaf/services/saf/logsv/lgs/lgs_filehdl.h
@@ -9,18 +9,18 @@
#define LGS_FILEHDL_H
#include <stdint.h>
+#include <stddef.h>
+#include <saAis.h>
#ifdef __cplusplus
extern "C" {
#endif
-#if 1 /* LLDTEST */
-int lldtest_hdl_slow(void *indata, void *outdata, uint32_t outsize_in);
-int lldtest_hdl_normal(void *indata, void *outdata, uint32_t outsize_in);
-#endif
-
-int fileclose_hdl(void *indata, void *outdata, uint32_t max_outsize);
-int delete_file_hdl(void *indata, void *outdata, uint32_t max_outsize);
+int make_log_dir_hdl(void *indata, void *outdata, size_t max_outsize);
+int fileopen_hdl(void *indata, void *outdata, size_t max_outsize);
+int fileclose_hdl(void *indata, void *outdata, size_t max_outsize);
+int delete_file_hdl(void *indata, void *outdata, size_t max_outsize);
+int get_number_of_log_files_hdl(void *indata, void *outdata, size_t
max_outsize);
#ifdef __cplusplus
}
diff --git a/osaf/services/saf/logsv/lgs/lgs_imm.c
b/osaf/services/saf/logsv/lgs/lgs_imm.c
--- a/osaf/services/saf/logsv/lgs/lgs_imm.c
+++ b/osaf/services/saf/logsv/lgs/lgs_imm.c
@@ -186,7 +186,7 @@ static bool path_is_writeable_dir(const
TRACE_ENTER();
- if (lgs_relative_path_check(pathname) || stat(pathname, &pathstat) !=
0) {
+ if (lgs_relative_path_check_ts(pathname) || stat(pathname, &pathstat)
!= 0) {
LOG_NO("Path %s does not exist", pathname);
goto done;
}
@@ -540,7 +540,7 @@ static SaAisErrorT check_attr_validity(c
strcat(fileName, "//");
strcat(fileName, *((char **) value));
strcat(fileName, "//.");
- if (lgs_relative_path_check(fileName)) {
+ if (lgs_relative_path_check_ts(fileName)) {
LOG_ER("Path %s not valid", fileName);
rc = SA_AIS_ERR_INVALID_PARAM;
} else if (stat(lgs_cb->logsv_root_dir,
&pathstat) != 0) {
@@ -809,7 +809,7 @@ static void logRootDirectory_set(const c
/* Create the new log file based on updated configuration */
sprintf(stream->logFileCurrent, "%s_%s", stream->fileName,
current_time);
- if ((stream->fd = log_file_open_fop(stream, NULL)) == -1) {
+ if ((stream->fd = log_file_open_fh(stream, NULL)) == -1) {
LOG_ER("New log file could not be created for stream:
%s",
stream->name);
}
@@ -1647,6 +1647,23 @@ const void *lgs_imm_logconf_get(lgs_logc
return NULL; /* Dummy */
}
+/**
+ * Set the logRootDirectory parameter in the lgs_conf struct
+ *
+ * Note: This is needed for #3053/#3023 quick fix.
+ * See also lgs_stream.c lgs_make_dir(...)
+ *
+ * @param root_path_str
+ */
+void lgs_imm_rootpathconf_set(char *root_path_str)
+{
+ if (strlen(root_path_str) > PATH_MAX)
+ osafassert(0);
+
+ strcpy(lgs_conf->logRootDirectory, root_path_str);
+ LOG_NO("lgsv root path is changed to
\"%s\"",lgs_conf->logRootDirectory);
+}
+
static const SaImmOiCallbacksT_2 callbacks = {
.saImmOiAdminOperationCallback = adminOperationCallback,
.saImmOiCcbAbortCallback = ccbAbortCallback,
diff --git a/osaf/services/saf/logsv/lgs/lgs_main.c
b/osaf/services/saf/logsv/lgs/lgs_main.c
--- a/osaf/services/saf/logsv/lgs/lgs_main.c
+++ b/osaf/services/saf/logsv/lgs/lgs_main.c
@@ -212,6 +212,11 @@ static uint32_t log_initialize(void)
TRACE_ENTER();
+ if (lgs_file_init() != NCSCC_RC_SUCCESS) {
+ LOG_ER("lgs_file_init FAILED");
+ goto done;
+ }
+
if (ncs_agents_startup() != NCSCC_RC_SUCCESS) {
LOG_ER("ncs_agents_startup FAILED");
goto done;
@@ -408,23 +413,11 @@ int main(int argc, char *argv[])
daemonize(argc, argv);
- TRACE("LLDTEST: lgs_file_init()");
- lgs_file_init();
-
if (log_initialize() != NCSCC_RC_SUCCESS) {
LOG_ER("log_initialize failed");
goto done;
}
-#if 1 /* LLDTEST */
- //lgs_file_init();
-
- /* Execute test function */
- //lldtest_function_slow();
- //sleep(1);
- //lldtest_function_normal();
-#endif
-
mbx_fd = ncs_ipc_get_sel_obj(&lgs_mbx);
daemon_sigterm_install(&term_fd);
diff --git a/osaf/services/saf/logsv/lgs/lgs_stream.c
b/osaf/services/saf/logsv/lgs/lgs_stream.c
--- a/osaf/services/saf/logsv/lgs/lgs_stream.c
+++ b/osaf/services/saf/logsv/lgs/lgs_stream.c
@@ -15,6 +15,17 @@
*
*/
+/*****************************************************************************
+ * Important information
+ * ---------------------
+ * To prevent log service thread from "hanging" if communication with NFS is
+ * not working or is very slow all functions using file I/O must run their file
+ * handling in a separate thread.
+ * For more information on how to do that see the following files:
+ * lgs_file.h, lgs_file.c, lgs_filendl.c and lgs_filehdl.h
+ * Examples can be found in this file, e.g. function fileopen(...) below
+ */
+
#include "lgs.h"
#include "lgs_file.h"
@@ -33,7 +44,43 @@ static unsigned int numb_of_streams;
static int lgs_stream_array_insert_nof(log_stream_t *stream, uint32_t id);
static int lgs_stream_array_insert_new_nof(log_stream_t *stream, uint32_t *id);
static int lgs_stream_array_remove_nof(int id);
-static int get_number_of_log_files_fop(log_stream_t *logStream, char
*oldest_file);
+static int get_number_of_log_files_hfop(log_stream_t *logStream, char
*oldest_file);
+
+/**
+ * Open/Create a file
+ * @param filepath[in]
+ * @param errno_save[out], errno if error
+ * @return File descriptor or -1 if error
+ */
+static int fileopen_hfop(char *filepath, int *errno_save)
+{
+ lgsf_apipar_t apipar;
+ lgsf_retcode_t api_rc;
+ int fd;
+
+ TRACE_ENTER2("LLDTEST1");
+
+ osafassert(filepath != NULL);
+
+ /* Fill in API structure */
+ apipar.req_code_in = LGSF_FILEOPEN;
+ apipar.data_in_size = strlen(filepath)+1;
+ apipar.data_in = (void*) filepath;
+ apipar.data_out_size = sizeof(int);
+ apipar.data_out = (void *) errno_save;
+
+ api_rc = log_file_api(&apipar);
+ if (api_rc != LGSF_SUCESS) {
+ TRACE("LLDTEST1: %s - API error %d",__FUNCTION__,api_rc);
+ fd = -1;
+ } else {
+ fd = apipar.hdl_ret_code_out;
+ }
+ TRACE("LLDTEST1: return %d",fd);
+
+ TRACE_LEAVE2("LLDTEST1");
+ return fd;
+}
/**
* Close with retry at EINTR
@@ -41,7 +88,7 @@ static int get_number_of_log_files_fop(l
*
* @return int
*/
-static int fileclose_fop(int fd)
+static int fileclose_hfop(int fd)
{
lgsf_apipar_t apipar;
lgsf_retcode_t api_rc;
@@ -62,50 +109,75 @@ static int fileclose_fop(int fd)
if (api_rc != LGSF_SUCESS) {
TRACE("LLDTEST: %s - API error %d",__FUNCTION__,api_rc);
rc = -1;
+ } else {
+ rc = apipar.hdl_ret_code_out;
}
- TRACE_LEAVE2("LLDTEST");
+ TRACE_LEAVE2("LLDTEST: rc=%d",rc);
return rc;
}
/**
+ * Delete a file (unlink())
+ *
+ * @param filepath A null terminated string containing the name of the file to
+ * be deleted
+ * @return (-1) if error
+ */
+static int file_unlink_hfop(char *filepath)
+{
+ int rc = 0;
+ lgsf_apipar_t apipar;
+ lgsf_retcode_t api_rc;
+ size_t filepath_len;
+
+ filepath_len = strlen(filepath)+1; /* Include terminating null
character */
+
+ /* Fill in API structure */
+ apipar.req_code_in = LGSF_DELETE_FILE;
+ apipar.data_in_size = filepath_len;
+ apipar.data_in = (void*) filepath;
+ apipar.data_out_size = 0;
+ apipar.data_out = NULL;
+
+ api_rc = log_file_api(&apipar);
+ if (api_rc != LGSF_SUCESS) {
+ TRACE("LLDTEST: %s - API error
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
+ rc = -1;
+ } else {
+ rc = apipar.hdl_ret_code_out;
+ }
+
+ TRACE_LEAVE2("LLDTEST: rc=%d", rc);
+ return rc;
+
+}
+
+/**
* Delete config file.
* @param stream
*
* @return int
*/
-static int delete_config_file_fop(log_stream_t *stream)
+static int delete_config_file_fh(log_stream_t *stream)
{
int rc, n;
char pathname[PATH_MAX + NAME_MAX];
- lgsf_apipar_t apipar;
- lgsf_retcode_t api_rc;
- TRACE_ENTER();
+ TRACE_ENTER2("LLDTEST");
/* create absolute path for config file */
n = snprintf(pathname, PATH_MAX, "%s/%s/%s.cfg",
lgs_cb->logsv_root_dir, stream->pathName, stream->fileName);
osafassert(n < sizeof(pathname));
- /* Fill in API structure */
- apipar.req_code_in = LGSF_DELETE_FILE;
- apipar.data_in_size = n+1; /* Include termination byte '\0' */
- apipar.data_in = (void*) &pathname;
- apipar.data_out_size = 0;
- apipar.data_out = NULL;
+ rc = file_unlink_hfop(pathname);
- api_rc = log_file_api(&apipar);
- if (api_rc != LGSF_SUCESS) {
- TRACE("LLDTEST: %s - API error
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
- rc = -1;
- }
-
- TRACE_LEAVE2("rc=%d", rc);
+ TRACE_LEAVE2("LLDTEST: rc=%d", rc);
return rc;
}
-static int rotate_if_needed_fop(log_stream_t *stream)
+static int rotate_if_needed_fh(log_stream_t *stream)
{
char oldest_file[PATH_MAX + NAME_MAX];
int rc = 0;
@@ -114,7 +186,7 @@ static int rotate_if_needed_fop(log_stre
TRACE_ENTER();
/* Rotate out files from previous lifes */
- if ((file_cnt = get_number_of_log_files_fop(stream, oldest_file)) ==
-1) {
+ if ((file_cnt = get_number_of_log_files_hfop(stream, oldest_file)) ==
-1) {
rc = -1;
goto done;
}
@@ -125,12 +197,12 @@ static int rotate_if_needed_fop(log_stre
*/
while (file_cnt >= stream->maxFilesRotated) {
TRACE_1("remove oldest file: %s", oldest_file);
- if ((rc = unlink(oldest_file)) == -1) {
- LOG_NO("could not unlink: %s - %s", oldest_file,
strerror(errno));
+ if ((rc = file_unlink_hfop(oldest_file)) == -1) {
+ LOG_NO("could not delete: %s - %s", oldest_file,
strerror(errno));
goto done;
}
- if ((file_cnt = get_number_of_log_files_fop(stream,
oldest_file)) == -1) {
+ if ((file_cnt = get_number_of_log_files_hfop(stream,
oldest_file)) == -1) {
rc = -1;
goto done;
}
@@ -309,7 +381,7 @@ log_stream_t *log_stream_new_nof(SaNameT
osafassert(dn != NULL);
TRACE_ENTER2("%s, l: %u", dn->value, dn->length);
- if (lgs_relative_path_check(pathname)) {
+ if (lgs_relative_path_check_ts(pathname)) {
goto done;
}
stream = calloc(1, sizeof(log_stream_t));
@@ -544,30 +616,22 @@ log_stream_t *log_stream_new_2_nof(SaNam
*
* @return int - the file descriptor or -1 on errors
*/
-int log_file_open_fop(log_stream_t *stream, int *errno_save)
+int log_file_open_fh(log_stream_t *stream, int *errno_save)
{
int fd;
char pathname[PATH_MAX + NAME_MAX + 1];
+ int errno_ret;
- TRACE_LEAVE2("%s", stream->logFileCurrent);
+ TRACE_ENTER2("LLDTEST1");
sprintf(pathname, "%s/%s/%s.log", lgs_cb->logsv_root_dir,
stream->pathName, stream->logFileCurrent);
-
-open_retry:
- fd = open(pathname, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR |
S_IRGRP);
-
- if (fd == -1) {
- if (errno == EINTR)
- goto open_retry;
- /* save errno for caller logging */
- if (errno_save)
- *errno_save = errno;
- /* Do not log with higher severity here to avoid flooding the
log.
- * Can be called in context of log_stream_write */
- LOG_IN("%s: Could not open: %s - %s", __FUNCTION__, pathname,
strerror(errno));
+
+ fd = fileopen_hfop(pathname, &errno_ret);
+ if (errno_save != 0) {
+ *errno_save = errno_ret;
}
- TRACE_LEAVE2("%d", fd);
+ TRACE_LEAVE2("LLDTEST1");
return fd;
}
@@ -583,15 +647,15 @@ SaAisErrorT log_stream_open_efop(log_str
if (stream->numOpeners == 0) {
/* Delete to get counting right. It might not exist. */
- (void)delete_config_file_fop(stream);
+ (void)delete_config_file_fh(stream);
/* Remove files from a previous life if needed */
- if (rotate_if_needed_fop(stream) == -1) {
+ if (rotate_if_needed_fh(stream) == -1) {
rc = SA_AIS_ERR_TRY_AGAIN;
goto done;
}
- if (lgs_make_dir_fop(lgs_cb->logsv_root_dir, stream->pathName)
!= 0){
+ if (lgs_make_dir_hfop(stream->pathName) != 0){
LOG_NO("Create directory '%s/%s' failed",
lgs_cb->logsv_root_dir, stream->pathName);
rc = SA_AIS_ERR_TRY_AGAIN;
goto done;
@@ -603,7 +667,7 @@ SaAisErrorT log_stream_open_efop(log_str
}
sprintf(stream->logFileCurrent, "%s_%s", stream->fileName,
lgs_get_time());
- if ((stream->fd = log_file_open_fop(stream, &errno_save)) ==
-1) {
+ if ((stream->fd = log_file_open_fh(stream, &errno_save)) == -1)
{
LOG_NO("Could not open '%s' - %s",
stream->logFileCurrent, strerror(errno_save));
rc = SA_AIS_ERR_TRY_AGAIN;
goto done;
@@ -628,7 +692,7 @@ SaAisErrorT log_stream_open_efop(log_str
goto done;
}
- if ((stream->fd = log_file_open_fop(stream, &errno_save)) ==
-1) {
+ if ((stream->fd = log_file_open_fh(stream, &errno_save)) == -1)
{
LOG_NO("Could not open '%s' - %s",
stream->logFileCurrent, strerror(errno_save));
rc = SA_AIS_ERR_TRY_AGAIN;
goto done;
@@ -662,7 +726,7 @@ int log_stream_close_efop(log_stream_t *
osafassert(stream->streamType == STREAM_TYPE_APPLICATION);
if (stream->fd != -1) {
char *timeString = lgs_get_time();
- if ((rc = fileclose_fop(stream->fd)) == -1) {
+ if ((rc = fileclose_hfop(stream->fd)) == -1) {
LOG_ER("log_stream_close FAILED: %s",
strerror(errno));
goto done;
}
@@ -702,7 +766,7 @@ int log_stream_file_close_efop(log_strea
osafassert(stream->numOpeners > 0);
if (stream->fd != -1) {
- if ((rc = fileclose_fop(stream->fd)) == -1) {
+ if ((rc = fileclose_hfop(stream->fd)) == -1) {
LOG_ER("log_stream_file_close FAILED: %s",
strerror(errno));
stream->fd = -1; /* Force reset the fd, otherwise fd
will be stale. */
} else
@@ -713,6 +777,7 @@ int log_stream_file_close_efop(log_strea
return rc;
}
+#if 0 /* replaced by file handler */
static int check_oldest(char *line, char *fname_prefix, int fname_prefix_size,
int *old_date, int *old_time)
{
int date, time, c, d;
@@ -772,7 +837,7 @@ static int filter_func(const struct dire
*
* @return int
*/
-static int get_number_of_log_files_fop(log_stream_t *logStream, char
*oldest_file)
+static int get_number_of_log_files_hfop(log_stream_t *logStream, char
*oldest_file)
{
struct dirent **namelist;
int n, old_date = -1, old_time = -1, old_ind = -1, files, i, failed = 0;
@@ -820,6 +885,46 @@ static int get_number_of_log_files_fop(l
return (files - failed);
}
+#endif
+
+/**
+ * Return number of log files in a dir and the name of the oldest file.
+ * @param logStream[in]
+ * @param oldest_file[out]
+ *
+ * @return int
+ */
+static int get_number_of_log_files_hfop(log_stream_t *logStream, char
*oldest_file)
+{
+ lgsf_apipar_t apipar;
+ lgsf_retcode_t api_rc;
+ gnolfh_in_t parameters_in;
+ int rc;
+
+ TRACE_ENTER2("LLDTEST");
+
+ strncpy(parameters_in.file_name, logStream->fileName, NAME_MAX+1);
+ strncpy(parameters_in.logsv_root_dir, lgs_cb->logsv_root_dir,
PATH_MAX+1);
+ strncpy(parameters_in.pathName, logStream->pathName, PATH_MAX+1);
+
+ /* Fill in API structure */
+ apipar.req_code_in = LGSF_GET_NUM_LOGFILES;
+ apipar.data_in_size = sizeof(gnolfh_in_t);
+ apipar.data_in = (void*) ¶meters_in;
+ apipar.data_out_size = (PATH_MAX + NAME_MAX);
+ apipar.data_out = (void *) oldest_file;
+
+ api_rc = log_file_api(&apipar);
+ if (api_rc != LGSF_SUCESS) {
+ TRACE("LLDTEST: %s - API error
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
+ rc = -1;
+ } else {
+ rc = apipar.hdl_ret_code_out;
+ }
+
+ TRACE_LEAVE2("LLDTEST");
+ return rc;
+}
/**
* log_stream_write will write a number of bytes to the associated file. If
@@ -843,10 +948,9 @@ int log_stream_write_efop(log_stream_t *
* enables LOG to cope with temporary file system problems. */
if (stream->fd == -1) {
-
/* Creating directory of given path to store log and cfg files,
* if not using shared file system. */
- if (lgs_make_dir_fop(lgs_cb->logsv_root_dir, stream->pathName)
!= 0) {
+ if (lgs_make_dir_hfop(stream->pathName) != 0) {
LOG_NO("Create directory '%s/%s' failed",
lgs_cb->logsv_root_dir, stream->pathName);
rc = -1;
goto done;
@@ -858,7 +962,7 @@ int log_stream_write_efop(log_stream_t *
goto done;
}
TRACE("stream: %s not opened, opening it now", stream->name);
- stream->fd = log_file_open_fop(stream, NULL);
+ stream->fd = log_file_open_fh(stream, NULL);
if (stream->fd == -1) {
rc = -1;
goto done;
@@ -890,7 +994,7 @@ int log_stream_write_efop(log_stream_t *
int errno_save;
char *current_time = lgs_get_time();
- if ((rc = fileclose_fop(stream->fd)) == -1) {
+ if ((rc = fileclose_hfop(stream->fd)) == -1) {
LOG_ER("close FAILED: %s", strerror(errno));
goto done;
}
@@ -904,12 +1008,12 @@ int log_stream_write_efop(log_stream_t *
stream->logFileCurrent[0] = 0;
/* Remove oldest file if needed */
- if ((rc = rotate_if_needed_fop(stream)) == -1)
+ if ((rc = rotate_if_needed_fh(stream)) == -1)
goto done;
stream->creationTimeStamp = lgs_get_SaTime();
sprintf(stream->logFileCurrent, "%s_%s", stream->fileName,
current_time);
- if ((stream->fd = log_file_open_fop(stream, &errno_save)) ==
-1) {
+ if ((stream->fd = log_file_open_fh(stream, &errno_save)) == -1)
{
LOG_NO("Could not open '%s' - %s",
stream->logFileCurrent, strerror(errno_save));
rc = -1;
goto done;
@@ -1100,7 +1204,7 @@ int log_stream_config_change_efop(bool c
} else {
/* close the existing log file, and only when there is a valid
fd */
- if ((rc = fileclose_fop(stream->fd)) == -1) {
+ if ((rc = fileclose_hfop(stream->fd)) == -1) {
LOG_ER("log_stream_config_change file close FAILED:
%s", strerror(errno));
goto done;
}
@@ -1122,7 +1226,7 @@ int log_stream_config_change_efop(bool c
sprintf(stream->logFileCurrent, "%s_%s", stream->fileName,
current_time);
/* Create the new log file based on updated configuration */
- stream->fd = log_file_open_fop(stream, NULL);
+ stream->fd = log_file_open_fh(stream, NULL);
}
if (stream->fd == -1)
diff --git a/osaf/services/saf/logsv/lgs/lgs_stream.h
b/osaf/services/saf/logsv/lgs/lgs_stream.h
--- a/osaf/services/saf/logsv/lgs/lgs_stream.h
+++ b/osaf/services/saf/logsv/lgs/lgs_stream.h
@@ -20,6 +20,7 @@
#include <limits.h>
#include "lgs_fmt.h"
+#include <ncspatricia.h>
/**
* Stream descriptor.
@@ -82,7 +83,7 @@ extern void log_stream_id_print(void);
#define LGS_STREAM_CREATE_FILES true
extern int log_stream_config_change_efop(bool create_files_f, log_stream_t
*stream, const char *current_file_name);
-extern int log_file_open_fop(log_stream_t *stream, int *errno_save);
+extern int log_file_open_fh(log_stream_t *stream, int *errno_save);
/* Accessor functions */
extern log_stream_t *log_stream_get_by_name_nof(const char *name);
diff --git a/osaf/services/saf/logsv/lgs/lgs_util.c
b/osaf/services/saf/logsv/lgs/lgs_util.c
--- a/osaf/services/saf/logsv/lgs/lgs_util.c
+++ b/osaf/services/saf/logsv/lgs/lgs_util.c
@@ -15,6 +15,24 @@
*
*/
+/*****************************************************************************
+ * Important information
+ * ---------------------
+ * To prevent log service thread from "hanging" if communication with NFS is
+ * not working or is very slow all functions using file I/O must run their file
+ * handling in a separate thread.
+ * For more information on how to do that see the following files:
+ * lgs_file.h, lgs_file.c, lgs_filendl.c and lgs_filehdl.h
+ * Examples can be found in file lgs_stream.c, e.g. function fileopen(...)
+ */
+
+/* TODO LLDTEST:
+ * Move all _fop to lgs_filehdl.c
+ * Handle all _efop via file thread
+ * Make sure that all functions used by _fop and _efop are thread safe. For
+ * such functions, add info "Must be thread safe" in header (-ts function)
+ */
+
#include <stdlib.h>
#include <inttypes.h>
#include <sys/stat.h>
@@ -22,6 +40,7 @@
#include "lgs.h"
#include "lgs_util.h"
#include "lgs_fmt.h"
+#include "lgs_file.h"
#define ALARM_STREAM_ENV_PREFIX "ALARM"
#define NOTIFICATION_STREAM_ENV_PREFIX "NOTIFICATION"
@@ -52,8 +71,8 @@ int lgs_create_config_file_efop(log_stre
/* check the existence of logsv_root_dir/pathName, create the path if
it doesn't */
snprintf(pathname, PATH_MAX, "%s/%s", lgs_cb->logsv_root_dir,
stream->pathName);
struct stat statbuf;
- if (lgs_relative_path_check(pathname) || lstat(pathname, &statbuf) !=
0) {
- if (lgs_make_dir_fop(lgs_cb->logsv_root_dir, stream->pathName)
!= 0) {
+ if (lgs_relative_path_check_ts(pathname) || lstat(pathname, &statbuf)
!= 0) {
+ if (lgs_make_dir_hfop(stream->pathName) != 0) {
LOG_NO("Create directory '%s/%s' failed",
lgs_cb->logsv_root_dir, stream->pathName);
rc = -1;
goto done;
@@ -291,9 +310,12 @@ void lgs_free_write_log(const lgsv_write
/**
* Check if a relative ("/../") path occurs in the path.
+ * Note: This function must be thread safe
+ *
* @param path
+ * @return true if path is allowed
*/
-bool lgs_relative_path_check(const char* path)
+bool lgs_relative_path_check_ts(const char* path)
{
bool rc = false;
int len_path = strlen(path);
@@ -308,6 +330,7 @@ bool lgs_relative_path_check(const char*
return rc;
}
+#if 0
static void quick_fix_make_root_dir_fop(const char* root_dir)
{
struct stat statbuf;
@@ -330,8 +353,9 @@ static void quick_fix_make_root_dir_fop(
/**
* Create directory structure, if not already created.
* @param path
+ * @return -1 on error
*/
-int lgs_make_dir_fop(const char* root, const char* path)
+int lgs_make_dir_hfop(const char* root, const char* path)
{
int rc = 0;
const int MAX_DEPTH = 10;
@@ -354,13 +378,13 @@ int lgs_make_dir_fop(const char* root, c
}
/* end tempoarary fix */
- if (lgs_relative_path_check(root) || lstat(root, &statbuf) != 0 ||
+ if (lgs_relative_path_check_ts(root) || lstat(root, &statbuf) != 0 ||
(strlen(root) + strlen(path) + 2) > (PATH_MAX +
NAME_MAX)) {
LOG_ER("root directory problem %s", root);
rc = -1;
goto done;
}
- if (lgs_relative_path_check(path)) {
+ if (lgs_relative_path_check_ts(path)) {
LOG_ER("relative path in directory %s", path);
rc = -1;
goto done;
@@ -404,3 +428,64 @@ done:
TRACE_LEAVE2("%u", rc);
return rc;
}
+#endif
+
+/**
+ * Create directory structure, if not already created.
+ * The structure is created in the log service root directory pointed to in
+ * lgs_cb->logsv_root_dir.
+ *
+ * Note: If the lgsv root directory does not exist a root directory is
+ * created based on the default path in PKGLOGDIR. The path in the
configuration
+ * object is not updated. The reason is to make it possible for the log service
+ * to work even if there is no existing root path in the file system.
+ *
+ * @param path, Path relative log service root directory
+ * @return -1 on error
+ */
+int lgs_make_dir_hfop(const char* path)
+{
+ lgsf_apipar_t apipar;
+ lgsf_retcode_t api_rc;
+ int rc = -1;
+ mld_in_t params_in;
+ char new_rootstr[PATH_MAX + NAME_MAX+2];
+ //const int MAX_DEPTH = 10;
+ //int dir_depth_cnt;
+ //char *dirdc_p;
+
+ TRACE_ENTER2("LLDTEST");
+
+ /* Check depth of path */
+// while (strchr)
+
+ strncpy(params_in.root_dir, lgs_cb->logsv_root_dir, PATH_MAX+1);
+ strncpy(params_in.rel_path, path, PATH_MAX+1);
+ TRACE("LLDTEST: %s - root_dir \"%s\"",__FUNCTION__,params_in.root_dir);
+ TRACE("LLDTEST: %s - rel_path \"%s\"",__FUNCTION__,params_in.rel_path);
+
+ /* Fill in API structure */
+ apipar.req_code_in = LGSF_MAKELOGDIR;
+ apipar.data_in_size = sizeof(mld_in_t);
+ apipar.data_in = (void*) ¶ms_in;
+ apipar.data_out_size = PATH_MAX + NAME_MAX;
+ apipar.data_out = &new_rootstr;
+
+ api_rc = log_file_api(&apipar);
+ if (api_rc != LGSF_SUCESS) {
+ TRACE("LLDTEST: %s - API error %d",__FUNCTION__,api_rc);
+ rc = -1;
+ } else {
+ rc = apipar.hdl_ret_code_out;
+ }
+
+ /* Handle a possible change of root dir to default */
+ if (new_rootstr[0] != '\0') {
+ lgs_imm_rootpathconf_set(new_rootstr);
+ TRACE("LLDTEST: %s - new_rootstr
\"%s\"",__FUNCTION__,new_rootstr);
+ }
+
+ TRACE_LEAVE2("LLDTEST");
+
+ return rc;
+}
\ No newline at end of file
diff --git a/osaf/services/saf/logsv/lgs/lgs_util.h
b/osaf/services/saf/logsv/lgs/lgs_util.h
--- a/osaf/services/saf/logsv/lgs/lgs_util.h
+++ b/osaf/services/saf/logsv/lgs/lgs_util.h
@@ -23,6 +23,11 @@
* ========================================================================
*/
#include <string.h>
+#include <saAis.h>
+#include <saAmf.h>
+
+#include "lgs_stream.h"
+#include "lgs_evt.h"
/* ========================================================================
* DEFINITIONS
@@ -46,7 +51,7 @@ extern SaTimeT lgs_get_SaTime(void);
extern int lgs_file_rename_fop(const char *path, const char *old_name, const
char *time_stamp, const char *suffix);
//extern uint32_t lgs_create_known_streams(lgs_cb_t *lgs_cb); /* Not used, no
code */
extern void lgs_exit(const char *msg, SaAmfRecommendedRecoveryT rec_rcvr);
-extern bool lgs_relative_path_check(const char* path);
-extern int lgs_make_dir_fop(const char* root, const char* path);
+extern bool lgs_relative_path_check_ts(const char* path);
+extern int lgs_make_dir_hfop(const char* path);
#endif /* ifndef __LGS_UTIL_H */
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel