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*) &parameters_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*) &params_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

Reply via email to