Hi Canh One more thing: The Log PR document must be updated. Filter callback is now supported, version handling is changed and minor version 3 must be set if callback shall be used
Thanks Lennart > -----Original Message----- > From: Canh Van Truong [mailto:canh.v.tru...@dektech.com.au] > Sent: den 1 januari 2017 13:27 > To: Lennart Lund <lennart.l...@ericsson.com>; Vu Minh Nguyen > <vu.m.ngu...@dektech.com.au>; mahesh.va...@oracle.com > Cc: opensaf-devel@lists.sourceforge.net > Subject: [PATCH 1 of 1] log: implement SaLogFilterSetCallbackT [#2146] > > src/log/agent/lga.h | 3 + > src/log/agent/lga_api.c | 2 +- > src/log/agent/lga_mds.c | 70 +++++ > src/log/agent/lga_util.c | 60 ++++- > src/log/apitest/logtest.c | 2 +- > src/log/apitest/logtestfr.c | 2 +- > src/log/apitest/saflogtest.c | 2 +- > src/log/apitest/tet_LogOiOps.c | 71 +++++ > src/log/apitest/tet_log_longDN.c | 2 +- > src/log/apitest/tet_saLogFilterSetCallbackT.c | 364 > +++++++++++++++++++++++++- > src/log/apitest/tet_saLogStreamOpen_2.c | 2 - > src/log/common/lgsv_defs.h | 2 +- > src/log/common/lgsv_msg.h | 7 + > src/log/logd/lgs_imm.cc | 7 + > src/log/logd/lgs_mds.cc | 57 ++- > src/log/logd/lgs_util.cc | 80 +++++ > src/log/logd/lgs_util.h | 2 + > src/log/tools/saf_logger.c | 2 +- > src/osaf/saflog/saflog.c | 4 +- > 19 files changed, 707 insertions(+), 34 deletions(-) > > > Implement SaLogFilterSetCallbackT which is mentioned at section 3.6.5 > SaLogFilterSetCallbackT @ AIS LOG document. > > LGS: > - Whenever severity filter is changed for app and systerm streams, lgs > will > find which clients that associate with the stream. Then lgs sends > message > callback to clients. > - Encoding callback message for severity filter callback > > LGA: > - Decoding callback message for severity callback from lgs and send the > message > to the client which setting filter callback. > - Dispatching severity filter callback > > - Encrease version of log service to A.02.03 > > diff --git a/src/log/agent/lga.h b/src/log/agent/lga.h > --- a/src/log/agent/lga.h > +++ b/src/log/agent/lga.h > @@ -155,5 +155,8 @@ extern bool lga_validate_lga_client_hdl( > extern lga_client_hdl_rec_t *lga_find_hdl_rec_by_regid(lga_cb_t *lga_cb, > uint32_t client_id); > extern void lga_msg_destroy(lgsv_msg_t *msg); > extern bool lga_is_extended_name_valid(const SaNameT* name); > +extern lga_log_stream_hdl_rec_t > *lga_find_stream_hdl_rec_by_regid(lga_cb_t *lga_cb, > + uint32_t > client_id, > + uint32_t > stream_id); > > #endif // LOG_AGENT_LGA_H_ > diff --git a/src/log/agent/lga_api.c b/src/log/agent/lga_api.c > --- a/src/log/agent/lga_api.c > +++ b/src/log/agent/lga_api.c > @@ -406,11 +406,11 @@ SaAisErrorT saLogDispatch(SaLogHandleT l > rc = SA_AIS_ERR_UNAVAILABLE; > goto done; > } > - osaf_mutex_unlock_ordie(&lga_cb.cb_lock); > > if ((rc = lga_hdl_cbk_dispatch(&lga_cb, hdl_rec, dispatchFlags)) != > SA_AIS_OK) > TRACE("LGA_DISPATCH_FAILURE"); > > + osaf_mutex_unlock_ordie(&lga_cb.cb_lock); > ncshm_give_hdl(logHandle); > > done: > diff --git a/src/log/agent/lga_mds.c b/src/log/agent/lga_mds.c > --- a/src/log/agent/lga_mds.c > +++ b/src/log/agent/lga_mds.c > @@ -559,6 +559,39 @@ static uint32_t lga_lgs_msg_proc(lga_cb_ > } > break; > > + case LGSV_SEVERITY_FILTER_CALLBACK: > + { > + lga_client_hdl_rec_t *lga_hdl_rec; > + /** Lookup the hdl rec by client_id **/ > + lga_hdl_rec = lga_find_hdl_rec_by_regid(cb, > lgsv_msg->info.cbk_info.lgs_client_id); > + if (lga_hdl_rec == NULL) { > + TRACE("regid not found"); > + lga_msg_destroy(lgsv_msg); > + TRACE_LEAVE(); > + return NCSCC_RC_FAILURE; > + } > + > + /* Check if client did not set filter callback > */ > + if(lga_hdl_rec- > >reg_cbk.saLogFilterSetCallback == NULL) { > + lga_msg_destroy(lgsv_msg); > + break; > + } > + > + > TRACE_2("LGSV_SEVERITY_FILTER_CALLBACK: client_id = %d, > stream_id %d, severity=%d", > + (int)lgsv_msg- > >info.cbk_info.lgs_client_id, > + (int)lgsv_msg- > >info.cbk_info.lgs_stream_id, > + (int)lgsv_msg- > >info.cbk_info.serverity_filter_cbk.log_severity); > + > + /** enqueue this message **/ > + if (NCSCC_RC_SUCCESS != > m_NCS_IPC_SEND(&lga_hdl_rec->mbx, lgsv_msg, prio)) { > + TRACE("IPC SEND FAILED"); > + lga_msg_destroy(lgsv_msg); > + TRACE_LEAVE(); > + return NCSCC_RC_FAILURE; > + } > + } > + break; > + > default: > TRACE("unknown type %d", lgsv_msg- > >info.cbk_info.type); > lga_msg_destroy(lgsv_msg); > @@ -932,6 +965,36 @@ static uint32_t lga_dec_clm_node_status_ > } > > > /********************************************************** > ****************** > +Name : lga_dec_serverity_cbk_msg > + > +Description : This routine decodes message > + > +Arguments : NCS_UBAID *uba, > + LGSV_MSG *msg > + > +Return Values : uint32_t > + > +Notes : None. > +********************************************************* > *********************/ > +static uint32_t lga_dec_serverity_cbk_msg(NCS_UBAID *uba, lgsv_msg_t > *msg) > +{ > + uint8_t *p8; > + uint32_t total_bytes = 0; > + lgsv_cbk_info_t *cbk_infos = &msg->info.cbk_info; > + uint8_t local_data[100]; > + > + osafassert(uba != NULL); > + > + p8 = ncs_dec_flatten_space(uba, local_data, 6); > + cbk_infos->lgs_stream_id = ncs_decode_32bit(&p8); > + cbk_infos->serverity_filter_cbk.log_severity = > ncs_decode_16bit(&p8); > + ncs_dec_skip_space(uba, 6); > + total_bytes += 6; > + > + return total_bytes; > +} > + > +/********************************************************* > ******************* > Name : lga_dec_lstr_open_sync_rsp_msg > > Description : This routine decodes a log stream open sync response > message > @@ -1053,6 +1116,13 @@ static uint32_t lga_mds_dec(struct ncsmd > msg- > >info.cbk_info.lgs_client_id); > total_bytes += > lga_dec_clm_node_status_cbk_msg(uba, msg); > break; > + case LGSV_SEVERITY_FILTER_CALLBACK: > + total_bytes += > lga_dec_serverity_cbk_msg(uba, msg); > + TRACE_2("decode severity filter message, > lgs_client_id=%d" > + " lgs_stream_id=%d", > + msg- > >info.cbk_info.lgs_client_id, > + msg- > >info.cbk_info.lgs_stream_id); > + break; > default: > TRACE_2("Unknown callback type = %d!", > msg->info.cbk_info.type); > break; > diff --git a/src/log/agent/lga_util.c b/src/log/agent/lga_util.c > --- a/src/log/agent/lga_util.c > +++ b/src/log/agent/lga_util.c > @@ -171,6 +171,19 @@ static void lga_hdl_cbk_rec_prc(lga_cb_t > reg_cbk->saLogWriteLogCallback(cbk_info- > >inv, cbk_info->write_cbk.error); > } > break; > + > + case LGSV_SEVERITY_FILTER_CALLBACK: > + { > + if (reg_cbk->saLogFilterSetCallback) { > + lga_log_stream_hdl_rec_t *lga_str_hdl_rec = > + > lga_find_stream_hdl_rec_by_regid(cb, cbk_info->lgs_client_id, > + > cbk_info->lgs_stream_id); > + reg_cbk- > >saLogFilterSetCallback(lga_str_hdl_rec->log_stream_hdl, > + cbk_info- > >serverity_filter_cbk.log_severity); > + } > + } > + break; > + > default: > TRACE("unknown callback type: %d", cbk_info->type); > break; > @@ -197,7 +210,8 @@ static SaAisErrorT lga_hdl_cbk_dispatch_ > /* Nonblk receive to obtain the message from priority queue */ > while (NULL != (cbk_msg = (lgsv_msg_t *) > m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, > cbk_msg))) { > - if (cbk_msg->info.cbk_info.type == > LGSV_WRITE_LOG_CALLBACK_IND) { > + if (cbk_msg->info.cbk_info.type == > LGSV_WRITE_LOG_CALLBACK_IND || > + cbk_msg->info.cbk_info.type == > LGSV_SEVERITY_FILTER_CALLBACK) { > lga_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec- > >reg_cbk); > lga_msg_destroy(cbk_msg); > break; > @@ -232,7 +246,8 @@ static uint32_t lga_hdl_cbk_dispatch_all > do { > if (NULL == (cbk_msg = (lgsv_msg_t > *)m_NCS_IPC_NON_BLK_RECEIVE(&hdl_rec->mbx, cbk_msg))) > break; > - if (cbk_msg->info.cbk_info.type == > LGSV_WRITE_LOG_CALLBACK_IND) { > + if (cbk_msg->info.cbk_info.type == > LGSV_WRITE_LOG_CALLBACK_IND || > + cbk_msg->info.cbk_info.type == > LGSV_SEVERITY_FILTER_CALLBACK) { > TRACE_2("LGSV_LGS_DELIVER_EVENT"); > lga_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec- > >reg_cbk); > } else { > @@ -268,7 +283,8 @@ static uint32_t lga_hdl_cbk_dispatch_blo > if (NULL != (cbk_msg = (lgsv_msg_t *) > m_NCS_IPC_RECEIVE(&hdl_rec->mbx, cbk_msg))) > { > > - if (cbk_msg->info.cbk_info.type == > LGSV_WRITE_LOG_CALLBACK_IND) { > + if (cbk_msg->info.cbk_info.type == > LGSV_WRITE_LOG_CALLBACK_IND || > + cbk_msg->info.cbk_info.type == > LGSV_SEVERITY_FILTER_CALLBACK) { > TRACE_2("LGSV_LGS_DELIVER_EVENT"); > lga_hdl_cbk_rec_prc(cb, cbk_msg, &hdl_rec- > >reg_cbk); > } else { > @@ -461,6 +477,44 @@ lga_client_hdl_rec_t *lga_find_hdl_rec_b > } > > > /********************************************************** > ****************** > + Name : lga_find_stream_hdl_rec_by_regid > + > + Description : This routine looks up a lga_log_stream_hdl_rec by client_id > + and stream_id > + > + Arguments : cb > + client_id > + stream_id > + > + Return Values : LGA_LOG_STREAM_HDL_REC * or NULL > + > + Notes : The lga_cb in-parameter is most likely pointing to the > global > + lga_cb structure and that is not thread safe. If that is > the > + case the lga_cb data must be protected by a mutex before > + calling this function. > + > +********************************************************* > *********************/ > +lga_log_stream_hdl_rec_t *lga_find_stream_hdl_rec_by_regid(lga_cb_t > *lga_cb, > + uint32_t client_id, uint32_t > stream_id) > +{ > + TRACE_ENTER(); > + lga_client_hdl_rec_t *lga_hdl_rec = > lga_find_hdl_rec_by_regid(lga_cb, client_id); > + > + if (lga_hdl_rec != NULL) { > + lga_log_stream_hdl_rec_t *lga_str_hdl_rec = lga_hdl_rec- > >stream_list; > + > + while (lga_str_hdl_rec != NULL) { > + if (lga_str_hdl_rec->lgs_log_stream_id == stream_id) > + return lga_str_hdl_rec; > + lga_str_hdl_rec = lga_str_hdl_rec->next; > + } > + } > + > + TRACE_LEAVE(); > + return NULL; > +} > + > +/********************************************************* > ******************* > Name : lga_hdl_list_del > > Description : This routine deletes all handles for this library. > diff --git a/src/log/apitest/logtest.c b/src/log/apitest/logtest.c > --- a/src/log/apitest/logtest.c > +++ b/src/log/apitest/logtest.c > @@ -93,7 +93,7 @@ SaLogRecordT genLogRecord = > .logBuffer = &genLogBuffer > }; > > -SaVersionT logVersion = {'A', 0x02, 0x02}; > +SaVersionT logVersion = {'A', 0x02, 0x03}; > SaVersionT immVersion = {'A', 2, 11}; > SaAisErrorT rc; > SaLogHandleT logHandle; > diff --git a/src/log/apitest/logtestfr.c b/src/log/apitest/logtestfr.c > --- a/src/log/apitest/logtestfr.c > +++ b/src/log/apitest/logtestfr.c > @@ -40,7 +40,7 @@ > > /********************************************************** > ********************* > * Global variables and defines > */ > -static SaVersionT logVersion = {'A', 0x02, 0x02}; > +static SaVersionT logVersion = {'A', 0x02, 0x03}; > static SaVersionT immVersion = {'A', 2, 11}; > > static SaLogHandleT logHandle; > diff --git a/src/log/apitest/saflogtest.c b/src/log/apitest/saflogtest.c > --- a/src/log/apitest/saflogtest.c > +++ b/src/log/apitest/saflogtest.c > @@ -86,7 +86,7 @@ static inline void time_meas_log(time_me > static void logWriteLogCallbackT(SaInvocationT invocation, SaAisErrorT > error); > > static SaLogCallbacksT logCallbacks = { 0, 0, logWriteLogCallbackT }; > -static SaVersionT logVersion = { 'A', 0x02, 0x02 }; > +static SaVersionT logVersion = { 'A', 0x02, 0x03 }; > > static char *progname = "saflogtest"; > static SaInvocationT cb_invocation; > diff --git a/src/log/apitest/tet_LogOiOps.c b/src/log/apitest/tet_LogOiOps.c > --- a/src/log/apitest/tet_LogOiOps.c > +++ b/src/log/apitest/tet_LogOiOps.c > @@ -1383,6 +1383,76 @@ done: > logFinalize(); > } > > +void verFilterOut(void) > +{ > + int ret; > + SaAisErrorT rc; > + char command[MAX_DATA]; > + const unsigned int serverity_filter = 31; > + FILE *fp = NULL; > + char fileSize_c[10]; > + int fileSize = 0; > + > + rc = logInitialize(); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + return; > + } > + > + rc = logAppStreamOpen(&app1StreamName, > &appStreamLogFileCreateAttributes); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + /* Set severity filter to enable log records have sev: emerg, alert, > crit, > error, warn */ > + sprintf(command, "immadm -o 1 -p > saLogStreamSeverityFilter:SA_UINT32_T:%d %s", > + serverity_filter, SA_LOG_STREAM_APPLICATION1); > + ret = systemCall(command); > + if (ret != 0) { > + test_validate(ret, 0); > + goto done; > + } > + > + /* saflogtest sends messages */ > + sprintf(command, "saflogtest -a saLogApplication1 --count=2 -- > interval=20 --severity=notice" > + " \"Test filter out, log records are not writen to log file\""); > + rc = system(command); > + if (rc == -1) { > + test_validate(rc, 0); > + goto done; > + } > + > + /* Check if log file is empty or not*/ > + sprintf(command, "find %s/saflogtest -type f -mmin -1 " > + "| egrep \"%s_([0-9]{8}_[0-9]{6}\\.log$)\" " > + "| xargs wc -c | awk '{printf $1}'", > + log_root_path, DEFAULT_APP_FILE_NAME); > + > + fp = popen(command, "r"); > + > + if (fp == NULL) { > + /* Fail to read size of log file. Report test failed. */ > + fprintf(stderr, "Failed to run command = %s\n", command); > + test_validate(1, 0); > + goto done; > + } > + /* Get file size in chars */ > + while (fgets(fileSize_c, sizeof(fileSize_c) - 1, fp) != NULL) {}; > + pclose(fp); > + > + /* Convert chars to number */ > + fileSize = atoi(fileSize_c); > + > + if (fileSize != 0) { > + fprintf(stderr, "Log file has log records\n"); > + } > + rc_validate(fileSize, 0); > + > +done: > + logFinalize(); > +} > + > /* > ========================================================== > =================== > * Test log service configuration object, suite 5 > * > ========================================================== > =================== > @@ -4298,6 +4368,7 @@ done: > test_case_add(4, verNetworkName_01, "CCB Object Modify, > saLogStreamLogFileFormat, network name token (@Cp)"); > test_case_add(4, verDefaultLogFileFmt, "Application stream with > default log file format"); > test_case_add(4, verLogFileName, "CCB Object Modify, > saLogStreamFileName with special character. ER"); > + test_case_add(4, verFilterOut, "CCB Object Modify, > saLogStreamSeverityFilter, filtering out log record that aren't written to log > file"); > > /* Configuration object */ > test_suite_add(5, "LOG OI tests, Service configuration object"); > diff --git a/src/log/apitest/tet_log_longDN.c > b/src/log/apitest/tet_log_longDN.c > --- a/src/log/apitest/tet_log_longDN.c > +++ b/src/log/apitest/tet_log_longDN.c > @@ -87,7 +87,7 @@ static SaNameT notifyingObjLd; > static SaNameT logStreamNameLd; > static SaLogBufferT logBufferLd; > static SaNtfClassIdT notificationClassIdLd = { 1, 2, 3 }; > -static SaVersionT logVersionLd = { 'A', 2, 2 }; > +static SaVersionT logVersionLd = { 'A', 2, 3 }; > static SaInvocationT invocationLd; > static SaAisErrorT errorLd; > > diff --git a/src/log/apitest/tet_saLogFilterSetCallbackT.c > b/src/log/apitest/tet_saLogFilterSetCallbackT.c > --- a/src/log/apitest/tet_saLogFilterSetCallbackT.c > +++ b/src/log/apitest/tet_saLogFilterSetCallbackT.c > @@ -15,10 +15,372 @@ > * > */ > > +#include <poll.h> > #include "logtest.h" > > +#define MAX_DATA 256 > +#define MAX_CLIENTS 2 > +static SaLogSeverityFlagsT log_severity[8]; > +static SaLogStreamHandleT log_streamHandle[8]; > +static int cb_index; > + > +static void logFilterSetCallbackT(SaLogStreamHandleT logStreamHandle, > SaLogSeverityFlagsT logSeverity) > +{ > + log_streamHandle[cb_index] = logStreamHandle; > + log_severity[cb_index] = logSeverity; > + cb_index++; > +} > + > +static SaLogFileCreateAttributesT_2 appStreamLogFileCreateAttributes = > +{ > + .logFilePathName = DEFAULT_APP_FILE_PATH_NAME, > + .logFileName = DEFAULT_APP_FILE_NAME, > + .maxLogFileSize = DEFAULT_APP_LOG_FILE_SIZE, > + .maxLogRecordSize = DEFAULT_APP_LOG_REC_SIZE, > + .haProperty = SA_TRUE, > + .logFileFullAction = SA_LOG_FILE_FULL_ACTION_ROTATE, > + .maxFilesRotated = DEFAULT_MAX_FILE_ROTATED, > + .logFileFmt = DEFAULT_FORMAT_EXPRESSION > +}; > + > void saLogFilterSetCallbackT_01(void) > { > - test_validate(SA_AIS_ERR_NOT_SUPPORTED, > SA_AIS_ERR_NOT_SUPPORTED); > + int ret; > + SaAisErrorT rc; > + struct pollfd fds[1]; > + char command[MAX_DATA]; > + const unsigned int serverity_filter = 7; > + SaUint32T v_saLogStreamSeverityFilter = 127; > + > + logCallbacks.saLogFilterSetCallback = logFilterSetCallbackT; > + rc = logInitialize(); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + return; > + } > + rc = saLogSelectionObjectGet(logHandle, &selectionObject); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + rc = logStreamOpen(&systemStreamName); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + cb_index = 0; > + /* Backup saLogStreamSeverityFilter value */ > + get_attr_value(&systemStreamName, "saLogStreamSeverityFilter", > + &v_saLogStreamSeverityFilter); > + > + sprintf(command, "immcfg %s -a saLogStreamSeverityFilter=%d 2> > /dev/null", > + SA_LOG_STREAM_SYSTEM, serverity_filter); > + ret = systemCall(command); > + if (ret != 0) { > + test_validate(ret, 0); > + goto done; > + } > + > + fds[0].fd = (int) selectionObject; > + fds[0].events = POLLIN; > + ret = poll(fds, 1, 1000); > + if (ret != 1) { > + fprintf(stderr, " poll log callback failed: %d \n", ret); > + test_validate(ret, 1); > + goto done; > + } > + > + rc = saLogDispatch(logHandle, SA_DISPATCH_ONE); > + if (rc != SA_AIS_OK) { > + fprintf(stderr, " saLogDispatch failed: %d \n", (int)rc); > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + if (log_streamHandle[0] == logStreamHandle && log_severity[0] == > serverity_filter) { > + test_validate(SA_AIS_OK, SA_AIS_OK); > + } else { > + test_validate(0, SA_AIS_OK); > + } > + > +done: > + logCallbacks.saLogFilterSetCallback = NULL; > + logFinalize(); > + /* Restore saLogStreamSeverityFilter attribute */ > + sprintf(command, "immcfg %s -a saLogStreamSeverityFilter=%d 2> > /dev/null", > + SA_LOG_STREAM_SYSTEM, v_saLogStreamSeverityFilter); > + systemCall(command); > } > > +void saLogFilterSetCallbackT_02(void) > +{ > + int ret; > + SaAisErrorT rc; > + struct pollfd fds[1]; > + char command[MAX_DATA]; > + const unsigned int serverity_filter = 7; > + > + logCallbacks.saLogFilterSetCallback = logFilterSetCallbackT; > + rc = logInitialize(); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + return; > + } > + rc = saLogSelectionObjectGet(logHandle, &selectionObject); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + rc = logAppStreamOpen(&app1StreamName, > &appStreamLogFileCreateAttributes); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + cb_index = 0; > + sprintf(command, "immadm -o 1 -p > saLogStreamSeverityFilter:SA_UINT32_T:%d %s 2> /dev/null", > + serverity_filter, SA_LOG_STREAM_APPLICATION1); > + ret = systemCall(command); > + if (ret != 0) { > + test_validate(ret, 0); > + goto done; > + } > + > + fds[0].fd = (int) selectionObject; > + fds[0].events = POLLIN; > + ret = poll(fds, 1, 1000); > + if (ret != 1) { > + fprintf(stderr, " poll log callback failed: %d \n", ret); > + test_validate(ret, 1); > + goto done; > + } > + > + rc = saLogDispatch(logHandle, SA_DISPATCH_ONE); > + if (rc != SA_AIS_OK) { > + fprintf(stderr, " saLogDispatch failed: %d \n", (int)rc); > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + if (log_streamHandle[0] == logStreamHandle && log_severity[0] == > serverity_filter) { > + test_validate(SA_AIS_OK, SA_AIS_OK); > + } else { > + test_validate(0, SA_AIS_OK); > + } > + > +done: > + logCallbacks.saLogFilterSetCallback = NULL; > + logFinalize(); > +} > + > +void saLogFilterSetCallbackT_03(void) > +{ > + int ret; > + SaAisErrorT rc; > + struct pollfd fds[1]; > + char command[MAX_DATA]; > + const unsigned int serverity_filter[2] = {7, 15}; > + SaUint32T v_saLogStreamSeverityFilter = 127; > + SaLogStreamHandleT logStreamHandle[2]; > + > + logCallbacks.saLogFilterSetCallback = logFilterSetCallbackT; > + rc = saLogInitialize(&logHandle, &logCallbacks, &logVersion); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + return; > + } > + rc = saLogSelectionObjectGet(logHandle, &selectionObject); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + rc = saLogStreamOpen_2(logHandle, &systemStreamName, NULL, 0, > + SA_TIME_ONE_SECOND, &logStreamHandle[0]); > + if (rc != SA_AIS_OK) { > + fprintf(stderr, " saLogStreamOpen_2 for system stream > failed: %d \n", (int)rc); > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + rc = saLogStreamOpen_2(logHandle, &app1StreamName, > &appStreamLogFileCreateAttributes, > + SA_LOG_STREAM_CREATE, > SA_TIME_ONE_SECOND, &logStreamHandle[1]); > + if (rc != SA_AIS_OK) { > + fprintf(stderr, " saLogStreamOpen_2 app stream failed: %d > \n", (int)rc); > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + cb_index = 0; > + /* Backup saLogStreamSeverityFilter value */ > + get_attr_value(&systemStreamName, "saLogStreamSeverityFilter", > + &v_saLogStreamSeverityFilter); > + /* Changing severity filter for system and app1 stream */ > + sprintf(command, "immcfg %s -a saLogStreamSeverityFilter=%d 2> > /dev/null", > + SA_LOG_STREAM_SYSTEM, serverity_filter[0]); > + ret = systemCall(command); > + if (ret != 0) { > + test_validate(ret, 0); > + goto done; > + } > + sleep(1); > + sprintf(command, "immadm -o 1 -p > saLogStreamSeverityFilter:SA_UINT32_T:%d %s 2> /dev/null", > + serverity_filter[1], SA_LOG_STREAM_APPLICATION1); > + ret = systemCall(command); > + if (ret != 0) { > + test_validate(ret, 0); > + goto done; > + } > + > + fds[0].fd = (int) selectionObject; > + fds[0].events = POLLIN; > + ret = poll(fds, 1, 1000); > + if (ret != 1) { > + fprintf(stderr, " poll log callback failed: %d \n", ret); > + test_validate(ret, 1); > + goto done; > + } > + > + rc = saLogDispatch(logHandle, SA_DISPATCH_ALL); > + if (rc != SA_AIS_OK) { > + fprintf(stderr, " saLogDispatch failed: %d \n", (int)rc); > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + if (cb_index != 2) { > + printf("cb_index = %u\n", cb_index); > + test_validate(SA_AIS_ERR_LIBRARY, SA_AIS_OK); > + goto done; > + } > + > + for (int i = 0; i < 2; i++) { > + if ((log_streamHandle[i] != logStreamHandle[i]) || > (log_severity[i] != serverity_filter[i])) { > + printf("log streamHandle: %llu, expected %llu \n", > log_streamHandle[i], logStreamHandle[i]); > + printf("log severity filter: %d, expected %d \n", > log_severity[i], > serverity_filter[i]); > + test_validate(0, SA_AIS_OK); > + goto done; > + } > + } > + > + test_validate(SA_AIS_OK, SA_AIS_OK); > + > +done: > + logCallbacks.saLogFilterSetCallback = NULL; > + logFinalize(); > + /* Restore saLogStreamSeverityFilter attribute */ > + sprintf(command, "immcfg %s -a saLogStreamSeverityFilter=%d 2> > /dev/null", > + SA_LOG_STREAM_SYSTEM, v_saLogStreamSeverityFilter); > + systemCall(command); > +} > + > + > +void saLogFilterSetCallbackT_04(void) > +{ > + int ret; > + SaAisErrorT rc; > + struct pollfd fds[MAX_CLIENTS]; > + char command[MAX_DATA]; > + const unsigned int serverity_filter[MAX_CLIENTS] = {7, 15}; > + SaUint32T v_saLogStreamSeverityFilter = 127; > + SaLogStreamHandleT logStreamHandle[MAX_CLIENTS]; > + SaLogHandleT logHandle[MAX_CLIENTS]; > + SaSelectionObjectT selectionObject[MAX_CLIENTS]; > + > + logCallbacks.saLogFilterSetCallback = logFilterSetCallbackT; > + for (int i = 0; i < MAX_CLIENTS; i++) { > + rc = saLogInitialize(&logHandle[i], &logCallbacks, > &logVersion); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + return; > + } > + > + rc = saLogSelectionObjectGet(logHandle[i], > &selectionObject[i]); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + fds[i].fd = (int) selectionObject[i]; > + fds[i].events = POLLIN; > + > + rc = saLogStreamOpen_2(logHandle[i], > &systemStreamName, NULL, 0, > + SA_TIME_ONE_SECOND, > &logStreamHandle[i]); > + if (rc != SA_AIS_OK) { > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + } > + > + /* Close stream handle 1 */ > + saLogStreamClose(logStreamHandle[1]); > + > + cb_index = 0; > + /* Backup saLogStreamSeverityFilter value */ > + get_attr_value(&systemStreamName, "saLogStreamSeverityFilter", > + &v_saLogStreamSeverityFilter); > + /* Changing severity filter for system and app1 stream */ > + sprintf(command, "immcfg %s -a saLogStreamSeverityFilter=%d 2> > /dev/null", > + SA_LOG_STREAM_SYSTEM, serverity_filter[0]); > + ret = systemCall(command); > + if (ret != 0) { > + test_validate(ret, 0); > + goto done; > + } > + > + ret = poll(fds, 2, 1000); > + if (ret <= 0) { > + fprintf(stderr, " poll log callback failed: %d \n", ret); > + test_validate(ret, 1); > + goto done; > + } > + > + if (fds[1].revents & POLLIN) { > + fprintf(stderr, " ERROR, get callback while handle closed > stream\n"); > + test_validate(0, SA_AIS_OK); > + } > + > + if (fds[0].revents & POLLIN) { > + rc = saLogDispatch(logHandle[0], SA_DISPATCH_ALL); > + if (rc != SA_AIS_OK) { > + fprintf(stderr, " saLogDispatch failed: %d \n", > (int)rc); > + test_validate(rc, SA_AIS_OK); > + goto done; > + } > + > + if (cb_index != 1) { > + fprintf(stderr, "cb_index = %u\n", cb_index); > + test_validate(SA_AIS_ERR_LIBRARY, SA_AIS_OK); > + goto done; > + } > + > + if (log_streamHandle[0] == logStreamHandle[0] && > log_severity[0] == serverity_filter[0]) { > + test_validate(SA_AIS_OK, SA_AIS_OK); > + } else { > + test_validate(0, SA_AIS_OK); > + } > + } else { > + fprintf(stderr, " ERROR, Can not receive any callback\n"); > + test_validate(0, SA_AIS_OK); > + } > + > +done: > + logCallbacks.saLogFilterSetCallback = NULL; > + logFinalize(); > + /* Restore saLogStreamSeverityFilter attribute */ > + sprintf(command, "immcfg %s -a saLogStreamSeverityFilter=%d 2> > /dev/null", > + SA_LOG_STREAM_SYSTEM, v_saLogStreamSeverityFilter); > + systemCall(command); > +} > + > + > +__attribute__ ((constructor)) static void > saLibraryLifeCycle_constructor(void) > +{ > + test_suite_add(17, "Log Severity filter Callback"); > + test_case_add(17, saLogFilterSetCallbackT_01, "saLogFilterSetCallbackT, > severity filter is changed for cfg stream"); > + test_case_add(17, saLogFilterSetCallbackT_02, "saLogFilterSetCallbackT, > severity filter is changed for runtime stream"); > + test_case_add(17, saLogFilterSetCallbackT_03, "saLogFilterSetCallbackT, > severity filter is changed for runtime & cfg streams"); > + test_case_add(17, saLogFilterSetCallbackT_04, "saLogFilterSetCallbackT, > after closing stream"); > +} > diff --git a/src/log/apitest/tet_saLogStreamOpen_2.c > b/src/log/apitest/tet_saLogStreamOpen_2.c > --- a/src/log/apitest/tet_saLogStreamOpen_2.c > +++ b/src/log/apitest/tet_saLogStreamOpen_2.c > @@ -1052,7 +1052,6 @@ extern void saLogWriteLogAsync_19(void); > extern void saLogWriteLogCallbackT_01(void); > extern void saLogWriteLogCallbackT_02(void); > extern void saLogWriteLogCallbackT_03(void); > -extern void saLogFilterSetCallbackT_01(void); > extern void saLogStreamClose_01(void); > > __attribute__ ((constructor)) static void > saLibraryLifeCycle_constructor(void) > @@ -1105,7 +1104,6 @@ extern void saLogStreamClose_01(void); > test_case_add(2, saLogWriteLogAsync_19, "saLogWriteLogAsync() > logBufSize > SA_LOG_MAX_RECORD_SIZE"); > test_case_add(2, saLogWriteLogCallbackT_01, "saLogWriteLogCallbackT() > SA_DISPATCH_ONE"); > test_case_add(2, saLogWriteLogCallbackT_02, "saLogWriteLogCallbackT() > SA_DISPATCH_ALL"); > - test_case_add(2, saLogFilterSetCallbackT_01, "saLogFilterSetCallbackT > OK"); > test_case_add(2, saLogStreamClose_01, "saLogStreamClose OK"); > test_case_add(2, saLogStreamOpen_2_46, "saLogStreamOpen_2 with > maxFilesRotated = 0, ERR"); > test_case_add(2, saLogStreamOpen_2_47, "saLogStreamOpen_2 with > maxFilesRotated = 128, ERR"); > diff --git a/src/log/common/lgsv_defs.h b/src/log/common/lgsv_defs.h > --- a/src/log/common/lgsv_defs.h > +++ b/src/log/common/lgsv_defs.h > @@ -20,7 +20,7 @@ > > #define LOG_RELEASE_CODE 'A' > #define LOG_MAJOR_VERSION 2 > -#define LOG_MINOR_VERSION 2 > +#define LOG_MINOR_VERSION 3 > > #define LOG_RELEASE_CODE_0 'A' > #define LOG_MAJOR_VERSION_0 2 > diff --git a/src/log/common/lgsv_msg.h b/src/log/common/lgsv_msg.h > --- a/src/log/common/lgsv_msg.h > +++ b/src/log/common/lgsv_msg.h > @@ -46,6 +46,7 @@ typedef enum { > typedef enum { > LGSV_WRITE_LOG_CALLBACK_IND = 0, > LGSV_CLM_NODE_STATUS_CALLBACK = 1, > + LGSV_SEVERITY_FILTER_CALLBACK = 2, > LGSV_LGS_CBK_MAX > } lgsv_cbk_msg_type_t; > > @@ -127,12 +128,18 @@ typedef struct logsv_loga_clm_status_par > uint32_t clm_node_status; > } logsv_lga_clm_status_cbk_t; > > +typedef struct { > +SaLogSeverityFlagsT log_severity; > +} lgsv_severity_filter_callback_t; > + > /* wrapper structure for all the callbacks */ > typedef struct { > lgsv_cbk_msg_type_t type; /* callback type */ > uint32_t lgs_client_id; /* lgs client_id */ > + uint32_t lgs_stream_id; > SaInvocationT inv; /* invocation value */ > /* union {*/ > + lgsv_severity_filter_callback_t serverity_filter_cbk; > lgsv_write_log_callback_ind_t write_cbk; > logsv_lga_clm_status_cbk_t clm_node_status_cbk; > /* } param; */ > diff --git a/src/log/logd/lgs_imm.cc b/src/log/logd/lgs_imm.cc > --- a/src/log/logd/lgs_imm.cc > +++ b/src/log/logd/lgs_imm.cc > @@ -472,6 +472,8 @@ static void adminOperationCallback(SaImm > osaf_abort(0); > } > > + /* Send changed severity filter to clients */ > + lgs_send_severity_filter_to_clients(stream->streamId, severityFilter); > > /* Checkpoint to standby LOG server */ > ckpt_stream_config(stream); > @@ -2307,6 +2309,11 @@ static void stream_ccb_apply_modify(cons > } else if (!strcmp(attribute->attrName, "saLogStreamSeverityFilter")) { > SaUint32T severityFilter = *((SaUint32T *)value); > stream->severityFilter = severityFilter; > + > + /* Send changed severity filter to clients */ > + if (stream->streamType != STREAM_TYPE_ALARM && > + stream->streamType != STREAM_TYPE_NOTIFICATION) > + lgs_send_severity_filter_to_clients(stream->streamId, > severityFilter); > } else { > LOG_ER("Error: Unknown attribute name"); > osafassert(0); > diff --git a/src/log/logd/lgs_mds.cc b/src/log/logd/lgs_mds.cc > --- a/src/log/logd/lgs_mds.cc > +++ b/src/log/logd/lgs_mds.cc > @@ -807,6 +807,7 @@ static uint32_t mds_enc(struct ncsmds_ca > rc = enc_lstr_close_rsp_msg(uba, msg); > break; > default: > + rc = NCSCC_RC_FAILURE; > TRACE("Unknown API RSP type = %d", msg->info.api_resp_info.type); > break; > } > @@ -824,26 +825,44 @@ static uint32_t mds_enc(struct ncsmds_ca > ncs_encode_32bit(&p8, msg->info.cbk_info.lgs_client_id); > ncs_encode_64bit(&p8, msg->info.cbk_info.inv); > ncs_enc_claim_space(uba, 16); > - if (msg->info.cbk_info.type == LGSV_WRITE_LOG_CALLBACK_IND) { > - p8 = ncs_enc_reserve_space(uba, 4); > - if (!p8) { > - TRACE("ncs_enc_reserve_space failed"); > - goto err; > - } > - ncs_encode_32bit(&p8, msg->info.cbk_info.write_cbk.error); > - TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND"); > - } else if (msg->info.cbk_info.type == > LGSV_CLM_NODE_STATUS_CALLBACK) { > - p8 = ncs_enc_reserve_space(uba, 4); > - if (!p8) { > - TRACE("ncs_enc_reserve_space failed"); > - goto err; > - } > - ncs_encode_32bit(&p8, msg- > >info.cbk_info.clm_node_status_cbk.clm_node_status); > - TRACE_8("LGSV_CLM_NODE_STATUS_CALLBACK"); > - } else { > - TRACE("unknown callback type %d", msg->info.cbk_info.type); > + > + switch (msg->info.cbk_info.type) { > + case LGSV_WRITE_LOG_CALLBACK_IND: > + p8 = ncs_enc_reserve_space(uba, 4); > + if (!p8) { > + TRACE("ncs_enc_reserve_space failed"); > + goto err; > + } > + ncs_encode_32bit(&p8, msg->info.cbk_info.write_cbk.error); > + TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND"); > + break; > + case LGSV_CLM_NODE_STATUS_CALLBACK: > + p8 = ncs_enc_reserve_space(uba, 4); > + if (!p8) { > + TRACE("ncs_enc_reserve_space failed"); > + goto err; > + } > + ncs_encode_32bit(&p8, msg- > >info.cbk_info.clm_node_status_cbk.clm_node_status); > + TRACE_8("LGSV_CLM_NODE_STATUS_CALLBACK"); > + break; > + case LGSV_SEVERITY_FILTER_CALLBACK: > + p8 = ncs_enc_reserve_space(uba, 6); > + if (!p8) { > + TRACE("ncs_enc_reserve_space failed"); > + goto err; > + } > + ncs_encode_32bit(&p8, msg->info.cbk_info.lgs_stream_id); > + ncs_encode_16bit(&p8, msg- > >info.cbk_info.serverity_filter_cbk.log_severity); > + TRACE_8("LGSV_SEVERITY_FILTER_CALLBACK"); > + break; > + default: > + rc = NCSCC_RC_FAILURE; > + TRACE("unknown callback type %d", msg->info.cbk_info.type); > + break; > + } > + if (rc == NCSCC_RC_FAILURE) > goto err; > - } > + > } else { > TRACE("unknown msg type %d", msg->type); > goto err; > diff --git a/src/log/logd/lgs_util.cc b/src/log/logd/lgs_util.cc > --- a/src/log/logd/lgs_util.cc > +++ b/src/log/logd/lgs_util.cc > @@ -834,3 +834,83 @@ bool lgs_is_extended_name_valid(const Sa > > return true; > } > + > + > +/** > + * Send a severity callback callback message to a client > + * > + * @param client_id > + * @param stream_id > + * @param severityFilter > + * @param mds_dest > + */ > +static void lgs_send_filter_msg(uint32_t client_id, uint32_t stream_id, > + SaLogSeverityFlagsT severity_filter, MDS_DEST > mds_dest) { > + uint32_t rc; > + NCSMDS_INFO mds_info = {0}; > + lgsv_msg_t msg; > + > + TRACE_ENTER(); > + TRACE_3("client_id: %u, stream_id: %u, modified severity filter: %u", > + client_id, stream_id, severity_filter); > + > + msg.type = LGSV_LGS_CBK_MSG; > + msg.info.cbk_info.type = LGSV_SEVERITY_FILTER_CALLBACK; > + msg.info.cbk_info.lgs_client_id = client_id; > + msg.info.cbk_info.lgs_stream_id = stream_id; > + msg.info.cbk_info.inv = 0; > + msg.info.cbk_info.serverity_filter_cbk.log_severity = severity_filter; > + > + mds_info.i_mds_hdl = lgs_cb->mds_hdl; > + mds_info.i_svc_id = NCSMDS_SVC_ID_LGS; > + mds_info.i_op = MDS_SEND; > + mds_info.info.svc_send.i_msg = &msg; > + mds_info.info.svc_send.i_to_svc = NCSMDS_SVC_ID_LGA; > + mds_info.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH; > + mds_info.info.svc_send.i_sendtype = MDS_SENDTYPE_SND; > + mds_info.info.svc_send.info.snd.i_to_dest = mds_dest; > + > + rc = ncsmds_api(&mds_info); > + if (rc != NCSCC_RC_SUCCESS) > + LOG_NO("Failed (%u) to send of severity filter callback to: %" PRIx64, > rc, > mds_dest); > + > + TRACE_LEAVE(); > +} > + > +/** > + * Send a changed severity filter to a client > + * > + * @param stream_id > + * @param severityFilter > + */ > +void lgs_send_severity_filter_to_clients(uint32_t stream_id, > + SaLogSeverityFlagsT severity_filter) { > + log_client_t *rp = NULL; > + uint32_t client_id_net; > + lgs_stream_list_t *stream; > + > + TRACE_ENTER(); > + TRACE_3("stream_id: %u, severity filter:%u", stream_id, severity_filter); > + > + rp = reinterpret_cast<log_client_t *> > + (ncs_patricia_tree_getnext(&lgs_cb->client_tree, NULL)); > + > + while (rp != NULL) { > + /* Store the client_id_net for getting next */ > + client_id_net = rp->client_id_net; > + /* Do not send to all client. Send to clients that need filter > + callback and associate with this stream */ > + stream = rp->stream_list_root; > + while (stream != NULL) { > + if (stream->stream_id == stream_id) { > + lgs_send_filter_msg(rp->client_id, stream_id, severity_filter, rp- > >mds_dest); > + break; > + } > + stream = stream->next; > + } > + rp = reinterpret_cast<log_client_t *>(ncs_patricia_tree_getnext( > + &lgs_cb->client_tree, reinterpret_cast<uint8_t > *>(&client_id_net))); > + } > + > + TRACE_LEAVE(); > +} > diff --git a/src/log/logd/lgs_util.h b/src/log/logd/lgs_util.h > --- a/src/log/logd/lgs_util.h > +++ b/src/log/logd/lgs_util.h > @@ -82,5 +82,7 @@ int lgs_init_timer(time_t timeout_s); > void lgs_close_timer(int ufd); > > bool lgs_is_extended_name_valid(const SaNameT* name); > +void lgs_send_severity_filter_to_clients(uint32_t stream_id, > + SaLogSeverityFlagsT serverity); > > #endif // LOG_LOGD_LGS_UTIL_H_ > diff --git a/src/log/tools/saf_logger.c b/src/log/tools/saf_logger.c > --- a/src/log/tools/saf_logger.c > +++ b/src/log/tools/saf_logger.c > @@ -58,7 +58,7 @@ > static void logWriteLogCallbackT(SaInvocationT invocation, SaAisErrorT > error); > > static SaLogCallbacksT logCallbacks = { 0, 0, logWriteLogCallbackT }; > -static SaVersionT logVersion = { 'A', 2, 1 }; > +static SaVersionT logVersion = { 'A', 2, 3 }; > > static char *progname = "saflogger"; > static SaInvocationT cb_invocation; > diff --git a/src/osaf/saflog/saflog.c b/src/osaf/saflog/saflog.c > --- a/src/osaf/saflog/saflog.c > +++ b/src/osaf/saflog/saflog.c > @@ -31,7 +31,7 @@ void saflog_init(void) > SaAisErrorT error; > > if (!initialized) { > - SaVersionT logVersion = { 'A', 2, 1 }; > + SaVersionT logVersion = { 'A', 2, 3 }; > SaNameT stream_name; > saAisNameLend(SA_LOG_STREAM_SYSTEM, > &stream_name); > > @@ -65,7 +65,7 @@ void saflog(int priority, const SaNameT > va_end(ap); > > if (!initialized) { > - SaVersionT logVersion = { 'A', 2, 1 }; > + SaVersionT logVersion = { 'A', 2, 3 }; > SaNameT stream_name; > saAisNameLend(SA_LOG_STREAM_SYSTEM, > &stream_name); > ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel