More functions converted to use threaded file handling:
- check_path_exists_hdl(..)
- This is the first inc for error handling updates.

diff --git a/README_LOGENH b/README_LOGENH
new file mode 100644
--- /dev/null
+++ b/README_LOGENH
@@ -0,0 +1,36 @@
+DESCRIPTION OF ONGOING ENHANCEMENT
+----------------------------------
+
+See ticket #9 and #124. The main problem to solve ist to prevent the log 
service to "hang",
+including e.g. not beeing able to handle health check etc. when the 
communication with a
+NFS file system is broken.
+
+This is not done by creating a thread for each stream and asynch IO is not 
used either, as
+suggested in #9.
+This enhancement creates a second thread and functions or parts of functions  
using file IO
+are moved to this thread.
+
+The enhancement is done i three steps:
+1.  Create a mechanism that can handle functions with in and out parameters 
and that times out
+    if such a function does not return "hangs". See lgs_file.c
+
+2.  Use 1. to handle already existing complete functions or parts of functions 
that has any type
+    of interaction with the file system. This is done without changing any of 
the existing structure
+    of the log service. Affected functions remains "as is" with the same in 
and out parameters as before,
+    but internally all or some of the code is moved to a "handler" that is 
running in the second thread.
+    The original function will now return with error instead of "hang" if an 
operation including file IO
+    "hangs". See lgs_filehdl.c, lgs_stream.c and lgs_util.c
+
+3.  Handle new error situations that may occur. Log streams can now be created 
and opened even if the
+    corresponding files cannot be handled. If a stream is opened without 
creating files an attempt to
+    create the files is done when a client tries to write a log record.
+    In this version the callback function will report "TRY AGAIN" if the 
logserver fails to write the
+    log record. This is the same behaviour as before, the only difference is 
that i may happen also if
+    there is communication problems with the file system.
+
+TODO
+----
+
+Handling of streams via IMM objects has to be improved. E.g. Some admin 
operations must be rejected if
+the filsystem is not available e.g. creating a new stream with a configuration 
object.
+
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
@@ -75,6 +75,12 @@
 /* The name of log service config object */    
 #define LGS_IMM_LOG_CONFIGURATION      "logConfig=1,safApp=safLogService"
 
+/* The maximum size of a path to a file. A path normally consists of
+ * a root path (PATH_MAX), a relative path (PATH_MAX) and a file name 
(NAME_MAX)
+ */
+#define LGS_FILEPATH_MAX (PATH_MAX + PATH_MAX + NAME_MAX)
+#define LGS_DIRPATH_MAX (PATH_MAX + PATH_MAX)
+
 /* ========================================================================
  *   TYPE DEFINITIONS
  * ========================================================================
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.c 
b/osaf/services/saf/logsv/lgs/lgs_evt.c
--- a/osaf/services/saf/logsv/lgs/lgs_evt.c
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.c
@@ -707,6 +707,10 @@ static uint32_t lgs_ckpt_stream_open(lgs
 
                ckpt.ckpt_rec.stream_open.streamType = logStream->streamType;
                ckpt.ckpt_rec.stream_open.logRecordId = logStream->logRecordId;
+               
+               ckpt.ckpt_rec.stream_open.files_initiated = 
logStream->files_initiated;
+               TRACE("LLDTEST2: %s - logFileCurrent 
\"%s\"",__FUNCTION__,logStream->logFileCurrent);
+               TRACE("LLDTEST2: %s - files_initiated = 
%d",__FUNCTION__,logStream->files_initiated);
 
                async_rc = lgs_ckpt_send_async(cb, &ckpt, NCS_MBCSV_ACT_ADD);
                if (async_rc == NCSCC_RC_SUCCESS) {
@@ -1082,6 +1086,9 @@ static uint32_t proc_write_log_async_msg
                ckpt.ckpt_rec.write_log.streamId = stream->streamId;
                ckpt.ckpt_rec.write_log.curFileSize = stream->curFileSize;
                ckpt.ckpt_rec.write_log.logFileCurrent = stream->logFileCurrent;
+               ckpt.ckpt_rec.write_log.files_initiated = 
stream->files_initiated;
+               TRACE("LLDTEST2: %s - logFileCurrent 
\"%s\"",__FUNCTION__,stream->logFileCurrent);
+               TRACE("LLDTEST2: %s - files_initiated = 
%d",__FUNCTION__,stream->files_initiated);
 
                (void)lgs_ckpt_send_async(cb, &ckpt, NCS_MBCSV_ACT_ADD);
        }
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
@@ -123,6 +123,12 @@ static void *file_hndl_thread(void *nopa
        void *outbuf;
        uint32_t max_outsize;
        
+//#define LLD_DELAY_TST
+#ifdef LLD_DELAY_TST /* LLDTEST Let "file system" hang for n sec after start */
+       static bool lld_start_f = true;
+       const unsigned int lld_sleep_sec = 3600;
+#endif
+       
        TRACE("LLDTEST: %s - is started",__FUNCTION__);
        
        osaf_mutex_lock_ordie(&lgs_ftcom_mutex); /* LOCK */
@@ -159,6 +165,16 @@ static void *file_hndl_thread(void *nopa
                         * assumed to know the data format.
                         */
                        osaf_mutex_unlock_ordie(&lgs_ftcom_mutex); /* UNLOCK */
+               
+#ifdef LLD_DELAY_TST /* LLDTEST Wait first time thread is used */
+                       if (lld_start_f == true) {
+                               lld_start_f = false;
+                               TRACE("LLDTEST1: file_hndl_thread sleeping");
+                               sleep(lld_sleep_sec);
+                               goto lld_wait_end;
+                       }
+#endif
+                       
                        switch (lgs_com_data.request_code)      {
                        case LGSF_FILEOPEN:
                                TRACE("LLDTEST: %s - LGSF_FILEOPEN 
received",__FUNCTION__);
@@ -192,9 +208,18 @@ static void *file_hndl_thread(void *nopa
                                TRACE("LLDTEST: %s - LGSF_RENAME_FILE 
received",__FUNCTION__);
                                hndl_rc = rename_file_hdl(inbuf, outbuf, 
max_outsize);
                                break;
+                       case LGSF_CHECKPATH:
+                               TRACE("LLDTEST: %s - LGSF_CHECKPATH 
received",__FUNCTION__);
+                               hndl_rc = check_path_exists_hdl(inbuf, outbuf, 
max_outsize);
                        default:
                                break;
                        }
+                       
+#ifdef LLD_DELAY_TST
+                       lld_wait_end:
+                               TRACE("LLDTEST1: file_hndl_thread is awake!");
+#endif
+                       
                        osaf_mutex_lock_ordie(&lgs_ftcom_mutex); /* LOCK */
 
                        /* Handle answer flag and return data
@@ -224,8 +249,8 @@ static void *file_hndl_thread(void *nopa
                        } else {
                                free(outbuf);
                        }
-               }               
-       }
+               }       
+       } /* End while(1) */
 }
 
 /**
@@ -311,7 +336,8 @@ lgsf_retcode_t log_file_api(lgsf_apipar_
         */
        if (lgs_com_data.request_f == true) {
                api_rc = LGSF_BUSY;
-               goto done;
+               TRACE("LLDTEST: %s - LGSF_BUSY",__FUNCTION__);
+               goto api_exit;
        }
        
        /* Enter data for a request */
@@ -331,7 +357,7 @@ lgsf_retcode_t log_file_api(lgsf_apipar_
        }
        lgs_com_data.outdata_size = apipar_in->data_out_size;
        
-       lgs_com_data.request_f = true;  /* We have a request */
+       lgs_com_data.request_f = true;  /* We have a pending request */
        lgs_com_data.timeout_f = false;
        
        /* Wake up the thread */
@@ -382,8 +408,10 @@ lgsf_retcode_t log_file_api(lgsf_apipar_
        
 done:
        /* Prepare for new request/answer cycle */
-       free(lgs_com_data.indata);
-       free(lgs_com_data.outdata);
+       if (lgs_com_data.indata != NULL) free(lgs_com_data.indata);
+       if (lgs_com_data.outdata != NULL) free(lgs_com_data.outdata);
+
+api_exit:
        osaf_mutex_unlock_ordie(&lgs_ftcom_mutex); /* UNLOCK */
        TRACE_LEAVE2("LLDTEST");
        return api_rc;  
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
@@ -44,6 +44,7 @@ typedef enum {
        LGSF_WRITELOGREC,
        LGSF_CREATECFGFILE,
        LGSF_RENAME_FILE,
+       LGSF_CHECKPATH,
        LGSF_NOREQ
 }lgsf_treq_t;
 
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
@@ -56,6 +56,24 @@
  *****************************************************************************/
 
 /**
+ * Check if a path exists. See also stat(..)
+ * 
+ * @param indata[in] path[]
+ * @param outdata[out] Not used
+ * @param max_outsize[in] Must be 0
+ * @return (-1) if not exists, 0 if exists
+ */
+int check_path_exists_hdl(void *indata, void *outdata, size_t max_outsize)
+{
+       struct stat pathstat;
+       char *path_str = (char *) indata;
+       int rc = 0;
+       
+       rc = stat(path_str, &pathstat);
+       return rc;
+}
+
+/**
  * Rename a file
  * 
  * @param indata[in] old_path[], new_path[]
@@ -211,7 +229,7 @@ int make_log_dir_hdl(void *indata, void 
        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 mpath[PATH_MAX + PATH_MAX+2];
        char *spath_p;
        char *epath_p;
        struct stat statbuf;
@@ -235,6 +253,7 @@ int make_log_dir_hdl(void *indata, void 
                strncpy(out_path, rootpath, max_outsize);
 #endif
                LOG_NO("LOG Root path does not exist. Will be created");
+               TRACE("LLDTEST: %s - create rootpath 
\"%s\"",__FUNCTION__,rootpath);
        }
        
        /* Create complete path string */
@@ -432,7 +451,7 @@ int get_number_of_log_files_hdl(void *in
 {
        struct dirent **namelist;
        int n, old_date = -1, old_time = -1, old_ind = -1, files, i, failed = 0;
-       char path[PATH_MAX];
+       char path[LGS_DIRPATH_MAX];
        gnolfh_in_t *params_in;
        char *oldest_file;
        int rc;
@@ -445,9 +464,9 @@ int get_number_of_log_files_hdl(void *in
        /* Initialize the filter */
        strncpy(file_prefix, params_in->file_name, NAME_MAX);
 
-       n = snprintf(path, PATH_MAX, "%s/%s",
+       n = snprintf(path, LGS_DIRPATH_MAX, "%s/%s",
                        params_in->logsv_root_dir, params_in->pathName);
-       if (n >= PATH_MAX) {
+       if (n >= LGS_DIRPATH_MAX) {
                LOG_ER("Parameter error: Path is longer than PATH_MAX");
                rc = -1;
                goto done_exit;
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
@@ -124,6 +124,16 @@ typedef struct {
  * No out parameters
  */
 
+/*
+ * check_path_exists_hdl(..)
+ * 
+ * Inpar:
+ * char path_str[], string containing path to check
+ * 
+ * No out parameters
+ */
+
+int check_path_exists_hdl(void *indata, void *outdata, size_t max_outsize);
 int rename_file_hdl(void *indata, void *outdata, size_t max_outsize);
 int create_config_file_hdl(void *indata, void *outdata, size_t max_outsize);
 int write_log_record_hdl(void *indata, void *outdata, size_t max_outsize);
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
@@ -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 file lgs_stream.c, e.g. function fileopen(...)
+ */
+
 #include <poll.h>
 #include <stdio.h>
 #include <errno.h>
@@ -179,7 +190,7 @@ static uint32_t ckpt_stream_open_close(l
  * return: true  = Path is valid
  *         false = Path is invalid
  */
-static bool path_is_writeable_dir(const char *pathname)
+static bool path_is_writeable_dir_fop(const char *pathname)
 {
        bool is_writeable_dir = false;
        struct stat pathstat;
@@ -412,7 +423,7 @@ static SaAisErrorT config_ccb_completed_
 
                if (!strcmp(attribute->attrName, "logRootDirectory")) {
                        char *pathName = *((char **)value);
-                       if (!path_is_writeable_dir(pathName)) {
+                       if (!path_is_writeable_dir_fop(pathName)) {
                                LOG_NO("pathName: %s is NOT accepted", 
pathName);
                                rc = SA_AIS_ERR_BAD_OPERATION;
                                goto done;
@@ -497,7 +508,7 @@ static SaAisErrorT config_ccb_completed(
  *
  * @return SaAisErrorT
  */
-static SaAisErrorT check_attr_validity(const struct CcbUtilOperationData 
*opdata)
+static SaAisErrorT check_attr_validity_fop(const struct CcbUtilOperationData 
*opdata)
 {
        SaAisErrorT rc = SA_AIS_OK;
        void *value;
@@ -525,16 +536,13 @@ static SaAisErrorT check_attr_validity(c
                        TRACE("attribute %s", attribute->attrName);
 
                        if (!strcmp(attribute->attrName, 
"saLogStreamFileName")) {
-                               struct stat pathstat;
                                char *fileName = *((char **) value);
-                               if (stat(fileName, &pathstat) == 0) {
-
+                               if (lgs_check_path_exists(fileName) == 0) {
                                        LOG_ER("File %s already exist", 
fileName);
                                        rc = SA_AIS_ERR_EXIST;
                                }
                                TRACE("fileName: %s", fileName);
                        } else if (!strcmp(attribute->attrName, 
"saLogStreamPathName")) {
-                               struct stat pathstat;
                                char fileName[PATH_MAX];
                                strcpy(fileName, lgs_cb->logsv_root_dir);
                                strcat(fileName, "//");
@@ -543,7 +551,7 @@ static SaAisErrorT check_attr_validity(c
                                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) {
+                               } else if 
(lgs_check_path_exists(lgs_cb->logsv_root_dir) != 0) {
                                        LOG_ER("Path %s does not exist", 
fileName);
                                        rc = SA_AIS_ERR_BAD_OPERATION;
                                }
@@ -643,7 +651,7 @@ static SaAisErrorT stream_ccb_completed_
        SaAisErrorT rc = SA_AIS_ERR_BAD_OPERATION;
 
        TRACE_ENTER2("CCB ID %llu", opdata->ccbId);
-       rc = check_attr_validity(opdata);
+       rc = check_attr_validity_fop(opdata);
        TRACE_LEAVE2("%u", rc);
        return rc;
 }
@@ -653,7 +661,7 @@ static SaAisErrorT stream_ccb_completed_
        SaAisErrorT rc;
 
        TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId, 
opdata->objectName.value);
-       rc = check_attr_validity(opdata);
+       rc = check_attr_validity_fop(opdata);
        TRACE_LEAVE2("%u", rc);
        return rc;
 }
@@ -780,7 +788,7 @@ static SaAisErrorT ccbCompletedCallback(
  *
  * @param logRootDirectory
  */
-static void logRootDirectory_set(const char *logRootDirectory)
+static void logRootDirectory_set_hf(const char *logRootDirectory)
 {
        log_stream_t *stream;
        char *current_time = lgs_get_time();
@@ -841,7 +849,7 @@ static void config_ccb_apply_modify(cons
                        const char *logRootDirectory = *((char **)value);
 
                        if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE) {
-                               logRootDirectory_set(logRootDirectory);
+                               logRootDirectory_set_hf(logRootDirectory);
                        } else {
                                strcpy(lgs_conf->logRootDirectory, 
logRootDirectory);
                        }
@@ -873,7 +881,7 @@ static void config_ccb_apply(const CcbUt
                osafassert(0);
                break;
        default:
-               assert(0);
+               osafassert(0);
                break;
        }
 
@@ -1087,6 +1095,7 @@ static void stream_ccb_apply_delete(cons
 
        /* Checkpoint to standby LOG server */
        ckpt_stream_open_close(stream, LGS_CKPT_CLOSE_STREAM);
+       TRACE("LLDTEST: %s - log_stream_close_hfop()",__FUNCTION__);
        log_stream_close_hfop(&stream);
 }
 
@@ -1849,7 +1858,11 @@ SaAisErrorT lgs_imm_activate_hfop(lgs_cb
                                       "saLogStreamCreationTimestamp", 
SA_IMM_ATTR_SATIMET,
                                       &cb->systemStream->creationTimeStamp);
 
-       /* Open all streams */
+       /* Open all streams
+        * Config file and log file will be created. If this fails we give up
+        * without returning any error. A new attempt to create the files will
+        * be done when trying to write a log record to the stream.
+        */
        stream = log_stream_getnext_by_name_nof(NULL);
        while (stream != NULL) {
                if (log_stream_open_fh(stream) != SA_AIS_OK)
diff --git a/osaf/services/saf/logsv/lgs/lgs_mbcsv.c 
b/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
--- a/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
+++ b/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
@@ -1095,6 +1095,9 @@ static uint32_t ckpt_proc_log_write(lgs_
        stream->logRecordId = param->recordId;
        stream->curFileSize = param->curFileSize;
        strcpy(stream->logFileCurrent, param->logFileCurrent);
+       stream->files_initiated = param->files_initiated; /* LLDTEST */
+       TRACE("LLDTEST2: %s - logFileCurrent 
\"%s\"",__FUNCTION__,stream->logFileCurrent);
+       TRACE("LLDTEST2 %s - stream->files_initiated = 
%d",__FUNCTION__,stream->files_initiated);
 
  done:
        free_edu_mem(param->logFileCurrent);
@@ -1132,6 +1135,7 @@ static uint32_t ckpt_proc_close_stream(l
 
        (void)lgs_client_stream_rmv(param->clientId, param->streamId);
 
+       TRACE("LLDTEST: %s - log_stream_close_hfop()",__FUNCTION__);
        if (log_stream_close_hfop(&stream) != 0) {
                /* Do not allow standby to get out of sync */
                lgs_exit("Client attributes differ", SA_AMF_COMPONENT_RESTART);
@@ -1160,6 +1164,7 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t 
 {
        lgs_ckpt_stream_open_t *param = &data->ckpt_rec.stream_open;
        log_stream_t *stream;
+       int lldi=1; /*LLDTEST remove*/
 
        TRACE_ENTER();
 
@@ -1168,6 +1173,7 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t 
                LOG_WA("Client %u does not exist, failed to create stream 
'%s'", param->clientId, param->logStreamName);
                goto done;
        }
+       TRACE("LLDTEST1 - %d",lldi++);
 
        stream = log_stream_get_by_name_nof(param->logStreamName);
        if (stream != NULL) {
@@ -1184,18 +1190,24 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t 
                strcpy((char *)name.value, param->logStreamName);
                name.length = strlen(param->logStreamName);
 
+               TRACE("LLDTEST1 - %d",lldi++);
                stream = log_stream_new_nof(&name, param->logFile, 
param->logPath, param->maxFileSize, param->maxLogRecordSize, 
param->logFileFullAction, param->maxFilesRotated, param->fileFmt, 
param->streamType, param->streamId, SA_FALSE, // FIX sync or calculate?
                                        param->logRecordId);
 
+               TRACE("LLDTEST1 - %d",lldi++);
                if (stream == NULL) {
                        /* Do not allow standby to get out of sync */
                        LOG_ER("Failed to create stream '%s'", 
param->logStreamName);
                        goto done;
                }
 
+               TRACE("LLDTEST1 - %d",lldi++);
                stream->numOpeners = param->numOpeners;
                stream->creationTimeStamp = param->creationTimeStamp;
                strcpy(stream->logFileCurrent, param->logFileCurrent);
+               stream->files_initiated = param->files_initiated; /* LLDTEST */
+               TRACE("LLDTEST2: %s - logFileCurrent 
\"%s\"",__FUNCTION__,stream->logFileCurrent);
+               TRACE("LLDTEST2: %s - stream->files_initiated = 
%d",__FUNCTION__,stream->files_initiated);
        }
 
        log_stream_print(stream);
@@ -1204,13 +1216,16 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t 
         ** Create an association between this client_id and the stream
         ** A client ID of -1 indicates that no client exist, skip this step.
         */
+       TRACE("LLDTEST1 - %d",lldi++);
        if ((param->clientId != -1) && lgs_client_stream_add(param->clientId, 
stream->streamId) != 0) {
                /* Do not allow standby to get out of sync */
                LOG_ER("Failed to add stream '%s' to client %u", 
param->logStreamName, param->clientId);
                lgs_exit("Could not add stream to client", 
SA_AMF_COMPONENT_RESTART);
        }
 
+       TRACE("LLDTEST1 - %d",lldi++);
  done:
+       TRACE("LLDTEST1 - %d",lldi++);
        /* Free strings allocated by the EDU encoder */
        free_edu_mem(param->logFile);
        free_edu_mem(param->logPath);
@@ -1319,6 +1334,9 @@ static uint32_t ckpt_proc_cfg_stream(lgs
        strcpy(stream->logFileFormat, param->logFileFormat);
        stream->severityFilter = param->severityFilter;
        strcpy(stream->logFileCurrent, param->logFileCurrent);
+       stream->files_initiated = param->files_initiated;
+       TRACE("LLDTEST2: %s - logFileCurrent 
\"%s\"",__FUNCTION__,stream->logFileCurrent);
+       TRACE("LLDTEST2 %s - files_initiated 
=%d",__FUNCTION__,param->files_initiated);
 
  done:
        /* Free strings allocated by the EDU encoder */
@@ -1376,6 +1394,7 @@ uint32_t lgs_ckpt_send_async(lgs_cb_t *c
        /* Send async update */
        if (NCSCC_RC_SUCCESS != (rc = ncs_mbcsv_svc(&mbcsv_arg))) {
                LOG_ER("MBCSV send FAILED rc=%u.", rc);
+               TRACE("LLDTEST2: %s - MBCSV send FAILED rc=%u.",__FUNCTION__, 
rc);
                TRACE_LEAVE();
                return NCSCC_RC_FAILURE;
        }
@@ -1567,9 +1586,12 @@ static uint32_t edp_ed_write_rec(EDU_HDL
                {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_write_log_t *)0)->streamId, 0, NULL},
                {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_write_log_t *)0)->curFileSize, 0, NULL},
                {EDU_EXEC, ncs_edp_string, 0, 0, 0, 
(long)&((lgs_ckpt_write_log_t *)0)->logFileCurrent, 0, NULL},
+               {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_write_log_t *)0)->files_initiated, 0, NULL},
                {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
        };
 
+       TRACE("LLDTEST2: %s",__FUNCTION__);
+       
        if (op == EDP_OP_TYPE_ENC) {
                ckpt_write_msg_ptr = (lgs_ckpt_write_log_t *)ptr;
        } else if (op == EDP_OP_TYPE_DEC) {
@@ -1633,6 +1655,7 @@ static uint32_t edp_ed_open_stream_rec(E
                {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_stream_open_t *)0)->numOpeners, 0, NULL},
                {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_stream_open_t *)0)->streamType, 0, NULL},
                {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_stream_open_t *)0)->logRecordId, 0, NULL},
+               {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_stream_open_t *)0)->files_initiated, 0, NULL},
                {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
        };
 
@@ -1800,6 +1823,7 @@ static uint32_t edp_ed_cfg_stream_rec(ED
                {EDU_EXEC, ncs_edp_string, 0, 0, 0, 
(long)&((lgs_ckpt_stream_cfg_t *)0)->logFileFormat, 0, NULL},
                {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_stream_cfg_t *)0)->severityFilter, 0, NULL},
                {EDU_EXEC, ncs_edp_string, 0, 0, 0, 
(long)&((lgs_ckpt_stream_cfg_t *)0)->logFileCurrent, 0, NULL},
+               {EDU_EXEC, ncs_edp_uns32, 0, 0, 0, 
(long)&((lgs_ckpt_stream_cfg_t *)0)->files_initiated , 0, NULL},
                {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
        };
 
diff --git a/osaf/services/saf/logsv/lgs/lgs_mbcsv.h 
b/osaf/services/saf/logsv/lgs/lgs_mbcsv.h
--- a/osaf/services/saf/logsv/lgs/lgs_mbcsv.h
+++ b/osaf/services/saf/logsv/lgs/lgs_mbcsv.h
@@ -60,6 +60,7 @@ typedef struct {
        uint32_t recordId;
        uint32_t curFileSize;
        char *logFileCurrent;
+       bool files_initiated; /* LLDTEST */
 } lgs_ckpt_write_log_t;
 
 typedef struct {
@@ -80,6 +81,7 @@ typedef struct {
        char *logFileCurrent;
        logStreamTypeT streamType;
        uint32_t logRecordId;   /* log record indentifier increased for each 
record */
+       bool files_initiated; /* LLDTEST */
 } lgs_ckpt_stream_open_t;
 
 typedef struct {
@@ -109,6 +111,7 @@ typedef struct {
        char *logFileFormat;
        SaUint32T severityFilter;
        char *logFileCurrent;
+       bool files_initiated; /* LLDTEST */
 } lgs_ckpt_stream_cfg_t;
 
 typedef struct {
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
@@ -72,7 +72,7 @@ static int fileopen_hfop(char *filepath,
        
        api_rc = log_file_api(&apipar);
        if (api_rc != LGSF_SUCESS) {
-               TRACE("%s - API error %d",__FUNCTION__,api_rc);
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
                fd = -1;
        } else {
                fd = apipar.hdl_ret_code_out;
@@ -105,7 +105,7 @@ static int fileclose_hfop(int fd)
        
        api_rc = log_file_api(&apipar);
        if (api_rc != LGSF_SUCESS) {
-               TRACE("%s - API error %d",__FUNCTION__,api_rc);
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
                rc = -1;
        } else {
                rc = apipar.hdl_ret_code_out;
@@ -160,12 +160,12 @@ static int file_unlink_hfop(char *filepa
 static int delete_config_file_fh(log_stream_t *stream)
 {
        int rc, n;
-       char pathname[PATH_MAX + NAME_MAX];
+       char pathname[LGS_FILEPATH_MAX];
 
        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);
+       n = snprintf(pathname, LGS_FILEPATH_MAX, "%s/%s/%s.cfg", 
lgs_cb->logsv_root_dir, stream->pathName, stream->fileName);
 
        osafassert(n < sizeof(pathname));
 
@@ -177,7 +177,7 @@ static int delete_config_file_fh(log_str
 
 static int rotate_if_needed_fh(log_stream_t *stream)
 {
-       char oldest_file[PATH_MAX + NAME_MAX];
+       char oldest_file[LGS_FILEPATH_MAX];
        int rc = 0;
        int file_cnt;
 
@@ -253,6 +253,61 @@ static uint32_t log_stream_remove_nof(co
        return rc;
 }
 
+/**
+ * Initiate the files belonging to a stream if they are not already initiated.
+ * The stream->files_initiated flag is set when the files are initiated.
+ * If the files could not be initiated e.g. the file system is not working, the
+ * files_initiated flag will not be set.
+ * This function should be used when a stream is opened and every time a log
+ * record is written.
+ * 
+ * @param stream
+ */
+static void log_initiate_stream_files(log_stream_t *stream)
+{
+       int errno_save;
+       
+       TRACE_ENTER2("LLDTEST");
+       TRACE("LLDTEST %s - stream->files_initiated = 
%d",__FUNCTION__,stream->files_initiated);
+       
+       if (stream->files_initiated == false) {
+               TRACE("LLDTEST: %s - Creating new files",__FUNCTION__);
+               
+               /* Delete to get counting right. It might not exist. */
+               (void)delete_config_file_fh(stream);
+
+               /* Save what filename that shall be the current log file */
+               sprintf(stream->logFileCurrent, "%s_%s", stream->fileName, 
lgs_get_time());
+
+               /* Remove files from a previous life if needed */
+               if (rotate_if_needed_fh(stream) == -1) {
+                       TRACE("LLDTEST: %s - rotate_if_needed_fh() 
FAIL",__FUNCTION__);
+                       goto done;
+               }
+
+               if (lgs_make_dir_hfop(stream->pathName) != 0){
+                       TRACE("LLDTEST: %s - lgs_make_dir_hfop() 
FAIL",__FUNCTION__);
+                       goto done;
+               }
+
+               if (lgs_create_config_file_hfop(stream) != 0) {
+                       TRACE("LLDTEST: %s - lgs_create_config_file_hfop() 
FAIL",__FUNCTION__);
+                       goto done;
+               }
+
+               if ((stream->fd = log_file_open_fh(stream, &errno_save)) == -1) 
{
+                       TRACE("LLDTEST: %s - Could not open '%s' - 
%s",__FUNCTION__,
+                                       stream->logFileCurrent, 
strerror(errno_save));
+                       goto done;
+               }
+               
+               stream->files_initiated = true;
+       }
+       
+done:
+       TRACE_LEAVE2("LLDTEST");
+}
+
 log_stream_t *log_stream_get_by_name_nof(const char *name)
 {
        char nname[SA_MAX_NAME_LENGTH + 1];
@@ -633,6 +688,7 @@ int log_file_open_fh(log_stream_t *strea
        return fd;
 }
 
+#if 0
 SaAisErrorT log_stream_open_fh(log_stream_t *stream)
 {
        SaAisErrorT rc = SA_AIS_OK;
@@ -700,6 +756,40 @@ SaAisErrorT log_stream_open_fh(log_strea
        TRACE_LEAVE2("rc=%u, numOpeners=%u", rc, stream->numOpeners);
        return rc;
 }
+#endif
+
+SaAisErrorT log_stream_open_fh(log_stream_t *stream)
+{
+       SaAisErrorT rc = SA_AIS_OK;
+       
+       osafassert(stream != NULL);
+       TRACE_ENTER2("%s, numOpeners=%u", stream->name, stream->numOpeners);
+
+       /* first time open? */
+       if (stream->numOpeners == 0) {
+               TRACE("LLDTEST3 %s name \"%s\", files_initiated=%d, HA 
state=%d",
+                               __FUNCTION__,
+                               stream->name,stream->files_initiated, 
lgs_cb->ha_state);
+               log_initiate_stream_files(stream);
+       } else {
+               /* Second or more open on a stream */
+               if (stream->fd == -1) {
+                       TRACE("LLDTEST3 fd = -1");
+                       TRACE("LLDTEST3 %s name \"%s\", files_initiated=%d, HA 
state=%d",
+                                       __FUNCTION__,
+                                       stream->name,stream->files_initiated, 
lgs_cb->ha_state);
+                       log_initiate_stream_files(stream);
+               }
+       }
+       
+       /* Opening a stream will always succeed. If file system problem a new
+        * attempt to open the files is done when trying to write to the stream
+        */
+       stream->numOpeners++;
+
+       TRACE_LEAVE2("rc=%u, numOpeners=%u", rc, stream->numOpeners);
+       return rc;
+}
 
 /**
  * if ref. count allows, close the associated file, rename it and delete the
@@ -715,6 +805,9 @@ int log_stream_close_hfop(log_stream_t *
 
        osafassert(stream != NULL);
        TRACE_ENTER2("%s, numOpeners=%u", stream->name, stream->numOpeners);
+       if (stream->numOpeners == 0) {
+               TRACE("LLDTEST: %s - numOpeners = 0, streamType = 
%u",__FUNCTION__,stream->streamType);
+       }
 
        osafassert(stream->numOpeners > 0);
        stream->numOpeners--;
@@ -799,7 +892,7 @@ static int get_number_of_log_files_hfop(
        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_size = LGS_FILEPATH_MAX;
        apipar.data_out = (void *) oldest_file;
        
        api_rc = log_file_api(&apipar);
@@ -840,7 +933,6 @@ int log_stream_write_hfop(log_stream_t *
 
        /* Open files on demand e.g. on new active after fail/switch-over. This
         * 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. */
@@ -863,7 +955,7 @@ int log_stream_write_hfop(log_stream_t *
                }
                TRACE("stream %s now opened", stream->name);
        }
-
+       
        TRACE("LLDTEST: %s - stream->fd = %d",__FUNCTION__,stream->fd);
        /* Write the log record
         */
@@ -888,7 +980,7 @@ int log_stream_write_hfop(log_stream_t *
        
        api_rc = log_file_api(&apipar);
        if (api_rc != LGSF_SUCESS) {
-               TRACE("%s - API error %d",__FUNCTION__,api_rc);
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
                rc = -1;
        } else {
                rc = apipar.hdl_ret_code_out;
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
@@ -47,6 +47,7 @@ typedef struct log_stream {
        SaUint64T filtered;     /* discarded by server due to filtering */
        /* --- end correspond to IMM Class --- */
 
+       bool files_initiated; /* True when all files belonging to stream are 
initiated */
        uint32_t streamId;      /* The unique stream id for this stream */
        int32_t fd;             /* The stream file descriptor */
        char logFileCurrent[NAME_MAX];  /* Current file 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
@@ -130,7 +130,7 @@ int lgs_create_config_file_hfop(log_stre
        
        api_rc = log_file_api(&apipar);
        if (api_rc != LGSF_SUCESS) {
-               TRACE("%s - API error %d",__FUNCTION__,api_rc);
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
                rc = -1;
        } else {
                rc = apipar.hdl_ret_code_out;
@@ -209,9 +209,8 @@ int lgs_file_rename_hfop(
                const char *suffix)
 {
        int rc;
-       char oldpath[PATH_MAX + NAME_MAX];
-       char newpath[PATH_MAX + NAME_MAX];
-       const size_t maxsize = PATH_MAX + NAME_MAX;
+       char oldpath[LGS_FILEPATH_MAX];
+       char newpath[LGS_FILEPATH_MAX];
        size_t n;
        lgsf_apipar_t apipar;
        void *params_in_p;
@@ -224,13 +223,13 @@ int lgs_file_rename_hfop(
        TRACE_ENTER2("LLDTEST");
        LOG_NO("LLDTEST: lgs_file_rename_hfop >>");
 
-       n = snprintf(oldpath, maxsize, "%s/%s/%s%s",
+       n = snprintf(oldpath, LGS_FILEPATH_MAX, "%s/%s/%s%s",
                        lgs_cb->logsv_root_dir, path, old_name, suffix);
-       if (n >= maxsize) osafassert(0);
+       if (n >= LGS_FILEPATH_MAX) osafassert(0);
 
-       n = snprintf(newpath, maxsize, "%s/%s/%s_%s%s",
+       n = snprintf(newpath, LGS_FILEPATH_MAX, "%s/%s/%s_%s%s",
                        lgs_cb->logsv_root_dir, path, old_name, time_stamp, 
suffix);
-       if (n >= maxsize) osafassert(0);
+       if (n >= LGS_FILEPATH_MAX) osafassert(0);
        
        TRACE_4("LLDTEST: Rename file from %s", oldpath);
        TRACE_4("LLDTEST:               to %s", newpath);
@@ -261,7 +260,7 @@ int lgs_file_rename_hfop(
        
        api_rc = log_file_api(&apipar);
        if (api_rc != LGSF_SUCESS) {
-               TRACE("%s - API error %d",__FUNCTION__,api_rc);
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
                rc = -1;
        } else {
                rc = apipar.hdl_ret_code_out;
@@ -413,7 +412,7 @@ int lgs_make_dir_hfop(const char* path)
        lgsf_retcode_t api_rc;
        int rc = -1;
        mld_in_t params_in;
-       char new_rootstr[PATH_MAX + NAME_MAX+2];
+       char new_rootstr[LGS_DIRPATH_MAX+2];
        //const int MAX_DEPTH = 10;
        //int dir_depth_cnt;
        //char *dirdc_p;
@@ -423,19 +422,25 @@ int lgs_make_dir_hfop(const char* path)
        /* Check depth of path TBD */
 //     while (strchr)
        
+       TRACE("LLDTEST: lgs_cb->logsv_root_dir \"%s\"",lgs_cb->logsv_root_dir);
+       TRACE("LLDTEST: path \"%s\"",path);
+       
        strncpy(params_in.root_dir, lgs_cb->logsv_root_dir, PATH_MAX+1);
        strncpy(params_in.rel_path, path, PATH_MAX+1);
        
+       TRACE("LLDTEST: root_dir \"%s\"",params_in.root_dir);
+       TRACE("LLDTEST: rel_path \"%s\"",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_size = LGS_DIRPATH_MAX;
        apipar.data_out = &new_rootstr;
        
        api_rc = log_file_api(&apipar);
        if (api_rc != LGSF_SUCESS) {
-               TRACE("%s - API error %d",__FUNCTION__,api_rc);
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
                rc = -1;
        } else {
                rc = apipar.hdl_ret_code_out;
@@ -450,4 +455,43 @@ int lgs_make_dir_hfop(const char* path)
        TRACE_LEAVE2("LLDTEST");
        
        return rc;
+}
+
+/**
+ * Check if a path exists. See also stat(..)
+ * 
+ * @param path_to_check
+ * @return (-1) if not exists, 0 if exists
+ */
+int lgs_check_path_exists(const char *path_to_check)
+{
+       lgsf_apipar_t apipar;
+       lgsf_retcode_t api_rc;
+       void *params_in_p;
+       int rc = 0;
+       
+       /* Allocate memory for parameter */
+       size_t params_in_size = strlen(path_to_check)+1;
+       params_in_p = malloc(params_in_size);
+       
+       /* Fill in path */
+       memcpy(params_in_p, path_to_check, params_in_size);
+       
+       /* Fill in API structure */
+       apipar.req_code_in = LGSF_CHECKPATH;
+       apipar.data_in_size = params_in_size;
+       apipar.data_in = params_in_p;
+       apipar.data_out_size = 0;
+       apipar.data_out = NULL;
+       
+       api_rc = log_file_api(&apipar);
+       if (api_rc != LGSF_SUCESS) {
+               TRACE("%s - API error 
%s",__FUNCTION__,lgsf_retcode_str(api_rc));
+               rc = -1;
+       } else {
+               rc = apipar.hdl_ret_code_out;
+       }
+       
+       free(params_in_p);
+       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
@@ -58,5 +58,6 @@ extern int lgs_file_rename_hfop(const ch
 extern void lgs_exit(const char *msg, SaAmfRecommendedRecoveryT rec_rcvr);
 extern bool lgs_relative_path_check_ts(const char* path);
 extern int lgs_make_dir_hfop(const char* path);
+extern int lgs_check_path_exists(const char *path_to_check);
 
 #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