Sorry. Please take this attach.

Regards, Vu.


>-----Original Message-----
>From: Vu Minh Nguyen [mailto:[email protected]]
>Sent: Thursday, February 25, 2016 9:23 AM
>To: 'Mathivanan Naickan Palanivelu'; [email protected]
>Cc: [email protected]
>Subject: Re: [devel] [PATCH 1 of 4] log: add support for cloud resilience 
>feature
>(service part) [#1179]
>
>Thanks, Mathi.
>
>Here is the fix for comments of patch 1/4 and 2/4.
>
>Regards, Vu.
>
>>-----Original Message-----
>>From: Mathivanan Naickan Palanivelu [mailto:[email protected]]
>>Sent: Wednesday, February 24, 2016 5:24 PM
>>To: [email protected]
>>Cc: [email protected]; [email protected];
>>[email protected]
>>Subject: Re: [PATCH 1 of 4] log: add support for cloud resilience feature
>(service
>>part) [#1179]
>>
>>Ack for patch 1,
>>You could use %PRIx64 for MDS addresses.
>>Mathi.
>>
>>----- [email protected] wrote:
>>
>>> osaf/services/saf/logsv/lgs/Makefile.am    |    6 +-
>>>  osaf/services/saf/logsv/lgs/lgs.h          |   12 +
>>>  osaf/services/saf/logsv/lgs/lgs_cb.h       |   14 +
>>>  osaf/services/saf/logsv/lgs/lgs_evt.cc     |   66 ++-
>>>  osaf/services/saf/logsv/lgs/lgs_evt.h      |    5 +
>>>  osaf/services/saf/logsv/lgs/lgs_file.cc    |    5 +
>>>  osaf/services/saf/logsv/lgs/lgs_file.h     |    1 +
>>>  osaf/services/saf/logsv/lgs/lgs_filehdl.cc |  424 ++++++++++++++++-
>>>  osaf/services/saf/logsv/lgs/lgs_filehdl.h  |   21 +
>>>  osaf/services/saf/logsv/lgs/lgs_imm.cc     |  541
>>> ++++++++++++++++++++-
>>>  osaf/services/saf/logsv/lgs/lgs_main.cc    |  134 ++++-
>>>  osaf/services/saf/logsv/lgs/lgs_mbcsv.cc   |   22 +-
>>>  osaf/services/saf/logsv/lgs/lgs_recov.cc   |  758
>>> +++++++++++++++++++++++++++++
>>>  osaf/services/saf/logsv/lgs/lgs_recov.h    |   37 +
>>>  osaf/services/saf/logsv/lgs/lgs_stream.cc  |   65 +-
>>>  osaf/services/saf/logsv/lgs/lgs_stream.h   |   28 +-
>>>  osaf/services/saf/logsv/lgs/lgs_util.cc    |   50 +-
>>>  osaf/services/saf/logsv/lgs/lgs_util.h     |    4 +
>>>  18 files changed, 2121 insertions(+), 72 deletions(-)
>>>
>>>
>>> The patch makes LOG service be able to handle the case that both SC
>>> nodes
>>> are down at the same time.
>>> When one or both nodes go up again the log service must be able to
>>> resume its work preferably without actions by the clients.
>>>
>>> A log client should not have to be aware of if one or both SC nodes
>>> are down.
>>> The only thing that should happen is that a TRY AGAIN (and in some
>>> cases TIMEOUT) returned.
>>> It is the responsibility of the client to decide how to handle this.
>>>
>>> diff --git a/osaf/services/saf/logsv/lgs/Makefile.am
>>> b/osaf/services/saf/logsv/lgs/Makefile.am
>>> --- a/osaf/services/saf/logsv/lgs/Makefile.am
>>> +++ b/osaf/services/saf/logsv/lgs/Makefile.am
>>> @@ -35,7 +35,8 @@ noinst_HEADERS = \
>>>     lgs_mbcsv_v1.h \
>>>     lgs_mbcsv_v2.h \
>>>     lgs_mbcsv_v3.h \
>>> -   lgs_mbcsv_v5.h
>>> +   lgs_mbcsv_v5.h \
>>> +   lgs_recov.h
>>>
>>>  osaf_execbindir = $(pkglibdir)
>>>  osaf_execbin_PROGRAMS = osaflogd
>>> @@ -63,7 +64,8 @@ osaflogd_SOURCES = \
>>>     lgs_mbcsv_v1.cc \
>>>     lgs_mbcsv_v2.cc \
>>>     lgs_mbcsv_v3.cc \
>>> -   lgs_mbcsv_v5.cc
>>> +   lgs_mbcsv_v5.cc \
>>> +   lgs_recov.cc
>>>
>>>  osaflogd_LDADD = \
>>>     $(top_builddir)/osaf/tools/safimm/src/libimmutil.la \
>>> 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
>>> @@ -30,6 +30,8 @@
>>>  #include <ncs_edu_pub.h>
>>>  #include <ncs_util.h>
>>>  #include <saAis.h>
>>> +#include <saf_error.h>
>>> +#include <saImmOm.h>
>>>
>>>  /* LGS files */
>>>  #include "lgsv_defs.h"
>>> @@ -111,6 +113,16 @@ extern void lgs_imm_impl_reinit_nonblock
>>>  extern void lgs_imm_init_OI_handle(SaImmOiHandleT *immOiHandle,
>>>                                     SaSelectionObjectT
>>> *immSelectionObject);
>>>  extern void lgs_imm_impl_set(SaImmOiHandleT immOiHandle);
>>> +extern  SaAisErrorT lgs_imm_init_configStreams(lgs_cb_t *cb);
>>>
>>> +// Functions for recovery handling
>>> +void lgs_clean_stream_objects(void);
>>> +void lgs_delete_one_stream_object(char *name_str);
>>> +void lgs_search_stream_objects(void);
>>> +SaUint32T *lgs_get_scAbsenceAllowed_attr(SaUint32T *attr_val);
>>> +int lgs_get_streamobj_attr(SaImmAttrValuesT_2 ***attrib_out,
>>> +                      char *object_name,
>>> +                      SaImmHandleT *immOmHandle);
>>> +int lgs_free_streamobj_attr(SaImmHandleT immHandle);
>>>
>>>  #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
>>> @@ -26,6 +26,14 @@
>>>
>>>  #include "lgs_stream.h"
>>>
>>> +/* LGS Recovery states */
>>> +typedef enum {
>>> +    LGS_NORMAL,     /* No recovery is ongoing. All requests are
>>> handled normally */
>>> +    LGS_RECOVERY    /* Recover streams if in recovery list when
>>> stream open
>>> +                                    * request with no parameters
>>> +                                    */
>>> +} lgs_state_t;
>>> +
>>>  /* Default HA state assigned locally during lgs initialization */
>>>  #define LGS_HA_INIT_STATE 0
>>>
>>> @@ -87,6 +95,12 @@ typedef struct lgs_cb {
>>>     LGA_DOWN_LIST *lga_down_list_tail;
>>>
>>>     bool nid_started;       /**< true if started by NID */
>>> +   SaUint32T scAbsenceAllowed; /* OpenSAF global configuration for
>>> recovery handling */
>>> +   lgs_state_t lgs_recovery_state; /* Indicate current recovery state
>>> for the server */
>>> +
>>> +   // Initialize default value in contructor
>>> +   lgs_cb() : lgs_recovery_state(LGS_NORMAL) {};
>>> +
>>>  } lgs_cb_t;
>>>
>>>  extern uint32_t lgs_cb_init(lgs_cb_t *);
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_evt.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_evt.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_evt.cc
>>> @@ -21,6 +21,7 @@
>>>
>>>  #include "lgs_mbcsv_v1.h"
>>>  #include "lgs_mbcsv_v2.h"
>>> +#include "lgs_recov.h"
>>>
>>>  /* Macro to validate the version */
>>>  #define m_LOG_VER_IS_VALID(ver)   \
>>> @@ -375,6 +376,8 @@ static uint32_t proc_lga_updn_mds_msg(lg
>>>             break;
>>>
>>>     case LGSV_LGS_EVT_LGA_DOWN:
>>> +           TRACE("%s: LGSV_LGS_EVT_LGA_DOWN mds_dest = %" PRIu64,
>>> +                 __FUNCTION__, evt->fr_dest);
>>>             if ((lgs_cb->ha_state == SA_AMF_HA_ACTIVE) || (lgs_cb-
>>>ha_state ==
>>> SA_AMF_HA_QUIESCED)) {
>>>             /* Remove this LGA entry from our processing lists */
>>>                     osaf_clock_gettime(CLOCK_REALTIME,
>>&closetime_tspec);
>>> @@ -772,11 +775,17 @@ static uint32_t lgs_ckpt_stream_open(lgs
>>>
>>>  /**
>>>   * Create a new application stream
>>> - * @param open_sync_param
>>> - * @param o_stream
>>> - * @return
>>> + *
>>> + * @param open_sync_param[in] Parameters used to create the stream
>>> + * @param o_stream[out]       The created stream
>>> + * @param create_object_f     IMM stream object is created
>>> + *
>>> + * @return AIS return code
>>>   */
>>> -static SaAisErrorT create_new_app_stream(lgsv_stream_open_req_t
>>> *open_sync_param, log_stream_t **o_stream)
>>> +SaAisErrorT create_new_app_stream(
>>> +           lgsv_stream_open_req_t *open_sync_param,
>>> +           log_stream_t **o_stream,
>>> +           int creationFlag)
>>>  {
>>>     SaAisErrorT rc = SA_AIS_OK;
>>>     log_stream_t *stream;
>>> @@ -870,7 +879,7 @@ static SaAisErrorT create_new_app_stream
>>>             goto done;
>>>     }
>>>
>>> -   stream = log_stream_new(&open_sync_param->lstr_name,
>>> +   stream = log_stream_new_1(&open_sync_param->lstr_name,
>>>                             open_sync_param->logFileName,
>>>                             open_sync_param->logFilePathName,
>>>                             open_sync_param->maxLogFileSize,
>>> @@ -878,7 +887,11 @@ static SaAisErrorT create_new_app_stream
>>>                             open_sync_param->logFileFullAction,
>>>                             open_sync_param->maxFilesRotated,
>>>                             open_sync_param->logFileFmt,
>>> -                           STREAM_TYPE_APPLICATION, STREAM_NEW,
>>twelveHourModeFlag, 0);
>>> +                           STREAM_TYPE_APPLICATION,
>>> +                           STREAM_NEW,
>>> +                           twelveHourModeFlag,
>>> +                           0,
>>> +                           creationFlag);
>>>
>>>     if (stream == NULL) {
>>>             rc = SA_AIS_ERR_NO_MEMORY;
>>> @@ -960,6 +973,7 @@ static uint32_t proc_stream_open_msg(lgs
>>>     log_stream_t *logStream;
>>>     char name[SA_MAX_NAME_LENGTH + 1];
>>>     time_t file_closetime = 0;
>>> +   int i_rc = 0;
>>>
>>>     /* Create null-terminated stream name */
>>>     memcpy(name, open_sync_param->lstr_name.value,
>>> open_sync_param->lstr_name.length);
>>> @@ -981,10 +995,12 @@ static uint32_t proc_stream_open_msg(lgs
>>>                     /* One of the well-known log streams */
>>>                     if (open_sync_param->lstr_open_flags &
>>SA_LOG_STREAM_CREATE) {
>>>                             ais_rv = SA_AIS_ERR_INVALID_PARAM;
>>> +                           rc = NCSCC_RC_FAILURE;
>>>                             goto snd_rsp;
>>>                     }
>>>             }
>>>     } else {
>>> +           /* Stream does not exist */
>>>             if (cb->immOiHandle == 0) {
>>>                     TRACE("IMM service unavailable, open stream failed");
>>>                     ais_rv = SA_AIS_ERR_TRY_AGAIN;
>>> @@ -992,20 +1008,48 @@ static uint32_t proc_stream_open_msg(lgs
>>>             }
>>>
>>>             if ((open_sync_param->lstr_open_flags &
>>SA_LOG_STREAM_CREATE) == 0)
>>> {
>>> -                   ais_rv = SA_AIS_ERR_NOT_EXIST;
>>> -                   goto snd_rsp;
>>> +                   /* The stream does not exist but the create flag is not
>>> +                    * set. If lgs_state is LGS_RECOVERY then:
>>> +                    * Check if the stream is in the list of stream objects
>>> +                    * not recovered. If in list, recover the stream and
>>> +                    * add it to the client
>>> +                    */
>>> +                   if (lgs_cb->lgs_recovery_state == LGS_RECOVERY) {
>>> +                           TRACE("%s LGS_RECOVERY",__FUNCTION__);
>>> +                           i_rc = lgs_restore_one_app_stream(name,
>>> +                                   open_sync_param->client_id,
>>> +                                   &logStream);
>>> +                           if (i_rc == -1) {
>>> +                                   TRACE("%s lgs_restore_one_stream
>>Fail", __FUNCTION__);
>>> +                                   ais_rv = SA_AIS_ERR_NOT_EXIST;
>>> +                                   goto snd_rsp;
>>> +                           }
>>> +                           TRACE("%s Stream %s is recovered",
>>__FUNCTION__, name);
>>> +                           log_stream_print(logStream); /* TRACE */
>>> +                           lstr_id = logStream->streamId;
>>> +                           goto snd_rsp;
>>> +                   } else {
>>> +                           /* Trying to open a non existing stream */
>>> +                           TRACE("%s Attempt to open not existing
>>stream", __FUNCTION__);
>>> +                           ais_rv = SA_AIS_ERR_NOT_EXIST;
>>> +                           goto snd_rsp;
>>> +                   }
>>>             }
>>>
>>>             /* Create the stream:
>>>              *  - Check parameters
>>>              *  - Create the stream in the stream "data base"
>>>              *  - If active create IMM runtime object
>>> +            *  - If recover do not create IMM object
>>>              *
>>>              * Note: Files are not created here
>>>              */
>>> -           ais_rv = create_new_app_stream(open_sync_param,
>>&logStream);
>>> -           if (ais_rv != SA_AIS_OK)
>>> +           ais_rv = create_new_app_stream(open_sync_param,
>>&logStream, 1);
>>> +           if (ais_rv != SA_AIS_OK) {
>>> +                   TRACE("%s create_new_app_stream Fail \"%s\"",
>>> +                           __FUNCTION__, saf_error(ais_rv));
>>>                     goto snd_rsp;
>>> +           }
>>>     }
>>>
>>>     /* Create the log files:
>>> @@ -1030,7 +1074,7 @@ static uint32_t proc_stream_open_msg(lgs
>>>             goto snd_rsp;
>>>     }
>>>
>>> -   TRACE_4("logStream->streamId = %u", logStream->streamId);
>>> +   TRACE_4("logStream->streamId = %u is created",
>>> logStream->streamId);
>>>     lstr_id = logStream->streamId;
>>>
>>>   snd_rsp:
>>> 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
>>> @@ -77,4 +77,9 @@ extern uint32_t lgs_remove_lga_down_rec(
>>>  extern void lgs_send_write_log_ack(uint32_t client_id, SaInvocationT
>>> invocation, SaAisErrorT error, MDS_DEST mds_dest);
>>>  extern void lgs_free_write_log(const lgsv_write_log_async_req_t
>>> *param);
>>>
>>> +SaAisErrorT create_new_app_stream(
>>> +           lgsv_stream_open_req_t *open_sync_param,
>>> +           log_stream_t **o_stream,
>>> +           int creationFlag);
>>> +
>>>  #endif   /*!LGS_EVT_H */
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_file.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_file.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_file.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_file.cc
>>> @@ -184,6 +184,11 @@ static void *file_hndl_thread(void *nopa
>>>                             hndl_rc =
>>own_log_files_by_group_hdl(lgs_com_data.indata_ptr,
>>>                                             lgs_com_data.outdata_ptr,
>>lgs_com_data.outdata_size);
>>>                             break;
>>> +                   case LGSF_GET_FILE_PAR:
>>> +                           hndl_rc =
>>lgs_get_file_params_hdl(lgs_com_data.indata_ptr,
>>> +
>>lgs_com_data.outdata_ptr,
>>> +
>>lgs_com_data.outdata_size);
>>> +                           break;
>>>                     default:
>>>                             break;
>>>                     }
>>> 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
>>> @@ -43,6 +43,7 @@ typedef enum {
>>>     LGSF_CHECKPATH,
>>>     LGSF_CHECKDIR,
>>>     LGSF_OWN_LOGFILES,
>>> +   LGSF_GET_FILE_PAR,
>>>     LGSF_NOREQ
>>>  }lgsf_treq_t;
>>>
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_filehdl.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_filehdl.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_filehdl.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_filehdl.cc
>>> @@ -23,7 +23,6 @@
>>>  #include <dirent.h>
>>>  #include <fcntl.h>
>>>  #include <sys/stat.h>
>>> -
>>>  #include <unistd.h>
>>>
>>>  #include <logtrace.h>
>>> @@ -731,3 +730,426 @@ done_exit:
>>>     TRACE_LEAVE();
>>>     return rc;
>>>  }
>>> +
>>> +/*
>>>
>>*****************************************************************
>*
>>**********
>>> + * lgs_get_file_params_hdl() with help functions
>>> + *
>>> + * Find the file that was current log file before server down.
>>> + * Get file size
>>> + * Get last written record Id by reading the first characters of the
>>> last
>>> + * log record in the file
>>> + *
>>> + */
>>> +
>>> +/**
>>> + * Count the occurrences  of character <c> in a string
>>> + * Count from end of string and stop when lim <c> is found or
>>> + * beginning of string
>>> + *
>>> + * @param str[in] '\0' terminated string to count characters in
>>> + * @param c[in]   Character to count
>>> + * @param lim[in] Stop count when lim characters found
>>> + * @return number of occurrences
>>> + */
>>> +static int chr_cnt_b(char *str, char c, int lim)
>>> +{
>>> +   int cnt = 0;
>>> +
>>> +   if ((str == NULL) || (*str == '\0')) {
>>> +           TRACE("%s: Parameter error", __FUNCTION__);
>>> +           return 0;
>>> +   }
>>> +
>>> +   char *ptr_str_end = strchr(str, '\0');
>>> +   char *ptr_str_pos = ptr_str_end - 1;
>>> +
>>> +   while (1) {
>>> +           if (*ptr_str_pos == c)
>>> +                   cnt++;
>>> +
>>> +           /* End if beginning of file or char limit */
>>> +           if ((ptr_str_pos == str) || (cnt >= lim))
>>> +                   break;
>>> +
>>> +           ptr_str_pos--;
>>> +   }
>>> +
>>> +   return cnt;
>>> +}
>>> +
>>> +/**
>>> + * Filter function used by scandir.
>>> + * Find a current log file if it exist
>>> + * - name as in file_name_find[]
>>> + * - extension .log
>>> + * - two timestamps (other log files has four)
>>> + */
>>> +/* Filename prefix (no timestamps or extension */
>>> +static std::string file_name_find_g;
>>> +static int filter_logfile_name(const struct dirent *finfo)
>>> +{
>>> +   bool name_found = false, ext_found = false;
>>> +
>>> +   if (strstr(finfo->d_name, file_name_find_g.c_str()) != NULL)
>>> +           name_found = true;
>>> +   if (strstr(finfo->d_name, ".log") != NULL)
>>> +           ext_found = true;
>>> +
>>> +   return (int) (name_found && ext_found);
>>> +}
>>> +
>>> +/**
>>> + * Get name and size of log file containing the last record Id. Is
>>> current log
>>> + * file if not empty or last rotated if current log file is empty
>>> + * Also give name of current log file if exist
>>> + *
>>> + * @param filepath_i[in]    Path to log file directory
>>> + * @param filename_i[in]    Name prefix for file to search for
>>> + * @param filename_o[out]   Name of file with Id. "" if no file
>>> found
>>> + * @param curname_o[out]    Name of current log  file or "" if no
>>> current found
>>> + * @param fsize[out]        Size of current log file
>>> + * @return -1 on error filename_o is not valid
>>> + */
>>> +static int filename_get(
>>> +   char *filepath_i, char *filename_i,
>>> +   std::string &filename_o, std::string &curname_o,
>>> +   uint32_t *fsize)
>>> +{
>>> +   int rc = 0;
>>> +   int num_files = 0;
>>> +   int i = 0;
>>> +   struct dirent **namelist;
>>> +   struct stat statbuf;
>>> +   std::string file_path;
>>> +   double time_tmp;
>>> +   char *str_p = NULL;
>>> +   int len = 0;
>>> +   /* Time newest file */
>>> +   double time_new = 0;
>>> +   /* Index in namelist for newest and second newest file */
>>> +   int name_ix_prv = 0, name_ix_new = 0;
>>> +   /* Set to true if file is empty */
>>> +   bool empty_flg_prv = true, empty_flg_new = true;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   // /* Initiate out data */
>>> +   filename_o.clear();
>>> +   curname_o.clear();
>>> +   *fsize = 0;
>>> +
>>> +   /* Create a list of all .log files that has
>>> +    * <filename_i> in <filepath_i>
>>> +    */
>>> +   file_name_find_g = filename_i;
>>> +   num_files = scandir(filepath_i, &namelist, filter_logfile_name,
>>> alphasort);
>>> +   if (num_files == -1) {
>>> +           TRACE("%s: scandir Fail %s", __FUNCTION__, strerror(errno));
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   if (num_files == 0) {
>>> +           /* There is no log file at all */
>>> +           TRACE("\t No log file at all found");
>>> +           goto done_free;
>>> +   }
>>> +
>>> +   /* Special case, only one file is found
>>> +    */
>>> +   if (num_files == 1) {
>>> +           file_path = std::string(filepath_i) + "/" + namelist[0]->d_name;
>>> +           if (stat(file_path.c_str(), &statbuf) == -1) {
>>> +                   TRACE("%s: stat() Fail %s", __FUNCTION__,
>>strerror(errno));
>>> +                   rc = -1;
>>> +                   goto done_free;
>>> +           }
>>> +
>>> +           /* Save found file name */
>>> +           filename_o = namelist[0]->d_name;
>>> +
>>> +           /* Handle current log file output */
>>> +           goto done_hdl_cur;
>>> +   }
>>> +
>>> +   /* Find the newest and the second newest file in the list
>>> +    * Return in filename_o name of newest file if not empty else
>>> +    * the second newest (if that also is empty return error)
>>> +    */
>>> +   time_new = time_tmp = 0;
>>> +   name_ix_prv = name_ix_new = 0;
>>> +   empty_flg_prv = empty_flg_new = false;
>>> +
>>> +   for (i = 0; i < num_files; i++) {
>>> +           file_path = std::string(filepath_i) + "/" + namelist[i]->d_name;
>>> +           if (stat(file_path.c_str(), &statbuf) == -1) {
>>> +                   TRACE("%s: stat() Fail %s", __FUNCTION__,
>>strerror(errno));
>>> +                   rc = -1;
>>> +                   goto done_free;
>>> +           }
>>> +
>>> +           time_tmp = osaf_timespec_to_double(&statbuf.st_mtim);
>>> +           if (time_tmp > time_new) {
>>> +                   name_ix_prv = name_ix_new;
>>> +                   name_ix_new = i;
>>> +                   time_new = time_tmp;
>>> +                   empty_flg_prv = empty_flg_new;
>>> +                   if (statbuf.st_size == 0)
>>> +                           empty_flg_new = true;
>>> +                   else
>>> +                           empty_flg_new = false;
>>> +           }
>>> +   }
>>> +
>>> +   /* Give found filename for output */
>>> +   *fsize = 0;
>>> +   if (empty_flg_new == false) {
>>> +           /* Give the newest filename and its size. File is not empty */
>>> +           filename_o = namelist[name_ix_new]->d_name;
>>> +           *fsize = statbuf.st_size;
>>> +   } else if (empty_flg_prv == false) {
>>> +           /* Give the second newest filename. File is not empty */
>>> +           filename_o = namelist[name_ix_prv]->d_name;
>>> +   } else {
>>> +           /* Both files are empty. This is an error */
>>> +           TRACE("%s: Both newest and second newest are empy",
>>__FUNCTION__);
>>> +           filename_o.clear();
>>> +           rc = -1;
>>> +   }
>>> +
>>> +done_hdl_cur:
>>> +   /* Handle current log file output */
>>> +   len = strlen(filename_i);
>>> +   str_p = namelist[name_ix_new]->d_name + len;
>>> +   if (chr_cnt_b(str_p, '_', 4) == 2) {
>>> +           /* Newest is current log file */
>>> +           curname_o = namelist[name_ix_new]->d_name;
>>> +   }
>>> +
>>> +done_free:
>>> +   /* Free namelist */
>>> +   for (i = 0; i < num_files; i++) {
>>> +           free(namelist[i]);
>>> +   }
>>> +
>>> +   free(namelist);
>>> +
>>> +done:
>>> +   TRACE_LEAVE();
>>> +   return rc;
>>> +}
>>> +
>>> +/**
>>> + * Get last record Id from the given file.
>>> + * Each record begins with a record Id number. The wanted Id is the
>>> last Id
>>> + * in the file
>>> + *
>>> + * @param file_name[in] Complete path to the file
>>> + * @return record Id or -1 on error. Set to 0 if no error but no Id
>>> is found
>>> + */
>>> +static int record_id_get(const char *file_path)
>>> +{
>>> +   FILE *fd = NULL;
>>> +   int id_rc = 0;
>>> +   int i;
>>> +   int c;
>>> +   long endpos;
>>> +
>>> +   char *read_line = NULL;
>>> +   size_t dummy_n = 0;
>>> +   ssize_t line_len;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   /* Open the file */
>>> +   while (1) {
>>> +           fd = fopen(file_path, "r");
>>> +           if (fd != NULL) {
>>> +                   break;
>>> +           } else if (errno != EINTR){
>>> +                   TRACE("%s fopen Fail %s",
>>> +                           __FUNCTION__, strerror(errno));
>>> +                   id_rc = -1;
>>> +                   goto done;
>>> +           }
>>> +   }
>>> +
>>> +   /* Get last pos in file */
>>> +   while(1) {
>>> +           if (fseek(fd, 0, SEEK_END) == -1) {
>>> +                   if (errno == EINTR)
>>> +                           continue;
>>> +                   TRACE("\t %d fseek Fail %s",__LINE__, strerror(errno));
>>> +                   id_rc = -1;
>>> +                   goto done;
>>> +           }
>>> +           break;
>>> +   }
>>> +   endpos = ftell(fd);
>>> +
>>> +   if (endpos == 0) {
>>> +           /* The file is empty. No Id to find */
>>> +           id_rc = 0;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Search from the end for '\n' (end of prev record)
>>> +    * or beginning of file
>>> +    */
>>> +   for (i = 2; i < endpos; i++) {
>>> +           while(1) {
>>> +                   if (fseek(fd, -i, SEEK_END) == -1) {
>>> +                           if (errno == EINTR)
>>> +                                   continue;
>>> +                           TRACE("\t %d fseek Fail %s",
>>> +                                   __LINE__, strerror(errno));
>>> +                           id_rc = -1;
>>> +                           goto done;
>>> +                   }
>>> +                   break;
>>> +           }
>>> +
>>> +           c = getc(fd);
>>> +           if (c == '\n')
>>> +                   break;
>>> +   }
>>> +
>>> +   /* Get pos for line start */
>>> +   c = getc(fd); /* Dummy read '\n' */
>>> +
>>> +   /* Read the last record and get record id */
>>> +   line_len = getline(&read_line, &dummy_n, fd);
>>> +   if (line_len == -1) {
>>> +           TRACE("%s: getline Fail %s",
>>> +                   __FUNCTION__, strerror(errno));
>>> +           id_rc = -1;
>>> +           goto done;
>>> +   }
>>> +   id_rc = atoi(read_line);
>>> +   if (id_rc == 0) {
>>> +           TRACE("%s: \"%s\" has no number. Id set to 0",
>>> +                   __FUNCTION__, read_line);
>>> +           id_rc = 0;
>>> +           goto done_free;
>>> +   }
>>> +
>>> +done_free:
>>> +   free(read_line);
>>> +
>>> +done:
>>> +   if (fd != NULL)
>>> +           fclose(fd);
>>> +
>>> +   TRACE_LEAVE();
>>> +   return id_rc;
>>> +}
>>> +
>>> +/**
>>> + * Get log file information:
>>> + * - Name of current log file: <name prefix>_YYMMDD_HHMMSS
>>> + * - Log record id
>>> + *
>>> + * Rules:
>>> + * - If current log file not empty: Name = cur log file, Size = file
>>> size,
>>> + *                                  Id = fr file, rc = OK
>>> + * - If current log file empty no rotated: Name = cur log file, Size
>>> = 0,
>>> + *                                         Id = 1, rc = OK
>>> + * - If current log file empty is rotated: Name = cur log file, Size
>>> = 0,
>>> + *                                         Id = fr last rotated, rc =
>>> OK
>>> + * - If no log file at all:  Name = NULL, Size = 0, Id = 1, rc = OK
>>> + * - If only rotated log file: Name = NULL, Size = 0, Id = fr rotated
>>> file,
>>> + *                             rc = OK
>>> + *
>>> + * @param indata[in]      gfp_in_t
>>> + *        file_name: File name prefix (name part before time stamps)
>>> + *        file_path: Full path to directory root path + rel path
>>> + *
>>> + * @param outdata[out]    gfp_out_t
>>> + *        curFileName: Current file name <name prefix>_YYMMDD_HHMMSS
>>> + *        curFileSize: Bytes written to current log file (file size)
>>> + *        logRecordId: log record identifier for last written log
>>> record
>>> +
>>> + * @param max_outsize[in] sizeof gfp_out_t (not used)
>>> + *
>>> + * @return (-1) on error, out data not valid
>>> + */
>>> +int lgs_get_file_params_hdl(void *indata, void *outdata, size_t
>>> max_outsize)
>>> +{
>>> +   gfp_in_t *par_in = static_cast<gfp_in_t *>(indata);
>>> +   gfp_out_t *par_out = static_cast<gfp_out_t *>(outdata);
>>> +   int rc = 0, int_rc = 0;
>>> +   std::string file_name;
>>> +   std::string file_name_cur;
>>> +   std::string file_path;
>>> +   int rec_id = 0;
>>> +   char *ptr_str;
>>> +
>>> +   uint32_t file_size = 0;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   osaf_mutex_unlock_ordie(&lgs_ftcom_mutex); /* UNLOCK  Critical
>>> section */
>>> +
>>> +   /* Initialize out parameters */
>>> +   par_out->curFileName = NULL;
>>> +   par_out->curFileSize = 0;
>>> +   par_out->logRecordId = 0;
>>> +
>>> +   /* Get log file to get info from and its size */
>>> +   int_rc = filename_get(
>>> +           par_in->file_path, par_in->file_name,
>>> +           file_name, file_name_cur, &file_size
>>> +           );
>>> +   if (int_rc == -1) {
>>> +           TRACE("%s: filename_get Fail",__FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   if (file_name[0] == '\0') {
>>> +           TRACE("No file found.");
>>> +           rc = -1;
>>> +           par_out->logRecordId = 0;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Create the file path */
>>> +   file_path = std::string(par_in->file_path) + "/" + file_name;
>>> +
>>> +   /* Find record id in file */
>>> +   rec_id = record_id_get(file_path.c_str());
>>> +   if (rec_id == -1) {
>>> +           TRACE("%s: record_id_get Fail", __FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Fill in out data */
>>> +   par_out->logRecordId = rec_id;
>>> +   par_out->curFileSize = file_size;
>>> +   if (file_name_cur.empty() == false) {
>>> +           // This memory will be deleted in
>>log_stream_open_file_restore()
>>> +           // who wants to get the info from this memory -
>>> par_out->curFileName
>>> +           par_out->curFileName = static_cast<char *>(
>>> +                   calloc(1, file_name_cur.size() + 1));
>>> +           if (par_out->curFileName == NULL) {
>>> +                   LOG_ER("%s Failed to allocate memory",
>>__FUNCTION__);
>>> +                   rc = -1;
>>> +                   goto done;
>>> +           }
>>> +
>>> +           strcpy(par_out->curFileName, file_name_cur.c_str());
>>> +           /* Remove extension */
>>> +           ptr_str = strstr(par_out->curFileName, ".log");
>>> +           if (ptr_str == NULL) {
>>> +                   TRACE("%s: Could not find .log extension Fail",
>>__FUNCTION__);
>>> +                   rc = -1;
>>> +           }
>>> +           *ptr_str = '\0';
>>> +   }
>>> +
>>> +done:
>>> +   osaf_mutex_lock_ordie(&lgs_ftcom_mutex); /* LOCK after critical
>>> section */
>>> +   TRACE_LEAVE2("rc = %d", rc);
>>> +   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
>>> @@ -155,6 +155,26 @@ typedef struct {
>>>   * No out parameters
>>>   */
>>>
>>> +/*
>>> + * lgs_get_file_params_hdl(...)
>>> + * Ret code -1 if error
>>> + */
>>> +/* IN params */
>>> +typedef struct {
>>> +   /* File name prefix (name part before time stamps) */
>>> +   char *file_name;
>>> +   /* Full path to directory root path + rel path */
>>> +   char *file_path;
>>> +} gfp_in_t;
>>> +
>>> +/* OUT params */
>>> +typedef struct {
>>> +   char *curFileName;
>>> +   uint32_t curFileSize;   /* Bytes written to current log file */
>>> +   uint32_t logRecordId;   /* log record identifier increased for each
>>> record */
>>> +} gfp_out_t;
>>> +
>>> +
>>>  int path_is_writeable_dir_hdl(void *indata, void *outdata, size_t
>>> max_outsize);
>>>  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);
>>> @@ -166,6 +186,7 @@ int fileclose_hdl(void *indata, void *ou
>>>  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);
>>>  int own_log_files_by_group_hdl(void *indata, void *outdata, size_t
>>> max_outsize);
>>> +int lgs_get_file_params_hdl(void *indata, void *outdata, size_t
>>> max_outsize);
>>>
>>>  #endif     /* LGS_FILEHDL_H */
>>>
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_imm.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_imm.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_imm.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_imm.cc
>>> @@ -42,6 +42,7 @@
>>>  #include "lgs.h"
>>>  #include "lgs_util.h"
>>>  #include "lgs_file.h"
>>> +#include "lgs_recov.h"
>>>  #include "lgs_config.h"
>>>  #include "saf_error.h"
>>>
>>> @@ -2507,7 +2508,8 @@ done:
>>>   * @return SaAisErrorT
>>>   */
>>>  static SaAisErrorT stream_create_and_configure(const char *dn,
>>> -           log_stream_t **in_stream, int stream_id,
>>SaImmAccessorHandleT
>>> accessorHandle)
>>> +           log_stream_t **in_stream, int stream_id,
>>> +           SaImmAccessorHandleT accessorHandle)
>>>  {
>>>     SaAisErrorT rc = SA_AIS_OK;
>>>     SaNameT objectName;
>>> @@ -2606,6 +2608,15 @@ static SaAisErrorT stream_create_and_con
>>>             } else if (!strcmp(attribute->attrName,
>>> "saLogStreamSeverityFilter")) {
>>>                     stream->severityFilter = *((SaUint32T *)value);
>>>                     TRACE("severityFilter: %u", stream->severityFilter);
>>> +           } else if (!strcmp(attribute->attrName,
>>> "saLogStreamCreationTimestamp")) {
>>> +                   if (attribute->attrValuesNumber != 0) {
>>> +                           /* Restore creation timestamp if exist
>>> +                            * Note: Creation timestamp in stream is set to
>>> +                            * current time which will be the value if no
>>> +                            * value found in object
>>> +                            */
>>> +                           stream->creationTimeStamp =
>>*(static_cast<SaTimeT *>(value));
>>> +                   }
>>>             }
>>>     }
>>>
>>> @@ -2648,11 +2659,15 @@ static const SaImmOiCallbacksT_2 callbac
>>>   * IMM-OM interface and initialize the corresponding information
>>>   * in the LOG control block. Initialize the LOG IMM-OI
>>>   * interface. Become class implementer.
>>> + *
>>> + * @param immOiHandle[in]
>>> + * @return
>>>   */
>>> -SaAisErrorT lgs_imm_create_configStream(lgs_cb_t *cb)
>>> +SaAisErrorT lgs_imm_init_configStreams(lgs_cb_t *cb)
>>>  {
>>> -   SaAisErrorT rc = SA_AIS_OK;
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>>     SaAisErrorT om_rc;
>>> +   int int_rc = 0;
>>>     log_stream_t *stream;
>>>     SaImmHandleT omHandle;
>>>     SaImmAccessorHandleT accessorHandle;
>>> @@ -2685,9 +2700,13 @@ SaAisErrorT lgs_imm_create_configStream(
>>>                     &immSearchHandle)) == SA_AIS_OK) {
>>>
>>>             while (immutil_saImmOmSearchNext_2(immSearchHandle,
>>&objectName,
>>> &attributes) == SA_AIS_OK) {
>>> -                   if ((rc = stream_create_and_configure((char*)
>>objectName.value,
>>> -                                   &stream, streamId, accessorHandle)) !=
>>SA_AIS_OK) {
>>> -                           LOG_ER("stream_create_and_configure failed
>>%d", rc);
>>> +                   /* Note: Here is creationTimeStamp and severityFilter
>>set
>>> +                    * Can be recovered if scAbseceAllowed
>>> +                    */
>>> +                   ais_rc = stream_create_and_configure((char*)
>>objectName.value,
>>> +                                   &stream, streamId, accessorHandle);
>>> +                   if (ais_rc != SA_AIS_OK) {
>>> +                           LOG_WA("stream_create_and_configure failed
>>%d", ais_rc);
>>>                             goto done;
>>>                     }
>>>                     streamId += 1;
>>> @@ -2709,12 +2728,35 @@ SaAisErrorT lgs_imm_create_configStream(
>>>
>>>     stream = log_stream_getnext_by_name(NULL);
>>>     while (stream != NULL) {
>>> -           (void)immutil_update_one_rattr(cb->immOiHandle, stream-
>>>name,
>>> -
>>> const_cast<SaImmAttrNameT>("saLogStreamCreationTimestamp"),
>>> -                                          SA_IMM_ATTR_SATIMET,
>>> -                                          &stream->creationTimeStamp);
>>> -
>>> -           log_stream_open_fileinit(stream);
>>> +           if (cb->scAbsenceAllowed != 0) {
>>> +                   /**
>>> +                    * This code to make LOG distinguish b/w headless and
>>cluster
>>> start-up/restarts
>>> +                    * 1) If data reading from IMM differs with default
>>ones, headless
>>> just occurs
>>> +                    * 2) If data reading from IMM equals to default ones,
>>continue
>>> checking:
>>> +                    *  2.1) If info in cfg file are equal to data reading 
>>> from
>>IMM,
>>> can reuse the cfg/log files
>>> +                    *  2.2) If info in cfg are not equal to, can not re-use
>>cfg/log
>>> file. Creating new ones instead.
>>> +                    */
>>> +                   int_rc = log_stream_open_file_restore(stream);
>>> +                   if (int_rc == -1) {
>>> +                           /* Restore failed. Initialize instead */
>>> +                           LOG_NO("%s: log_stream_open_file_restore
>>Fail", __FUNCTION__);
>>> +                           log_stream_open_fileinit(stream);
>>> +                           stream->creationTimeStamp =
>>lgs_get_SaTime();
>>> +                   }
>>> +           } else {
>>> +                   /* Always create new files and set current timestamp
>>to
>>> +                    * current time
>>> +                    */
>>> +                   log_stream_open_fileinit(stream);
>>> +                   stream->creationTimeStamp = lgs_get_SaTime();
>>> +           }
>>> +
>>> +           (void)immutil_update_one_rattr(
>>> +                   cb->immOiHandle, stream->name,
>>> +
>>      const_cast<SaImmAttrNameT>("saLogStreamCreationTimestamp"),
>>> +                   SA_IMM_ATTR_SATIMET,
>>> +                   &stream->creationTimeStamp);
>>> +
>>>             stream = log_stream_getnext_by_name(stream->name);
>>>     }
>>>
>>> @@ -2740,7 +2782,7 @@ SaAisErrorT lgs_imm_create_configStream(
>>>     immutilWrapperProfile.errorsAreFatal = errorsAreFatal; /* Enable
>>> again */
>>>
>>>     TRACE_LEAVE();
>>> -   return rc;
>>> +   return ais_rc;
>>>  }
>>>
>>>  /**
>>> @@ -2951,3 +2993,476 @@ void lgs_imm_impl_reinit_nonblocking(lgs
>>>
>>>     TRACE_LEAVE();
>>>  }
>>> +
>>>
>>+/***************************************************************
>*
>>**************
>>> + * Functions used for recovery handling
>>> +
>>>
>>*****************************************************************
>*
>>************/
>>> +/**
>>> + * Search for old runtime stream objects and put their names in a
>>> list.
>>> + * Become OI for the runtime stream class if any objects found
>>> + *
>>> + * @param object_list
>>> + */
>>> +void lgs_search_stream_objects(void)
>>> +{
>>> +   int rc = 0;
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +   SaImmHandleT immOmHandle;
>>> +   SaImmSearchHandleT immSearchHandle;
>>> +   const char* class_name = "SaLogStream";
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   /* Save immutil settings and reconfigure immutil
>>> +    */
>>> +   struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
>>> +   tmp_immutilWrapperProfile.errorsAreFatal =
>>> immutilWrapperProfile.errorsAreFatal;
>>> +   tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
>>> +   tmp_immutilWrapperProfile.retryInterval =
>>> immutilWrapperProfile.retryInterval;
>>> +
>>> +   immutilWrapperProfile.errorsAreFatal = 0;
>>> +   immutilWrapperProfile.nTries = 500;
>>> +   immutilWrapperProfile.retryInterval = 1000;
>>> +
>>> +
>>> +   /* Intialize Om API
>>> +    */
>>> +   ais_rc = immutil_saImmOmInitialize(&immOmHandle, NULL,
>>> &immVersion);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           LOG_WA("%s saImmOmInitialize FAIL %d", __FUNCTION__,
>>ais_rc);
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Initialize search for application stream runtime objects
>>> +    * Search for all objects of class 'SaLogStream'
>>> +    * Search criteria:
>>> +    * Attribute SaImmAttrClassName == SaLogStream
>>> +    */
>>> +   SaImmSearchParametersT_2 searchParam;
>>> +   searchParam.searchOneAttr.attrName = const_cast<char
>>> *>("SaImmAttrClassName");
>>> +   searchParam.searchOneAttr.attrValueType =
>>SA_IMM_ATTR_SASTRINGT;
>>> +   searchParam.searchOneAttr.attrValue = &class_name;
>>> +   SaNameT root_name;
>>> +   root_name.value[0] = '\0';
>>> +   root_name.length = 1;
>>> +
>>> +   ais_rc = immutil_saImmOmSearchInitialize_2(
>>> +                   immOmHandle,
>>> +                   &root_name,
>>> +                   SA_IMM_SUBTREE,
>>> +                   SA_IMM_SEARCH_ONE_ATTR |
>>SA_IMM_SEARCH_GET_NO_ATTR,
>>> +                   &searchParam,
>>> +                   NULL,
>>> +                   &immSearchHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           LOG_WA("%s saImmOmSearchInitialize FAIL %d",
>>__FUNCTION__,
>>> ais_rc);
>>> +           goto done_fin_Om;
>>> +   }
>>> +
>>> +   /* Iterate the search and save objects in list until all objects
>>> found
>>> +    */
>>> +   SaNameT object_name;
>>> +   SaImmAttrValuesT_2 **attributes;
>>> +
>>> +   ais_rc = immutil_saImmOmSearchNext_2(immSearchHandle,
>>&object_name,
>>> &attributes);
>>> +   if (ais_rc == SA_AIS_ERR_NOT_EXIST) {
>>> +           TRACE("\tNo objects found");
>>> +   }
>>> +
>>> +   while (ais_rc == SA_AIS_OK) {
>>> +           TRACE("\tFound object \"%s\"", reinterpret_cast<char
>>> *>(object_name.value));
>>> +           /* Add the string to the list
>>> +            */
>>> +           rc = log_rtobj_list_add(reinterpret_cast<char
>>> *>(object_name.value));
>>> +           if (rc == -1) {
>>> +                   TRACE("%s Could not add %s to list Fail",
>>> +                         __FUNCTION__, reinterpret_cast<char
>>*>(object_name.value));
>>> +           }
>>> +
>>> +           /* Get next object */
>>> +           ais_rc = immutil_saImmOmSearchNext_2(immSearchHandle,
>>> +                   &object_name, &attributes);
>>> +   }
>>> +   if (ais_rc == SA_AIS_ERR_NOT_EXIST) {
>>> +           TRACE("\tAll objects found OK");
>>> +   } else {
>>> +           LOG_WA("\t%s saImmOmSearchNext FAILED %d",
>>__FUNCTION__, ais_rc);
>>> +   }
>>> +
>>> +   /* Finalize the serach API
>>> +    */
>>> +   ais_rc = immutil_saImmOmSearchFinalize(immSearchHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("\tsaImmOmSearchFinalize FAIL %d", ais_rc);
>>> +   }
>>> +
>>> +done_fin_Om:
>>> +   /* Finalize the Om API
>>> +    */
>>> +   ais_rc = immutil_saImmOmFinalize(immOmHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("\tsaImmOmFinalize FAIL %d", ais_rc);
>>> +   }
>>> +
>>> +done:
>>> +   /* Restore immutil settings */
>>> +   immutilWrapperProfile.errorsAreFatal =
>>> tmp_immutilWrapperProfile.errorsAreFatal;
>>> +   immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
>>> +   immutilWrapperProfile.retryInterval =
>>> tmp_immutilWrapperProfile.retryInterval;
>>> +
>>> +   TRACE_LEAVE();
>>> +}
>>> +
>>> +void lgs_delete_one_stream_object(char *name_str)
>>> +{
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +   SaNameT object_name;
>>> +
>>> +   if (name_str == NULL) {
>>> +           TRACE("%s No object name given", __FUNCTION__);
>>> +           return;
>>> +   }
>>> +
>>> +   /* Save immutil settings and reconfigure */
>>> +   struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
>>> +   tmp_immutilWrapperProfile.errorsAreFatal =
>>> immutilWrapperProfile.errorsAreFatal;
>>> +   tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
>>> +   tmp_immutilWrapperProfile.retryInterval =
>>> immutilWrapperProfile.retryInterval;
>>> +
>>> +   immutilWrapperProfile.errorsAreFatal = 0;
>>> +   immutilWrapperProfile.nTries = 500;
>>> +   immutilWrapperProfile.retryInterval = 1000;
>>> +
>>> +   /* Copy name to a SaNameT */
>>> +   (void) strncpy(reinterpret_cast<char *>(object_name.value),
>>> +                  name_str, SA_MAX_NAME_LENGTH);
>>> +   object_name.length = strlen(name_str) + 1;
>>> +
>>> +   /* and delete the object */
>>> +   ais_rc = immutil_saImmOiRtObjectDelete(lgs_cb->immOiHandle,
>>> &object_name);
>>> +   if (ais_rc == SA_AIS_OK) {
>>> +           TRACE("%s Object \"%s\" deleted", __FUNCTION__,
>>> +                 reinterpret_cast<char *>(object_name.value));
>>> +   } else {
>>> +           LOG_WA("%s saImmOiRtObjectDelete for \"%s\" FAILED %d",
>>> +                  __FUNCTION__, reinterpret_cast<char
>>*>(object_name.value),
>>> ais_rc);
>>> +   }
>>> +
>>> +   /* Restore immutil settings */
>>> +   immutilWrapperProfile.errorsAreFatal =
>>> tmp_immutilWrapperProfile.errorsAreFatal;
>>> +   immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
>>> +   immutilWrapperProfile.retryInterval =
>>> tmp_immutilWrapperProfile.retryInterval;
>>> +}
>>> +
>>> +/**
>>> + * Delete all stream objects in the stream object list.
>>> + * See also: lgs_search_stream_objects()
>>> + *
>>> + */
>>> +void lgs_clean_stream_objects(void)
>>> +{
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +   int pos = 0;
>>> +   char *name_str;
>>> +   SaNameT object_name;
>>> +
>>> +   TRACE_ENTER();
>>> +   /* Check if there are any objects to delete. If not do nothing  */
>>> +   if (log_rtobj_list_no() <= 0) {
>>> +           TRACE("%s\t No objects to delete is found", __FUNCTION__);
>>> +           return;
>>> +   }
>>> +
>>> +   /* Save immutil settings and reconfigure */
>>> +   struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
>>> +   tmp_immutilWrapperProfile.errorsAreFatal =
>>> immutilWrapperProfile.errorsAreFatal;
>>> +   tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
>>> +   tmp_immutilWrapperProfile.retryInterval =
>>> immutilWrapperProfile.retryInterval;
>>> +
>>> +   immutilWrapperProfile.errorsAreFatal = 0;
>>> +   immutilWrapperProfile.nTries = 500;
>>> +   immutilWrapperProfile.retryInterval = 1000;
>>> +
>>> +   pos = log_rtobj_list_getnamepos();
>>> +   while (pos != -1) {
>>> +           /* Get found name */
>>> +           name_str = log_rtobj_list_getname(pos);
>>> +
>>> +           /* Delete the object if in object list. Note this is an Oi
>>> operation
>>> +            * Remove name from list
>>> +            */
>>> +           if (name_str != NULL) {
>>> +                   /* Copy name to a SaNameT */
>>> +                   (void) strncpy(reinterpret_cast<char
>>*>(object_name.value),
>>> +                                  name_str, SA_MAX_NAME_LENGTH);
>>> +                   object_name.length = strlen(name_str) + 1;
>>> +                   /* and delete the object */
>>> +                   ais_rc = immutil_saImmOiRtObjectDelete(lgs_cb-
>>>immOiHandle,
>>> +                           &object_name);
>>> +                   if (ais_rc == SA_AIS_OK) {
>>> +                           TRACE("\tObject \"%s\" deleted",
>>> +                                 reinterpret_cast<char
>>*>(object_name.value));
>>> +                   } else {
>>> +                           LOG_WA("%s saImmOiRtObjectDelete for
>>\"%s\" FAILED %d",
>>> +                                  __FUNCTION__,
>>> +                                  reinterpret_cast<char
>>*>(object_name.value), ais_rc);
>>> +                   }
>>> +           } else {
>>> +                   /* Should never happen! */
>>> +                   TRACE("%s\tFound name has NULL pointer!",
>>__FUNCTION__);
>>> +           }
>>> +           /* Remove deleted object name from list */
>>> +           log_rtobj_list_erase_one_pos(pos);
>>> +
>>> +           /* Get next object */
>>> +           pos = log_rtobj_list_getnamepos();
>>> +   }
>>> +
>>> +   /* Restore immutil settings */
>>> +   immutilWrapperProfile.errorsAreFatal =
>>> tmp_immutilWrapperProfile.errorsAreFatal;
>>> +   immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
>>> +   immutilWrapperProfile.retryInterval =
>>> tmp_immutilWrapperProfile.retryInterval;
>>> +
>>> +   TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * Get cached stream attributes for given object name
>>> + *
>>> + * @param attrib_out[out] Pointer to a NULL terminated
>>> SaImmAttrValuesT_2 vector
>>> + * @param object_name[in]  String containing the object name
>>> + * @param immOmHandle[out]
>>> + * @return -1 on error
>>> + */
>>> +int lgs_get_streamobj_attr(SaImmAttrValuesT_2 ***attrib_out, char
>>> *object_name_in,
>>> +   SaImmHandleT *immOmHandle)
>>> +{
>>> +   int rc = 0;
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +   SaImmAccessorHandleT accessorHandle;
>>> +   char *attribute_names[] = {
>>> +           const_cast<char *>("saLogStreamFileName"),
>>> +           const_cast<char *>("saLogStreamPathName"),
>>> +           const_cast<char *>("saLogStreamMaxLogFileSize"),
>>> +           const_cast<char *>("saLogStreamFixedLogRecordSize"),
>>> +           const_cast<char *>("saLogStreamHaProperty"),
>>> +           const_cast<char *>("saLogStreamLogFullAction"),
>>> +           const_cast<char *>("saLogStreamMaxFilesRotated"),
>>> +           const_cast<char *>("saLogStreamLogFileFormat"),
>>> +           const_cast<char *>("saLogStreamSeverityFilter"),
>>> +           const_cast<char *>("saLogStreamCreationTimestamp"),
>>> +           NULL
>>> +   };
>>> +
>>> +   TRACE_ENTER2("object_name_in \"%s\"", object_name_in);
>>> +
>>> +   SaNameT object_name;
>>> +
>>> +   /* Save immutil settings and reconfigure */
>>> +   struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
>>> +   tmp_immutilWrapperProfile.errorsAreFatal =
>>> immutilWrapperProfile.errorsAreFatal;
>>> +   tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
>>> +   tmp_immutilWrapperProfile.retryInterval =
>>> immutilWrapperProfile.retryInterval;
>>> +
>>> +   immutilWrapperProfile.errorsAreFatal = 0;
>>> +   immutilWrapperProfile.nTries = 500;
>>> +   immutilWrapperProfile.retryInterval = 1000;
>>> +
>>> +   if (object_name_in == NULL) {
>>> +           TRACE("%s No object name given (NULL)", __FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Initialize Om API
>>> +    */
>>> +   ais_rc = immutil_saImmOmInitialize(immOmHandle, NULL,
>>&immVersion);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           LOG_WA("\t%s saImmOmInitialize FAIL %d", __FUNCTION__,
>>ais_rc);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Initialize accessor for reading attributes
>>> +    */
>>> +   ais_rc = immutil_saImmOmAccessorInitialize(*immOmHandle,
>>> &accessorHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmAccessorInitialize Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   strncpy(reinterpret_cast<char *>(object_name.value),
>>> +           object_name_in, SA_MAX_NAME_LENGTH);
>>> +   object_name.length = strlen(reinterpret_cast<char
>>> *>(object_name.value)) + 1;
>>> +
>>> +   ais_rc = immutil_saImmOmAccessorGet_2(accessorHandle,
>>&object_name,
>>> +                   attribute_names, attrib_out);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmAccessorGet_2 Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +           rc = -1;
>>> +           goto done_fin_Om;
>>> +   } else {
>>> +           goto done;
>>> +   }
>>> +
>>> +done_fin_Om:
>>> +   /* Free resources if fail */
>>> +   ais_rc = immutil_saImmOmFinalize(*immOmHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmFinalize Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +   }
>>> +
>>> +done:
>>> +   /* Restore immutil settings */
>>> +   immutilWrapperProfile.errorsAreFatal =
>>> tmp_immutilWrapperProfile.errorsAreFatal;
>>> +   immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
>>> +   immutilWrapperProfile.retryInterval =
>>> tmp_immutilWrapperProfile.retryInterval;
>>> +
>>> +   TRACE_LEAVE();
>>> +   return rc;
>>> +}
>>> +
>>> +/**
>>> + * Free resources claimed when calling lgs_get_streamobj_attr()
>>> + *
>>> + * @param immHandle[in]
>>> + * @return -1 on error
>>> + */
>>> +int lgs_free_streamobj_attr(SaImmHandleT immOmHandle)
>>> +{
>>> +   int rc = 0;
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   /* Save immutil settings and reconfigure */
>>> +   struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
>>> +   tmp_immutilWrapperProfile.errorsAreFatal =
>>> immutilWrapperProfile.errorsAreFatal;
>>> +   tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
>>> +   tmp_immutilWrapperProfile.retryInterval =
>>> immutilWrapperProfile.retryInterval;
>>> +
>>> +   immutilWrapperProfile.errorsAreFatal = 0;
>>> +   immutilWrapperProfile.nTries = 500;
>>> +   immutilWrapperProfile.retryInterval = 1000;
>>> +
>>> +   ais_rc = immutil_saImmOmFinalize(immOmHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmFinalize Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +           rc = -1;
>>> +   }
>>> +
>>> +   /* Restore immutil settings */
>>> +   immutilWrapperProfile.errorsAreFatal =
>>> tmp_immutilWrapperProfile.errorsAreFatal;
>>> +   immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
>>> +   immutilWrapperProfile.retryInterval =
>>> tmp_immutilWrapperProfile.retryInterval;
>>> +
>>> +   TRACE_LEAVE();
>>> +   return rc;
>>> +}
>>> +
>>> +/**
>>> + * Read the scAbsenceAllowed attribute in
>>> + * opensafImm=opensafImm,safApp=safImmService object.
>>> + * No value means that "absence handling" is not allowed. For Log
>>> this means
>>> + * that no recovery shall be done.
>>> + *
>>> + * @param attr_val[out] Value read from scAbsenceAllowed attribute. 0
>>> = No value
>>> + * @return Pointer to attr_val if value is read. NULL if no value. If
>>> NULL the
>>> + *         value in attr_val is not valid
>>> + */
>>> +SaUint32T *lgs_get_scAbsenceAllowed_attr(SaUint32T *attr_val)
>>> +{
>>> +   SaUint32T *rc_attr_val = NULL;
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +   SaImmAccessorHandleT accessorHandle;
>>> +   SaImmHandleT immOmHandle;
>>> +   SaImmAttrValuesT_2 *attribute;
>>> +   SaImmAttrValuesT_2 **attributes;
>>> +
>>> +   TRACE_ENTER();
>>> +   char *attribute_names[] = {
>>> +           const_cast<char *>("scAbsenceAllowed"),
>>> +           NULL
>>> +   };
>>> +   char object_name_str[] =
>>> "opensafImm=opensafImm,safApp=safImmService";
>>> +
>>> +   SaNameT object_name;
>>> +   strncpy(reinterpret_cast<char *>(object_name.value),
>>> +           object_name_str, SA_MAX_NAME_LENGTH);
>>> +   object_name.length = strlen(reinterpret_cast<char
>>> *>(object_name.value)) + 1;
>>> +
>>> +   /* Default restore handling shall be disabled. Is enabled if the
>>> +    * scAbsenceAllowed attribute is not empty
>>> +    */
>>> +   *attr_val = 0;
>>> +
>>> +   /* Save immutil settings and reconfigure */
>>> +   struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
>>> +   tmp_immutilWrapperProfile.errorsAreFatal =
>>> immutilWrapperProfile.errorsAreFatal;
>>> +   tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
>>> +   tmp_immutilWrapperProfile.retryInterval =
>>> immutilWrapperProfile.retryInterval;
>>> +
>>> +   immutilWrapperProfile.errorsAreFatal = 0;
>>> +   immutilWrapperProfile.nTries = 500;
>>> +   immutilWrapperProfile.retryInterval = 1000;
>>> +
>>> +   /* Initialize Om API
>>> +    */
>>> +   ais_rc = immutil_saImmOmInitialize(&immOmHandle, NULL,
>>> &immVersion);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           LOG_WA("\t%s saImmOmInitialize FAIL %d", __FUNCTION__,
>>ais_rc);
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Initialize accessor for reading attributes
>>> +    */
>>> +   ais_rc = immutil_saImmOmAccessorInitialize(immOmHandle,
>>> &accessorHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmAccessorInitialize Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +           goto done;
>>> +   }
>>> +
>>> +
>>> +   ais_rc = immutil_saImmOmAccessorGet_2(accessorHandle,
>>&object_name,
>>> +                   attribute_names, &attributes);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmAccessorGet_2 Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +           goto done_fin_Om;
>>> +   }
>>> +
>>> +   void *value;
>>> +
>>> +   /* Handle the global scAbsenceAllowed_flag */
>>> +   attribute = attributes[0];
>>> +   TRACE("%s\t attrName \"%s\"", __FUNCTION__, attribute->attrName);
>>> +   if ((attribute != NULL) && (attribute->attrValuesNumber != 0)) {
>>> +           /* scAbsenceAllowed has value. Get the value */
>>> +           value = attribute->attrValues[0];
>>> +           *attr_val = *(static_cast<SaUint32T *>(value));
>>> +           rc_attr_val = attr_val;
>>> +   }
>>> +
>>> +done_fin_Om:
>>> +   /* Free Om resources */
>>> +   ais_rc = immutil_saImmOmFinalize(immOmHandle);
>>> +   if (ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s\t saImmOmFinalize Fail '%s'",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +   }
>>> +
>>> +done:
>>> +   /* Restore immutil settings */
>>> +   immutilWrapperProfile.errorsAreFatal =
>>> tmp_immutilWrapperProfile.errorsAreFatal;
>>> +   immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
>>> +   immutilWrapperProfile.retryInterval =
>>> tmp_immutilWrapperProfile.retryInterval;
>>> +
>>> +   TRACE_LEAVE();
>>> +   return rc_attr_val;
>>> +}
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_main.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_main.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_main.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_main.cc
>>> @@ -31,21 +31,26 @@
>>>  #include <daemon.h>
>>>  #include <nid_api.h>
>>>  #include <ncs_main_papi.h>
>>> +#include <osaf_time.h>
>>>
>>>  #include "lgs.h"
>>>  #include "lgs_file.h"
>>>  #include "osaf_utility.h"
>>> +#include "lgs_recov.h"
>>>
>>>  /*
>>>
>>=================================================================
>=
>>======
>>>   *   DEFINITIONS
>>>   *
>>>
>>=================================================================
>=
>>======
>>>   */
>>> -
>>> -#define FD_TERM 0
>>> -#define FD_AMF 1
>>> -#define FD_MBCSV 2
>>> -#define FD_MBX 3
>>> -#define FD_IMM 4           /* Must be the last in the fds array */
>>> +enum {
>>> +   FD_TERM = 0,
>>> +   FD_AMF,
>>> +   FD_MBCSV,
>>> +   FD_MBX,
>>> +   FD_CLTIMER,
>>> +   FD_IMM,         /* Must be the last in the fds array */
>>> +   FD_NUM
>>> +};
>>>
>>>  #ifndef LOG_STREAM_LOW_LIMIT_PERCENT
>>>  #define LOG_STREAM_LOW_LIMIT_PERCENT 0.6 // default value for low is
>>> 60%
>>> @@ -62,6 +67,7 @@
>>>   */
>>>
>>>  static lgs_cb_t _lgs_cb;
>>> +
>>>  lgs_cb_t *lgs_cb = &_lgs_cb;
>>>  SYSF_MBX lgs_mbx; /* LGS's mailbox */
>>>
>>> @@ -83,8 +89,8 @@ uint32_t mbox_low[NCS_IPC_PRIORITY_MAX];
>>>   */
>>>  pthread_mutex_t lgs_mbox_init_mutex = PTHREAD_MUTEX_INITIALIZER;
>>>
>>> -static struct pollfd fds[5];
>>> -static nfds_t nfds = 5;
>>> +static struct pollfd fds[FD_NUM];
>>> +static nfds_t nfds = FD_NUM;
>>>  static NCS_SEL_OBJ usr1_sel_obj;
>>>
>>>  /**
>>> @@ -195,6 +201,69 @@ uint32_t lgs_configure_mailbox(void)
>>>  }
>>>
>>>  /**
>>> + * Get OpenSAF global scAbsenceAllowed configuration
>>> + */
>>> +static void init_scAbsenceAllowed()
>>> +{
>>> +   SaUint32T scAbsenceAllowed_val = 0;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   if (lgs_get_scAbsenceAllowed_attr(&scAbsenceAllowed_val) != NULL) {
>>> +           TRACE("%s\t Got scAbsenceAllowed_val = %d", __FUNCTION__,
>>> +                   scAbsenceAllowed_val);
>>> +   }
>>> +
>>> +   lgs_cb->scAbsenceAllowed = scAbsenceAllowed_val;
>>> +
>>> +   TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * Initiate recovery handling.
>>> + * Note1: This must be done during init before any streams are
>>> created
>>> + * Note2: Recovery state timer is started in the main() function
>>> + *
>>> + * If absence is allowed configuration is set:
>>> + * - Create a list of recoverable streams
>>> + * - If list is not empty set recovery state to LGS_RECOVERY
>>> + */
>>> +static void init_recovery()
>>> +{
>>> +   int list_num = 0;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   /* Set default state */
>>> +   lgs_cb->lgs_recovery_state = LGS_NORMAL;
>>> +
>>> +   /* Get the value of the scAbsenceAllowed IMM attribute for
>>> configuring
>>> +    * SC node absence handling
>>> +    */
>>> +   init_scAbsenceAllowed();
>>> +
>>> +   if (lgs_cb->scAbsenceAllowed == 0) {
>>> +           TRACE("%s Absence is not allowded", __FUNCTION__);
>>> +           TRACE_LEAVE();
>>> +           return;
>>> +   }
>>> +
>>> +   /* Create a list of recoverable (IMM object exist) streams */
>>> +   lgs_search_stream_objects();
>>> +   list_num = log_rtobj_list_no();
>>> +
>>> +   TRACE("Number of runtime objects found = %d", list_num);
>>> +
>>> +   /* set recovery state if the list is not empty */
>>> +   if (list_num != 0) {
>>> +           /* There are objects in list */
>>> +           lgs_cb->lgs_recovery_state = LGS_RECOVERY;
>>> +   }
>>> +
>>> +   TRACE_LEAVE2();
>>> +}
>>> +
>>> +/**
>>>   * Initialize log
>>>   *
>>>   * @return uns32
>>> @@ -254,6 +323,9 @@ static uint32_t log_initialize(void)
>>>             goto done;
>>>     }
>>>
>>> +   /* Initiate "headless" recovery handling */
>>> +   init_recovery();
>>> +
>>>     /* Initialize configuration stream class
>>>      * Configuration must have been initialized
>>>      */
>>> @@ -324,7 +396,11 @@ static uint32_t log_initialize(void)
>>>             /* Create streams that has configuration objects and become
>>>              * class implementer for the SaLogStreamConfig class
>>>              */
>>> -           if (lgs_imm_create_configStream(lgs_cb) != SA_AIS_OK) {
>>> +
>>> +           /* Note1: lgs_cb->immOiHandle is set in lgs_imm_init()
>>> +            * Note2: lgs_cb->logsv_root_dir must be set
>>> +            */
>>> +           if (lgs_imm_init_configStreams(lgs_cb) != SA_AIS_OK) {
>>>                     LOG_ER("lgs_imm_create_configStream FAILED");
>>>                     rc = NCSCC_RC_FAILURE;
>>>                     goto done;
>>> @@ -362,6 +438,18 @@ int main(int argc, char *argv[])
>>>     uint32_t rc;
>>>     int term_fd;
>>>
>>> +   /* File descriptor for timeout to delete not used stream runtime
>>> objects.
>>> +    * May exist after 'headless' state.
>>> +    */
>>> +   int cltimer_fd = -1;
>>> +
>>> +   /* Timeout time in seconds before clean up of runtime objects that
>>> may
>>> +    * still exist after a "headless" situation. After timeout recovery
>>> of
>>> +    * "lost" streams is no longer possible.
>>> +    */
>>> +   const time_t CLEAN_TIMEOUT = 600; /* 10 min */
>>> +   //const time_t CLEAN_TIMEOUT = 60; /* 1 min LLDTEST */
>>> +
>>>     daemonize(argc, argv);
>>>
>>>     if (log_initialize() != NCSCC_RC_SUCCESS) {
>>> @@ -372,6 +460,13 @@ int main(int argc, char *argv[])
>>>     mbx_fd = ncs_ipc_get_sel_obj(&lgs_mbx);
>>>     daemon_sigterm_install(&term_fd);
>>>
>>> +   if (log_rtobj_list_no() != 0) {
>>> +           /* Needed only if any "lost" objects are found
>>> +            * See log_initialize */
>>> +           cltimer_fd = lgs_init_timer(CLEAN_TIMEOUT);
>>> +           TRACE("%s Recovery timeout started", __FUNCTION__);
>>> +   }
>>> +
>>>     /* Set up all file descriptors to listen to */
>>>     fds[FD_TERM].fd = term_fd;
>>>     fds[FD_TERM].events = POLLIN;
>>> @@ -382,6 +477,8 @@ int main(int argc, char *argv[])
>>>     fds[FD_MBCSV].events = POLLIN;
>>>     fds[FD_MBX].fd = mbx_fd.rmv_obj;
>>>     fds[FD_MBX].events = POLLIN;
>>> +   fds[FD_CLTIMER].fd = cltimer_fd;
>>> +   fds[FD_CLTIMER].events = POLLIN;
>>>     fds[FD_IMM].fd = lgs_cb->immSelectionObject;
>>>     fds[FD_IMM].events = POLLIN;
>>>
>>> @@ -440,6 +537,25 @@ int main(int argc, char *argv[])
>>>                     }
>>>             }
>>>
>>> +           if (fds[FD_CLTIMER].revents & POLLIN) {
>>> +                   /* To avoid 'stray objects', after a timeout all runtime
>>> +                    * objects that has not been restored shall be deleted
>>> +                    */
>>> +                   TRACE("Recover state End. Clean objects");
>>> +
>>> +                   /* Close timer to free resources and stop timer poll */
>>> +                   lgs_close_timer(cltimer_fd);
>>> +                   fds[FD_CLTIMER].fd = -1;
>>> +
>>> +                   if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE) {
>>> +                           /* Delete objects left if active */
>>> +                           lgs_clean_stream_objects();
>>> +                   }
>>> +
>>> +                   /* Remove the found objects list */
>>> +                   log_rtobj_list_free();
>>> +           }
>>> +
>>>             if (fds[FD_MBX].revents & POLLIN)
>>>                     lgs_process_mbx(&lgs_mbx);
>>>
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_mbcsv.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_mbcsv.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_mbcsv.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_mbcsv.cc
>>> @@ -24,6 +24,7 @@
>>>  #include "lgs_mbcsv_v3.h"
>>>  #include "lgs_mbcsv_v2.h"
>>>  #include "lgs_mbcsv_v1.h"
>>> +#include "lgs_recov.h"
>>>
>>>  /*
>>>  LGS_CKPT_DATA_HEADER
>>> @@ -1856,6 +1857,7 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t
>>>  {
>>>     lgs_ckpt_stream_open_t *param;
>>>     log_stream_t *stream;
>>> +   int pos = 0;
>>>
>>>     TRACE_ENTER();
>>>
>>> @@ -1871,7 +1873,8 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t
>>>     /* Check that client still exist */
>>>     if ((param->clientId != invalidClient) &&
>>>             (lgs_client_get_by_id(param->clientId) == NULL)) {
>>> -           LOG_WA("\tClient %u does not exist, failed to create stream
>>'%s'",
>>> param->clientId, param->logStreamName);
>>> +           LOG_WA("\tClient %u does not exist, failed to create stream
>>'%s'",
>>> +                      param->clientId, param->logStreamName);
>>>             goto done;
>>>     }
>>>
>>> @@ -1890,7 +1893,7 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t
>>>             strcpy((char *)name.value, param->logStreamName);
>>>             name.length = strlen(param->logStreamName);
>>>
>>> -           stream = log_stream_new(&name,
>>> +           stream = log_stream_new_1(&name,
>>>                             param->logFile,
>>>                             param->logPath,
>>>                             param->maxFileSize,
>>> @@ -1901,11 +1904,12 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t
>>>                             param->streamType,
>>>                             param->streamId,
>>>                             SA_FALSE,       // FIX sync or calculate?
>>> -                           param->logRecordId);
>>> +                           param->logRecordId,
>>> +                           0);
>>>
>>>             if (stream == NULL) {
>>>                     /* Do not allow standby to get out of sync */
>>> -                   LOG_ER("%s - Failed to create stream
>>'%s'",__FUNCTION__,
>>> +                   LOG_ER("%s - Failed to create stream '%s'",
>>__FUNCTION__,
>>>                                     param->logStreamName);
>>>                     goto done;
>>>             }
>>> @@ -1923,6 +1927,9 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t
>>>      */
>>>     if (lgs_is_split_file_system()) {
>>>             if (stream->numOpeners <= 1) {
>>> +                   TRACE("%s: log_initiate_stream_files(%s)",
>>> +                             __FUNCTION__, stream->fileName.c_str());
>>> +
>>>                     log_initiate_stream_files(stream);
>>>             }
>>>     }
>>> @@ -1935,11 +1942,16 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t
>>>     if ((param->clientId != invalidClient) &&
>>>             lgs_client_stream_add(param->clientId, stream->streamId) !=
>>0) {
>>>             /* Do not allow standby to get out of sync */
>>> -           LOG_ER("%s - Failed to add stream '%s' to client
>>%u",__FUNCTION__,
>>> +           LOG_ER("%s - Failed to add stream '%s' to client %u",
>>> __FUNCTION__,
>>>                             param->logStreamName, param->clientId);
>>>             lgs_exit("Could not add stream to client",
>>> SA_AMF_COMPONENT_RESTART);
>>>     }
>>>
>>> +   /* Stream is opened  on standby. Remove from rtobj list if exist */
>>> +   pos = log_rtobj_list_find(param->logStreamName);
>>> +   if (pos != -1)
>>> +           log_rtobj_list_erase_one_pos(pos);
>>> +
>>>   done:
>>>     /* Free strings allocated by the EDU encoder */
>>>     lgs_free_edu_mem(param->logFile);
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_recov.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_recov.cc
>>> new file mode 100644
>>> --- /dev/null
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_recov.cc
>>> @@ -0,0 +1,758 @@
>>> +/*      -*- OpenSAF  -*-
>>> + *
>>> + * (C) Copyright 2016 The OpenSAF Foundation
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> MERCHANTABILITY
>>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>>> licensed
>>> + * under the GNU Lesser General Public License Version 2.1, February
>>> 1999.
>>> + * The complete license can be accessed from the following location:
>>> + * http://opensource.org/licenses/lgpl-license.php
>>> + * See the Copying file included with the OpenSAF distribution for
>>> full
>>> + * licensing terms.
>>> + *
>>> + * Author(s): Ericsson AB
>>> + *
>>> + */
>>> +
>>> +#include "lgs_recov.h"
>>> +#include "lgs_file.h"
>>> +#include "lgs_filehdl.h"
>>> +
>>> +/***
>>> + * The following functions are used to handle a list of runtime
>>> stream objects
>>> + * (application streams with runtime objects) that may be found
>>> during start of
>>> + * the log server.
>>> + * The list consists of a vector of strings containing runtime stream
>>> object
>>> + * dn:s
>>> + */
>>> +
>>> +static char **rtobj_list = NULL;
>>> +static bool rtobj_list_init_f = false;
>>> +static uint32_t rtobj_cnt = 0; /* Number of object names in list */
>>> +static SaUint32T rtobj_list_len = 0; /* Also the length of the list
>>> */
>>> +
>>> +/**
>>> + * Initiate the list by allocating memory for a vector of pointers to
>>> strings
>>> + * (char *). The number of elements will be
>>> "logMaxApplicationStreams", see log
>>> + * configuration object.
>>> + *
>>> + * @return true if initiated (list exist)
>>> + */
>>> +static bool log_rtobj_list_init()
>>> +{
>>> +   TRACE_ENTER();
>>> +
>>> +   if (rtobj_list_init_f == true)
>>> +           goto done; /* Already initiated */
>>> +
>>> +   rtobj_list_len = *static_cast<const SaUint32T *>(
>>> +           lgs_cfg_get(LGS_IMM_LOG_MAX_APPLICATION_STREAMS));
>>> +
>>> +   rtobj_list = static_cast<char **>(calloc(rtobj_list_len, sizeof(char
>>> *)));
>>> +   if (rtobj_list != NULL) {
>>> +           rtobj_list_init_f = true;
>>> +   } else {
>>> +           TRACE("%s\tFail to alloc memory for rtobj_list",
>>__FUNCTION__);
>>> +   }
>>> +
>>> +done:
>>> +   TRACE_LEAVE2("rtobj_list_init_f = %d", rtobj_list_init_f);
>>> +   return rtobj_list_init_f;
>>> +}
>>> +
>>> +/**
>>> + * Free an initialized rtobj list
>>> + *
>>> + */
>>> +void log_rtobj_list_free()
>>> +{
>>> +   TRACE_ENTER();
>>> +
>>> +   if (rtobj_list == NULL)
>>> +           return; /* No list to free */
>>> +
>>> +   /* Free positions in the list if needed */
>>> +   uint32_t pos;
>>> +   for (pos = 0; pos < rtobj_list_len; pos++) {
>>> +           if (rtobj_list[pos] != NULL)
>>> +                   free(rtobj_list[pos]);
>>> +   }
>>> +
>>> +   free(rtobj_list);
>>> +   rtobj_cnt = 0;
>>> +   rtobj_list_len = 0;
>>> +   rtobj_list = NULL;
>>> +
>>> +   TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * Add a dn name of an rt-object
>>> + *
>>> + * @param dn_str[in] '\0' terminated string containing a dn
>>> + * @return -1 on error
>>> + */
>>> +int log_rtobj_list_add(char *dn_str)
>>> +{
>>> +   char *str_ptr = NULL;
>>> +   size_t len = 0;
>>> +   int rc = 0;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   if (log_rtobj_list_init() == false) {
>>> +           TRACE("%s\trtobj_list not initiated!", __FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   if (rtobj_cnt >= rtobj_list_len) {
>>> +           /* Should be impossible */
>>> +           LOG_WA("%s\trtobj_cnt >= maxApplicationStreams!",
>>> +                   __FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Save dn string */
>>> +   len = strlen(dn_str) + 1; /* Including '\0' */
>>> +   if (len > SA_MAX_NAME_LENGTH) {
>>> +           /* Should never happen */
>>> +           LOG_WA("%s\tToo long dn string!",__FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   str_ptr = static_cast<char *>(calloc(1, len));
>>> +   if (str_ptr == NULL) {
>>> +           LOG_WA("%s\tcalloc Fail",__FUNCTION__);
>>> +           rc = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   strcpy(str_ptr, dn_str);
>>> +
>>> +   /* Add dn to list */
>>> +   rtobj_list[rtobj_cnt] = str_ptr;
>>> +   rtobj_cnt++;
>>> +
>>> +   done:
>>> +   TRACE_LEAVE2("rc = %d", rc);
>>> +   return rc;
>>> +}
>>> +
>>> +/**
>>> + * Return number of names in list
>>> + *
>>> + * @return Number of names
>>> + */
>>> +int log_rtobj_list_no()
>>> +{
>>> +   return rtobj_cnt;
>>> +}
>>> +
>>> +/**
>>> + * Find pos of the given given name in list
>>> + *
>>> + * @param dn_str[in] '\0' terminated string with dn to find
>>> + * @return Position of found name or -1 if name not found
>>> + */
>>> +int log_rtobj_list_find(char *dn_str)
>>> +{
>>> +   uint32_t i = 0;
>>> +   int pos = -1;
>>> +
>>> +   TRACE_ENTER2("dn_str \"%s\"", dn_str);
>>> +
>>> +   if (rtobj_list == NULL) {
>>> +           TRACE("\t No rtobj_list exist");
>>> +           goto done;
>>> +   }
>>> +
>>> +   for (i = 0; i < rtobj_list_len; i++) {
>>> +           if (rtobj_list[i] == NULL)
>>> +                   continue;
>>> +           if (strcmp(rtobj_list[i], dn_str) == 0) {
>>> +                   /* Found! */
>>> +                   pos = (int) i;
>>> +                   break;
>>> +           }
>>> +   }
>>> +
>>> +done:
>>> +   TRACE_LEAVE2("pos = %d", pos);
>>> +   return pos;
>>> +}
>>> +
>>> +/**
>>> + * Get pos of first name found in list.
>>> + *
>>> + * @return Position of found name or -1 if no name found
>>> + */
>>> +int log_rtobj_list_getnamepos()
>>> +{
>>> +   uint32_t i = 0;
>>> +   int pos = -1;
>>> +
>>> +   for (i = 0; i < rtobj_list_len; i++) {
>>> +           if (rtobj_list[i] == NULL) {
>>> +                   continue;
>>> +           } else {
>>> +                   pos = static_cast<int>(i);
>>> +                   break;
>>> +           }
>>> +   }
>>> +
>>> +   return pos;
>>> +}
>>> +
>>> +/**
>>> + * Get name at given pos in list.
>>> + *
>>> + * @param pos[in] Position for name to get
>>> + * @return A pointer to the string in given pos.
>>> + *         If there is no string in pos or pos is outside the list
>>> + *         NULL is returned.
>>> + */
>>> +char *log_rtobj_list_getname(int pos)
>>> +{
>>> +   if (pos >= static_cast<int>(rtobj_list_len))
>>> +           return NULL;
>>> +
>>> +   return rtobj_list[pos];
>>> +}
>>> +
>>> +/**
>>> + * "Erase" dn name at pos in list
>>> + *
>>> + * @param pos[in] Position in list to erase
>>> + */
>>> +void log_rtobj_list_erase_one_pos(int pos)
>>> +{
>>> +   TRACE_ENTER2("pos = %d", pos);
>>> +   if (pos > static_cast<int>(rtobj_list_len)) {
>>> +           TRACE_LEAVE2("%s\tPosition %d outside list!", __FUNCTION__,
>>pos);
>>> +           return;
>>> +   }
>>> +
>>> +   if (rtobj_list[pos] == NULL) {
>>> +           TRACE_LEAVE2("%s\tNo string in pos %d", __FUNCTION__,
>>pos);
>>> +           return;
>>> +   }
>>> +
>>> +   free(rtobj_list[pos]);
>>> +   rtobj_list[pos] = NULL;
>>> +
>>> +   if (rtobj_cnt > 0)
>>> +           rtobj_cnt--;
>>> +
>>> +   TRACE_LEAVE();
>>> +}
>>> +
>>> +/***
>>> + * Restore a lost runtime stream.
>>> + * Get attributes from given runtime object (if exists).
>>> + * Find the last open logfile. From the file get number of log
>>> records written
>>> + * and latest used log record id
>>> + * If fail delete the stream IMM object (if exist)
>>> + * Always delete the object name from the rtobj list
>>> + */
>>> +
>>> +/**
>>> + * Local help function
>>> + * Find the file that was current log file before server down.
>>> + * Get file size
>>> + * Get last written record Id by reading the first characters of the
>>> last
>>> + * log record in the file
>>> + *
>>> + * NOTE:
>>> + * All file handling must be done in the file thread
>>> + * See lgs_get_file_params_hdl() in lgs_filehdl.c
>>> + *
>>> + * @param fileName[in]   The name in saLogStreamFileName e.g. "app1"
>>> + * @param pathName[in]      Full path to the dir where the log file can
>>> be found
>>> + *                       root path + relative path
>>> + * @param logFileCurrent[out]
>>> + * @param curFileSize[out]
>>> + * @param logRecordId[out]
>>> + *
>>> + * @return -1 on error
>>> + */
>>> +//static int lgs_get_file_params_h(gfp_in_t *par_in, gfp_out_t
>>> *par_out)
>>> +static int lgs_get_file_params_h(gfp_in_t *par_in, gfp_out_t
>>> *par_out)
>>> +{
>>> +   lgsf_retcode_t api_rc;
>>> +   lgsf_apipar_t apipar;
>>> +   int rc = 0;
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   /* Fill in API structure */
>>> +   apipar.req_code_in = LGSF_GET_FILE_PAR;
>>> +   apipar.data_in_size = sizeof(gfp_in_t);
>>> +   apipar.data_in = par_in;
>>> +   apipar.data_out_size = sizeof(gfp_out_t);
>>> +   apipar.data_out = par_out;
>>> +
>>> +   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;
>>> +           TRACE("\t hdl_ret_code_out = %d", rc);
>>> +   }
>>> +
>>> +   TRACE_LEAVE();
>>> +   return rc;
>>> +}
>>> +
>>> +static void lgs_remove_stream(uint32_t client_id, log_stream_t
>>> *log_stream)
>>> +{
>>> +   TRACE_ENTER();
>>> +
>>> +   /* Remove the stream handle and
>>> +    * remove the stream resources
>>> +    */
>>> +       if (lgs_client_stream_rmv(client_id, log_stream->streamId) <
>>> 0) {
>>> +          TRACE("%s lgs_client_stream_rmv Fail", __FUNCTION__);
>>> +       }
>>> +
>>> +       log_free_stream_resources(log_stream);
>>> +
>>> +       log_stream = NULL;
>>> +
>>> +       TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * Restore parameters for a lost runtime (application) stream, create
>>> the
>>> + * stream in the local stream list and associate with a client.
>>> + * Remove the stream object name from the found objects list.
>>> + *
>>> + * @param stream_name[in]  The name of the stream
>>> + * @param client_id[in]    Client to recover stream for
>>> + * @param o_stream[out]    The recovered stream
>>> + *                         stream
>>> + * @return -1 on error
>>> + */
>>> +int lgs_restore_one_app_stream(
>>> +   char *stream_name, uint32_t client_id,
>>> +   log_stream_t **o_stream)
>>> +{
>>> +   int int_rc = 0;
>>> +   int rc_out = 0;
>>> +   SaAisErrorT ais_rc = SA_AIS_OK;
>>> +   SaImmHandleT immOmHandle;
>>> +   SaImmAttrValuesT_2 *attribute;
>>> +   SaImmAttrValuesT_2 **attributes;
>>> +   gfp_in_t par_in;
>>> +   gfp_out_t par_out;
>>> +   int list_pos;
>>> +   int n;
>>> +   int i = 0;
>>> +
>>> +   lgsv_stream_open_req_t open_stream_param;
>>> +   log_stream_t *log_stream = NULL;
>>> +   SaTimeT restored_creationTimeStamp = 0;
>>> +   SaUint32T restored_severityFilter = 0;
>>> +
>>> +   std::string fileName;
>>> +   std::string pathName;
>>> +
>>> +   // Make it safe for free
>>> +   par_out.curFileName = NULL;
>>> +
>>> +   TRACE_ENTER2("object_name \"%s\", client_id=%d", stream_name,
>>> client_id);
>>> +
>>> +   memset(&open_stream_param, 0, sizeof(open_stream_param));
>>> +
>>> +   /* Check and save stream file name */
>>> +   if (stream_name == NULL) {
>>> +           TRACE("%s: No object name <NULL>", __FUNCTION__);
>>> +           rc_out = -1;
>>> +           goto done;
>>> +   }
>>> +   n = snprintf(reinterpret_cast<char
>>> *>(open_stream_param.lstr_name.value),
>>> +           SA_MAX_NAME_LENGTH, "%s", stream_name);
>>> +
>>> +   open_stream_param.lstr_name.length = strlen(stream_name) + 1;
>>> +   if (n >= SA_MAX_NAME_LENGTH) {
>>> +           TRACE("Log stream name \"%s\" is truncated",
>>> +                   open_stream_param.lstr_name.value);
>>> +           rc_out = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Check if in found objects list */
>>> +   list_pos = log_rtobj_list_find(stream_name);
>>> +   if (list_pos == -1) {
>>> +           TRACE("%s: No stream \"%s\" found to restore",
>>__FUNCTION__,
>>> stream_name);
>>> +           rc_out = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Remove from list */
>>> +   log_rtobj_list_erase_one_pos(list_pos);
>>> +
>>> +   /* Get the cached attributes for the object
>>> +    */
>>> +   int_rc = lgs_get_streamobj_attr(&attributes, stream_name,
>>> &immOmHandle);
>>> +   if (int_rc == -1) {
>>> +           TRACE("%s:\t lgs_get_streamobj_attr Fail", __FUNCTION__);
>>> +           rc_out = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   /* Fill in the "lgsv_stream_open_req_t open_stream_param" struct
>>> with
>>> +    * recovered parameters, re-create the stream and add it to the
>>> client
>>> +    * Note: Before restoring a stream the client to own the stream
>>> must
>>> +    *       exist.
>>> +    */
>>> +   i = 0;
>>> +   while ((attribute = attributes[i++]) != NULL) {
>>> +           void *value;
>>> +           char *name;
>>> +           char *str_val;
>>> +
>>> +           /* Fill in parameters read from the app stream object
>>> +            */
>>> +           name = attribute->attrName;
>>> +           if (attribute->attrValuesNumber != 0)
>>> +                   value = attribute->attrValues[0];
>>> +           else {
>>> +                   value = NULL;
>>> +           }
>>> +
>>> +           TRACE("\t attribute name \"%s\"", name);
>>> +           if (!strcmp(name, "saLogStreamFileName")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +
>>> +                   fileName = *(static_cast<char **>(value));
>>> +                   TRACE("\t saLogStreamFileName \"%s\"",
>>fileName.c_str());
>>> +           } else if (!strcmp(name, "saLogStreamPathName")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +
>>> +                   pathName = *(static_cast<char **>(value));
>>> +                   TRACE("\t saLogStreamPathName \"%s\"",
>>pathName.c_str());
>>> +           } else if (!strcmp(name, "saLogStreamMaxLogFileSize")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +
>>> +                   open_stream_param.maxLogFileSize =
>>*(static_cast<SaUint64T
>>> *>(value));
>>> +                   TRACE("\t saLogStreamMaxLogFileSize = %lld",
>>> +                           open_stream_param.maxLogFileSize);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamFixedLogRecordSize")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   open_stream_param.maxLogRecordSize =
>>*(static_cast<SaUint32T
>>> *>(value));
>>> +                   TRACE("\t saLogStreamFixedLogRecordSize = %d",
>>> +                           open_stream_param.maxLogRecordSize);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamHaProperty")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   open_stream_param.haProperty =
>>*(static_cast<SaBoolT *>(value));
>>> +                   TRACE("\t saLogStreamHaProperty=%d",
>>> +                           open_stream_param.haProperty);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamLogFullAction")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   open_stream_param.logFileFullAction =
>>> *(static_cast<SaLogFileFullActionT *>(value));
>>> +                   TRACE("\t saLogStreamLogFullAction=%d",
>>> +                           open_stream_param.logFileFullAction);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamMaxFilesRotated")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   open_stream_param.maxFilesRotated =
>>*(static_cast<SaUint16T
>>> *>(value));
>>> +                   TRACE("\t saLogStreamMaxFilesRotated=%d",
>>> +                           open_stream_param.maxFilesRotated);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamLogFileFormat")) {
>>> +                   /*TBD Is this correct way of handling format?
>>> +                    * - Must be checked!
>>> +                    * - Use better max length than PATH_MAX!
>>> +                    */
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   str_val = *(static_cast<char **>(value));
>>> +                   open_stream_param.logFileFmt = NULL;
>>> +                   open_stream_param.logFileFmt = static_cast<char *>(
>>> +                           calloc(1, strlen(str_val) + 1));
>>> +                   if (open_stream_param.logFileFmt == NULL) {
>>> +                           TRACE("%s [%d] calloc Fail",
>>> +                                   __FUNCTION__, __LINE__);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   n = snprintf(open_stream_param.logFileFmt,
>>> +                           PATH_MAX, "%s", str_val);
>>> +                   open_stream_param.logFileFmtLength =
>>> +                           strlen(open_stream_param.logFileFmt);
>>> +                   if (n >= PATH_MAX) {
>>> +                           TRACE("Format string \"%s\" too long",
>>> +                                   str_val);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   TRACE("\t saLogStreamLogFileFormat \"%s\"",
>>> +                           open_stream_param.logFileFmt);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamCreationTimestamp")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   restored_creationTimeStamp = *(static_cast<SaTimeT
>>*>(value));
>>> +                   TRACE("\t saLogStreamCreationTimestamp=%lld",
>>> +                           restored_creationTimeStamp);
>>> +
>>> +           } else if (!strcmp(name, "saLogStreamSeverityFilter")) {
>>> +                   if (value == NULL) {
>>> +                           TRACE("%s: Fail, has empty value", name);
>>> +                           rc_out = -1;
>>> +                           goto done_free_attr;
>>> +                   }
>>> +                   restored_severityFilter = *(static_cast<SaUint32T
>>*>(value));
>>> +                   TRACE("\t saLogStreamSeverityFilter=%d",
>>> +                           restored_severityFilter);
>>> +           }
>>> +   }
>>> +
>>> +   /* Fill in the rest of the stream open parameters
>>> +    * and create the stream. Do not create an IMM object
>>> +    */
>>> +   open_stream_param.client_id = client_id;
>>> +   open_stream_param.lstr_open_flags = 0; /* Dummy not used here */
>>> +
>>> +   open_stream_param.logFileName = const_cast<char
>>> *>(fileName.c_str());
>>> +   open_stream_param.logFilePathName = const_cast<char
>>> *>(pathName.c_str());
>>> +
>>> +   ais_rc = create_new_app_stream(&open_stream_param, &log_stream,
>>0);
>>> +   if ( ais_rc != SA_AIS_OK) {
>>> +           TRACE("%s: create_new_app_stream Fail %s",
>>> +                   __FUNCTION__, saf_error(ais_rc));
>>> +           rc_out = -1;
>>> +           goto done_free_attr;
>>> +   }
>>> +
>>> +   /* Create an association between this client and the stream */
>>> +   int_rc = lgs_client_stream_add(client_id, log_stream->streamId);
>>> +   if (int_rc == -1) {
>>> +           TRACE("%s: lgs_client_stream_add Fail", __FUNCTION__);
>>> +           log_free_stream_resources(log_stream); /* Undo create new
>>stream
>>> */
>>> +           rc_out = -1;
>>> +           goto done_free_attr;
>>> +   }
>>> +
>>> +   /* Set values for attributes not restored when creating a stream.
>>> +    * The value must be set after the stream is created.
>>> +    * Cached:
>>> +    * - saLogStreamSeverityFilter (cached)
>>> +    * - saLogStreamCreationTimestamp (cached)
>>> +    *
>>> +    * Pure runtime:
>>> +    * - saLogStreamNumOpeners
>>> +    *   Handled when streams are opened. No recovery needed
>>> +    * - logStreamDiscardedCounter
>>> +    *   Cannot be restored. Initialized with 0
>>> +    */
>>> +   log_stream->creationTimeStamp = restored_creationTimeStamp;
>>> +   log_stream->severityFilter = restored_severityFilter;
>>> +   log_stream->filtered = 0;
>>> +
>>> +   TRACE("\t Stream obj attributes handled and stream is created");
>>> +
>>> +   /* Get recovery data from the log file and update the stream
>>> +    */
>>> +   pathName = static_cast<const char *>(
>>> +           lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY));
>>> +   pathName = pathName + "/" + open_stream_param.logFilePathName;
>>> +
>>> +   par_in.file_name = open_stream_param.logFileName;
>>> +   par_in.file_path = const_cast<char *>(pathName.c_str());
>>> +
>>> +   int_rc = lgs_get_file_params_h(&par_in, &par_out);
>>> +   if (int_rc == -1) {
>>> +           TRACE("%s:\t lgs_get_file_params_h Fail", __FUNCTION__);
>>> +            /* Remove the stream handle and
>>> +             * remove the stream resources
>>> +             */
>>> +           lgs_remove_stream(client_id, log_stream);
>>> +           rc_out = -1;
>>> +           goto done_free_attr;
>>> +   }
>>> +
>>> +   /* If no current log file create a file name
>>> +    */
>>> +   if (par_out.curFileName == NULL) {
>>> +           /* There is no current log file. Create a file name */
>>> +           log_stream->logFileCurrent = log_stream->fileName + "_" +
>>> lgs_get_time(NULL);
>>> +           TRACE("\t A new file name for current log file is created");
>>> +   } else {
>>> +           log_stream->logFileCurrent = par_out.curFileName;
>>> +   }
>>> +
>>> +   TRACE("\t Current log file \"%s\"",
>>> log_stream->logFileCurrent.c_str());
>>> +
>>> +   log_stream->curFileSize = par_out.curFileSize;
>>> +   log_stream->logRecordId = par_out.logRecordId;
>>> +
>>> +   /* The stream is open again and opened for the first time so far */
>>> +   log_stream->numOpeners = 1;
>>> +
>>> +   /* Set the stream file descriptor to -1. The file will then be
>>> opened
>>> +    * at next write.
>>> +    */
>>> +   *log_stream->p_fd = -1;
>>> +
>>> +done_free_attr:
>>> +   /* Free resources used for finding attribute values */
>>> +   int_rc = lgs_free_streamobj_attr(immOmHandle);
>>> +   if (int_rc == -1) {
>>> +           TRACE("%s:\t lgs_free_streamobj_attr Fail", __FUNCTION__);
>>> +           rc_out = -1;
>>> +   }
>>> +
>>> +done:
>>> +   free(open_stream_param.logFileFmt);
>>> +   if (par_out.curFileName != NULL) {
>>> +           // This memory is allocated in lgs_get_file_params_hdl()
>>> +           free(par_out.curFileName);
>>> +   }
>>> +
>>> +   /* Return recovered stream. Will be NULL if not recovered (rc_out =
>>> -1) */
>>> +   *o_stream = log_stream;
>>> +   TRACE_LEAVE2("rc_out = %d", rc_out);
>>> +   return rc_out;
>>> +}
>>> +
>>> +/**
>>> + * Restore lost files for a configuration stream.
>>> + * Update the stream with current log file and log record Id
>>> + *
>>> + *
>>> + * @param log_stream[in/out]
>>> + * Will/May modify the following stream parameters:
>>> + *   logFileCurrent
>>> + *   curFileSize
>>> + *   logRecordId
>>> + *   creationTimeStamp
>>> + *   *p_fd
>>> + *   numOpeners
>>> + *
>>> + * @return -1 on error
>>> + */
>>> +int log_stream_open_file_restore(log_stream_t *stream)
>>> +{
>>> +   int int_rc = 0;
>>> +   int rc_out = 0;
>>> +   gfp_in_t par_in;
>>> +   gfp_out_t par_out;
>>> +   std::string pathName, log_root_path;
>>> +   size_t name_length = lgs_max_nlength();
>>> +
>>> +   TRACE_ENTER();
>>> +
>>> +   pathName = static_cast<const char
>>> *>(lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY));
>>> +   pathName = pathName + "/" + stream->pathName;
>>> +
>>> +   par_in.file_name = const_cast<char *>(stream->fileName.c_str());
>>> +   par_in.file_path = const_cast<char *>(pathName.c_str());
>>> +
>>> +   TRACE("pathName = %s, fileName = %s, name_length = %zu",
>>> +         pathName.c_str(), stream->fileName.c_str(), name_length);
>>> +
>>> +   // Initialize the output
>>> +   par_out.curFileSize = 0;
>>> +   par_out.logRecordId = 0;
>>> +   par_out.curFileName = NULL;
>>> +
>>> +   int_rc = lgs_get_file_params_h(&par_in, &par_out);
>>> +
>>> +   /****
>>> +    * Rules for lgs_get_file_params_h():
>>> +    * - If current log file not empty: Name = cur log file, Size = file
>>> size,
>>> +    *                                  Id = fr file, rc = OK
>>> +    * - If current log file empty no rotated: Name = cur log file, Size
>>> = 0,
>>> +    *                                         Id = 1, rc = OK
>>> +    * - If current log file empty is rotated: Name = cur log file, Size
>>> = 0,
>>> +    *                                         Id = fr last rotated, rc
>>> = OK
>>> +    * - If no log file at all:  Name = NULL, Size = 0, Id = 1, rc = OK
>>> +    * - If only rotated log file: Name = NULL, Size = 0, Id = fr
>>> rotated file,
>>> +    *                             rc = OK
>>> +    */
>>> +
>>> +   if (int_rc == -1) {
>>> +           /* No relevant file info found. Recovery fail */
>>> +           TRACE("%s: lgs_get_file_params_h Fail", __FUNCTION__);
>>> +           rc_out = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   stream->logFileCurrent = par_out.curFileName;
>>> +   stream->curFileSize = par_out.curFileSize;
>>> +   stream->logRecordId = par_out.logRecordId;
>>> +
>>> +   TRACE("Out: curFileSize = %u, logRecordId = %u, logFileCurrent =
>>> %s",
>>> +         stream->curFileSize, stream->logRecordId,
>>> stream->logFileCurrent.c_str());
>>> +
>>> +   if (stream->numOpeners != 0) {
>>> +           TRACE("%s: numOpeners = %u Fail", __FUNCTION__,
>>> stream->numOpeners);
>>> +           rc_out = -1;
>>> +           goto done;
>>> +   }
>>> +
>>> +   int errno_save;
>>> +   log_root_path = static_cast<const char
>>> *>(lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY));
>>> +   *stream->p_fd = -1;
>>> +
>>> +   if ((*stream->p_fd = log_file_open(log_root_path, stream,
>>> +                                      stream->logFileCurrent,
>>> +                                      &errno_save)) == -1) {
>>> +           TRACE("%s - Could not open '%s' - %s", __FUNCTION__,
>>> +                 stream->logFileCurrent.c_str(), strerror(errno_save));
>>> +   }
>>> +
>>> +   stream->numOpeners++;
>>> +
>>> +done:
>>> +   // This memory is allocated in lgs_get_file_params_hdl()
>>> +   if (par_out.curFileName != NULL)
>>> +           free(par_out.curFileName);
>>> +
>>> +   TRACE_LEAVE2("rc_out = %d", rc_out);
>>> +   return rc_out;
>>> +}
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_recov.h
>>> b/osaf/services/saf/logsv/lgs/lgs_recov.h
>>> new file mode 100644
>>> --- /dev/null
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_recov.h
>>> @@ -0,0 +1,37 @@
>>> +/*      -*- OpenSAF  -*-
>>> + *
>>> + * (C) Copyright 2016 The OpenSAF Foundation
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> MERCHANTABILITY
>>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>>> licensed
>>> + * under the GNU Lesser General Public License Version 2.1, February
>>> 1999.
>>> + * The complete license can be accessed from the following location:
>>> + * http://opensource.org/licenses/lgpl-license.php
>>> + * See the Copying file included with the OpenSAF distribution for
>>> full
>>> + * licensing terms.
>>> + *
>>> + * Author(s): Ericsson AB
>>> + *
>>> + */
>>> +
>>> +#ifndef LGS_STATE_H
>>> +#define    LGS_STATE_H
>>> +
>>> +#include "lgs.h"
>>> +
>>> +int log_rtobj_list_add(char *dn_str);
>>> +int log_rtobj_list_no();
>>> +int log_rtobj_list_find(char *stream_name);
>>> +int log_rtobj_list_getnamepos();
>>> +char *log_rtobj_list_getname(int pos);
>>> +void log_rtobj_list_erase_one_pos(int pos);
>>> +void log_rtobj_list_free();
>>> +int lgs_restore_one_app_stream(
>>> +   char *stream_name,
>>> +   uint32_t client_id,
>>> +   log_stream_t **o_stream
>>> +   );
>>> +int log_stream_open_file_restore(log_stream_t *log_stream);
>>> +
>>> +#endif     /* LGS_STATE_H */
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_stream.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_stream.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_stream.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_stream.cc
>>> @@ -409,6 +409,33 @@ void log_stream_print(log_stream_t *stre
>>>     TRACE_2("  filtered:             %llu", stream->filtered);
>>>  }
>>>
>>> +/**
>>> + * Free stream resources
>>> + *
>>> + * @param stream[in]
>>> + */
>>> +void log_free_stream_resources(log_stream_t *stream)
>>> +{
>>> +   if (stream->streamId != 0)
>>> +           lgs_stream_array_remove(stream->streamId);
>>> +
>>> +   if (stream->pat_node.key_info != NULL)
>>> +           log_stream_remove(stream->name);
>>> +
>>> +   if (stream->logFileFormat != NULL)
>>> +           free(stream->logFileFormat);
>>> +
>>> +   delete stream;
>>> +   stream = NULL;
>>> +}
>>> +
>>> +/**
>>> + * Remove a log stream including:
>>> + * - Runtime object if application stream and active
>>> + * - Remove stream resources (allocated memory)
>>> + *
>>> + * @param s[in] Pointer to the array of streams
>>> + */
>>>  void log_stream_delete(log_stream_t **s)
>>>  {
>>>     log_stream_t *stream;
>>> @@ -469,6 +496,12 @@ static void init_log_stream_fd(log_strea
>>>   * Create a new stream object. If HA state active, create the
>>>   * correspronding IMM runtime object.
>>>   *
>>> + * Note: log_stream_new() is replaced by this function.
>>> + *       The new function is doing the same as the old but the
>>> possibility
>>> + *       to create a stream without creating a corresponding runtime
>>> object
>>> + *       is added. See creationFlag parameter
>>> + *
>>> + * Stream attributes[in]:
>>>   * @param name
>>>   * @param filename
>>>   * @param pathname
>>> @@ -484,17 +517,21 @@ static void init_log_stream_fd(log_strea
>>>   *
>>>   * @return log_stream_t*
>>>   */
>>> -log_stream_t *log_stream_new(SaNameT *dn,
>>> -                            const std::string &filename,
>>> -                            const std::string &pathname,
>>> -                        SaUint64T maxLogFileSize,
>>> -                        SaUint32T fixedLogRecordSize,
>>> -                        SaLogFileFullActionT logFullAction,
>>> -                        SaUint32T maxFilesRotated,
>>> -                        const char *logFileFormat,
>>> -                        logStreamTypeT streamType, int stream_id,
>>> -                            SaBoolT twelveHourModeFlag,
>>> -                            uint32_t logRecordId)
>>> +log_stream_t *log_stream_new_1(
>>> +   SaNameT *dn,
>>> +   const std::string &filename,
>>> +   const std::string &pathname,
>>> +   SaUint64T maxLogFileSize,
>>> +   SaUint32T fixedLogRecordSize,
>>> +   SaLogFileFullActionT logFullAction,
>>> +   SaUint32T maxFilesRotated,
>>> +   const char *logFileFormat,
>>> +   logStreamTypeT streamType,
>>> +   int stream_id,
>>> +   SaBoolT twelveHourModeFlag,
>>> +   uint32_t logRecordId,
>>> +   int creationFlag
>>> +   )
>>>  {
>>>     int rc;
>>>     log_stream_t *stream = NULL;
>>> @@ -690,10 +727,10 @@ log_stream_t *log_stream_new(SaNameT *dn
>>>  }
>>>
>>>  /**
>>> - * Create a new stream object. Do not create an IMM runtime object.
>>> + * Create a new default stream. Do not create an IMM runtime object.
>>>   * @param name
>>>   * @param stream_id
>>> - *
>>> + *
>>>   * @return log_stream_t*
>>>   */
>>>  log_stream_t *log_stream_new_2(SaNameT *name, int stream_id)
>>> @@ -704,7 +741,7 @@ log_stream_t *log_stream_new_2(SaNameT *
>>>     osafassert(name != NULL);
>>>     TRACE_ENTER2("%s, l: %u", name->value, (unsigned int)name->length);
>>>
>>> -   stream = new (std::nothrow) (log_stream_t)();
>>> +   stream = new (std::nothrow) log_stream_t();
>>>     if (stream == NULL) {
>>>             LOG_WA("calloc FAILED");
>>>             goto done;
>>> 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
>>> @@ -79,18 +79,21 @@ extern uint32_t log_stream_init();
>>>  extern void log_stream_delete(log_stream_t **s);
>>>
>>>  #define STREAM_NEW -1
>>> -extern log_stream_t *log_stream_new(SaNameT *name,
>>> -                               const std::string &filename,
>>> -                               const std::string &pathname,
>>> -                               SaUint64T maxLogFileSize,
>>> -                               SaUint32T fixedLogRecordSize,
>>> -                               SaLogFileFullActionT logFullAction,
>>> -                               SaUint32T maxFilesRotated,
>>> -                               const char *logFileFormat,
>>> -                               logStreamTypeT streamType,
>>> -                               int stream_id,
>>> -                               SaBoolT twelveHourModeFlag,
>>> -                               uint32_t logRecordId);
>>> +extern log_stream_t *log_stream_new_1(
>>> +   SaNameT *name,
>>> +   const std::string &filename,
>>> +   const std::string &pathname,
>>> +   SaUint64T maxLogFileSize,
>>> +   SaUint32T fixedLogRecordSize,
>>> +   SaLogFileFullActionT logFullAction,
>>> +   SaUint32T maxFilesRotated,
>>> +   const char *logFileFormat,
>>> +   logStreamTypeT streamType,
>>> +   int stream_id,
>>> +   SaBoolT twelveHourModeFlag,
>>> +   uint32_t logRecordId,
>>> +   int creationFlag
>>> +   );
>>>
>>>  extern log_stream_t *log_stream_new_2(SaNameT *name, int stream_id);
>>>
>>> @@ -118,5 +121,6 @@ extern log_stream_t *log_stream_get_by_n
>>>  extern log_stream_t *log_stream_getnext_by_name(const char *name);
>>>  extern void log_stream_print(log_stream_t *stream);
>>>  extern log_stream_t *log_stream_get_by_id(uint32_t id);
>>> +void log_free_stream_resources(log_stream_t *stream);
>>>
>>>  #endif
>>> diff --git a/osaf/services/saf/logsv/lgs/lgs_util.cc
>>> b/osaf/services/saf/logsv/lgs/lgs_util.cc
>>> --- a/osaf/services/saf/logsv/lgs/lgs_util.cc
>>> +++ b/osaf/services/saf/logsv/lgs/lgs_util.cc
>>> @@ -30,12 +30,13 @@
>>>
>>>  #include <stdlib.h>
>>>  #include <grp.h>
>>> +#include <osaf_time.h>
>>>
>>>  #include "immutil.h"
>>>  #include "lgs.h"
>>>  #include "lgs_file.h"
>>>  #include "lgs_filehdl.h"
>>> -#include "osaf_time.h"
>>> +#include "osaf_timerfd.h"
>>>
>>>  #define ALARM_STREAM_ENV_PREFIX "ALARM"
>>>  #define NOTIFICATION_STREAM_ENV_PREFIX "NOTIFICATION"
>>> @@ -239,14 +240,14 @@ SaTimeT lgs_get_SaTime()
>>>   * @param root_path[in]
>>>   * @param rel_path[in]
>>>   * @param old_name[in]
>>> - * @param time_stamp[in]
>>> + * @param time_stamp[in]
>>>   *        Can be set to NULL but then new_name must be the complete
>>> new name
>>>   *        including time stamps but without suffix
>>>   * @param suffix[in]
>>> - * @param new_name[in/out]
>>> - *        Pointer to char string of NAME_MAX size
>>> + * @param new_name[in/out]
>>> + *        Pointer to char string
>>>   *        Filename of renamed file. Can be set to NULL
>>> - *
>>> + *
>>>   * @return -1 if error
>>>   */
>>>  int lgs_file_rename_h(
>>> @@ -638,6 +639,45 @@ done:
>>>  }
>>>
>>>  /**
>>> + * Initiate a timer:
>>> + * Creates a timeout timer, set timeout time and starts the timer
>>> + * returns a file descriptor to the timer that can be used with
>>> poll()
>>> + * See also osaf_timerfd.h
>>> + *
>>> + * @param timeout_s[in] Timeout time in seconds
>>> + * @return fd  File descriptor referring to the created timer
>>> + */
>>> +int lgs_init_timer(time_t timeout_s)
>>> +{
>>> +   int fd;
>>> +   struct itimerspec lgs_cltimer;
>>> +
>>> +   fd = osaf_timerfd_create(CLOCK_MONOTONIC, 0);
>>> +
>>> +   /* Set timeout time. Do not use as interval timer */
>>> +   lgs_cltimer.it_interval.tv_sec = 0;
>>> +   lgs_cltimer.it_interval.tv_nsec = 0;
>>> +   /* Set timeout in seconds */
>>> +   lgs_cltimer.it_value.tv_sec = timeout_s;
>>> +   lgs_cltimer.it_value.tv_nsec = 0;
>>> +
>>> +   osaf_timerfd_settime(fd, 0, &lgs_cltimer, NULL);
>>> +
>>> +   return fd;
>>> +}
>>> +
>>> +/**
>>> + * Close a timer created with lgs_init_timer()
>>> + * See also osaf_timerfd.h
>>> + *
>>> + * @param ufd[in]
>>> + */
>>> +void lgs_close_timer(int ufd)
>>> +{
>>> +   osaf_timerfd_close(ufd);
>>> +}
>>> +
>>> +/**
>>>   * Validate if string contains special characters or not
>>>   *
>>>   * @param: str [in] input string for checking
>>> 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
>>> @@ -77,4 +77,8 @@ bool lgs_is_valid_pathlength(const std::
>>>                               const std::string &fileName,
>>>                          const std::string &rootPath = "");
>>>
>>> +/* Timer functions */
>>> +int lgs_init_timer(time_t timeout_s);
>>> +void lgs_close_timer(int ufd);
>>> +
>>>  #endif   /* ifndef __LGS_UTIL_H */

Attachment: lgsv_cloud_fix_rvcomment_p2.patch
Description: Binary data

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to