Ack,

Iam not yet through with the testing, but you please go ahead to push the patch
as you deem appropriate.

Thanks,
Mathi.

----- vu.m.ngu...@dektech.com.au wrote:

> Sorry. Please take this attach.
> 
> Regards, Vu.
> 
> 
> >-----Original Message-----
> >From: Vu Minh Nguyen [mailto:vu.m.ngu...@dektech.com.au]
> >Sent: Thursday, February 25, 2016 9:23 AM
> >To: 'Mathivanan Naickan Palanivelu'; lennart.l...@ericsson.com
> >Cc: opensaf-devel@lists.sourceforge.net
> >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:mathi.naic...@oracle.com]
> >>Sent: Wednesday, February 24, 2016 5:24 PM
> >>To: vu.m.ngu...@dektech.com.au
> >>Cc: lennart.l...@ericsson.com; opensaf-devel@lists.sourceforge.net;
> >>anders.wid...@ericsson.com
> >>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.
> >>
> >>----- vu.m.ngu...@dektech.com.au 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 */

------------------------------------------------------------------------------
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
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to