osaf/services/saf/logsv/README | 58 +++++-
osaf/services/saf/logsv/config/logsv_classes.xml | 59 ++++++
osaf/services/saf/logsv/lgs/lgs_config.c | 198 ++++++++++++++++++++--
osaf/services/saf/logsv/lgs/lgs_config.h | 19 ++
osaf/services/saf/logsv/lgs/lgs_evt.c | 4 -
osaf/services/saf/logsv/lgs/lgs_filehdl.c | 2 +-
osaf/services/saf/logsv/lgs/lgs_imm.c | 109 +++++++-----
osaf/services/saf/logsv/lgs/lgs_main.c | 5 +
osaf/services/saf/logsv/lgs/lgs_mbcsv.c | 3 +-
osaf/services/saf/logsv/lgs/lgs_mbcsv_v5.c | 17 +-
tests/logsv/Makefile.am | 3 +-
tests/logsv/logtest.h | 3 +
tests/logsv/tet_log_runtime_cfgobj.c | 105 ++++++++++++
13 files changed, 484 insertions(+), 101 deletions(-)
Create a runtime object to make it possible to see the actual
configuration. Configuration may come from three sources;
configuration object, environment variables or hard coded default
values;
This handling is dependent on that a runtime class is predefined.
No runtime object will be created if no runtime class is defined
diff --git a/osaf/services/saf/logsv/README b/osaf/services/saf/logsv/README
--- a/osaf/services/saf/logsv/README
+++ b/osaf/services/saf/logsv/README
@@ -32,7 +32,7 @@ such a file system and must be configure
Important!
----------
-Contibutors/Maintainers see section
+Contributors/Maintainers see section
IMPORTANT INFORMATION FOR CONTRIBUTORS/MAINTAINERS.
@@ -97,7 +97,7 @@ OVERLOAD PROTECTION
LOG uses a single mailbox used to communicate from the MDS thread to the
main thread. An IPC mailbox has four priority levels. By default a level
is unbounded in size, as many messages as the main memory allows can be
-queued. The mailbox provides a mechanism to put a a limit on how many
+queued. The mailbox provides a mechanism to put a limit on how many
messages that can be stored at the same time in it. LOG overload uses
that feature.
@@ -145,8 +145,9 @@ default streams are included in the Open
Service configuration
---------------------
There is also a configuration object class OpenSafLogConfig used to configure
-the LOG Service itself. These classes are not described in the LOG AIS
-specification.
+the LOG Service itself and a runtime object class OpenSafLogConfigRuntime
making
+it possible to read the configuration.
+These classes are not described in the LOG AIS specification.
There are three sources where the log server may get configuration data; an
OpenSafLogConfig IMM object, environment variables or hard coded default
values.
@@ -163,6 +164,8 @@ will be supported.
1. IMM configuration object
---------------------------
+The name of the class is:
+"OpenSafLogConfig"
The name of the configuration object is:
"logConfig=1,safApp=safLogService"
@@ -220,7 +223,7 @@ The following attributes can be changed
all current log files will be changed to this group for consistent purpose.
Users who are member of this group then can read the log files.
After the deletion of the value of this attribute, the ownership of all
current
- log files won't be changed and behaviour will be kept as previous, i.e: new
opened
+ log files won't be changed and behavior will be kept as previous, i.e: new
opened
log file will be owned by the primary group as which LOG service is
running.
Other attributes cannot be changed in runtime.
@@ -260,7 +263,7 @@ LOGSV_ROOT_DIRECTORY:
This variable is needed to configure the "implementation defined root
directory" as mentioned in the spec. All log files will be stored directly
-in this directory or in a subdirectory. If HA characterisitcs are needed for
+in this directory or in a subdirectory. If HA characteristics are needed for
LOG streams, configure this directory to point to replicated (shared &
persistent) partition.
@@ -304,6 +307,39 @@ Any user wants to read log data must bec
Don't forget the "export" keyword before the variable!
+IMM configuration runtime object
+--------------------------------
+The name of the class is:
+"OpenSafLogConfigRuntime"
+The name of the configuration object is:
+"logConfig=2,safApp=safLogService"
+
+Since the log service can use three sources for setting the configuration
+parameters there is a possibility that there is a mismatch between the
+configuration object and the actual configuration. All attributes in this
object
+is pure runtime attributes and shows the actual content of each configuration
+parameter.
+Normally the log service shall be configured using an IMM class matching the
+sw version (all attributes exist) and all attributes have a valid value. If
this
+is the case the configuration object and the actual configuration will match.
+
+Some examples of when there will be a mismatch:
+A.
+The configuration classes are updated but new parameters has not been given a
+value (attributes exist but has empty values)
+
+B.
+The configuration object exist and has all attributes but one or more attribute
+has an invalid value. This could be the case if a configuration object is
+predefined with incorrect values. In this case the log service will use default
+values instead of the invalid values.
+
+NOTE: When upgrading to a sw version that has new configuration parameters both
+ configuration object classes has to be upgraded to contain the new
+ attributes. If the new parameters are not added to the runtime class it
+ will not be possible to see the complete configuration. The OpenSAF
+ logsv_classes.xml file shall always be updated.
+
COMMAND LINE INTERFACE
======================
@@ -373,7 +409,7 @@ File IO
File operations are no longer allowed in the log-server main thread. This is in
order to prevent "hanging" of the log-server if a file operation does not
return
-e.g. when a NFS filesystem is not working correctly. It is therfore very
+e.g. when a NFS filesystem is not working correctly. It is therefore very
important that no future code do any file-system operations in the main thread.
All file system operations are handled in a separate thread.
@@ -421,7 +457,7 @@ The function is tread safe (see also lgs
lgs_cfgupd_list_create()
Used to create a list for configuration information. Contains attribute names
and their values. The list may contain one or more attributes. The list is used
-for updating configuration data check-ponting etc. Typically a list is created
+for updating configuration data check-pointing etc. Typically a list is created
when OI is reading a ccb in the apply callback.
lgs_cfgupd_list_read()
@@ -438,7 +474,7 @@ Shall never be used in new code! Instead
lgs_cfg_update() shall be used.
-Checkpointing:
+Check-pointing:
Previously configuration data was check-pointed using a check-point structure
in the same way as check-pointing is done for other changes. This is changed.
Configuration changes are now check-pointed using a variable length buffer
@@ -508,8 +544,8 @@ If something goes wrong the general beha
saAmfComponentErrorReport(...,SA_AMF_COMPONENT_RESTART,...) in order to avoid
being out of sync (will trig a mbcs cold sync).
-Checkpointed
-------------
+Check-pointed
+-------------
initialize client:
Adds a new client.
diff --git a/osaf/services/saf/logsv/config/logsv_classes.xml
b/osaf/services/saf/logsv/config/logsv_classes.xml
--- a/osaf/services/saf/logsv/config/logsv_classes.xml
+++ b/osaf/services/saf/logsv/config/logsv_classes.xml
@@ -245,4 +245,63 @@ to ensure that default global values in
<flag>SA_WRITABLE</flag>
</attr>
</class>
+ <class name="OpenSafLogConfigRuntime">
+ <category>SA_RUNTIME</category>
+ <rdn>
+ <name>logConfig</name>
+ <type>SA_STRING_T</type>
+ <category>SA_RUNTIME</category>
+ <flag>SA_CACHED</flag>
+ </rdn>
+ <attr>
+ <name>logRootDirectory</name>
+ <type>SA_STRING_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logMaxLogrecsize</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logStreamSystemHighLimit</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logStreamSystemLowLimit</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logStreamAppHighLimit</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logStreamAppLowLimit</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logMaxApplicationStreams</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logFileIoTimeout</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logFileSysConfig</name>
+ <type>SA_UINT32_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ <attr>
+ <name>logDataGroupname</name>
+ <type>SA_STRING_T</type>
+ <category>SA_RUNTIME</category>
+ </attr>
+ </class>
</imm:IMM-contents>
diff --git a/osaf/services/saf/logsv/lgs/lgs_config.c
b/osaf/services/saf/logsv/lgs/lgs_config.c
--- a/osaf/services/saf/logsv/lgs/lgs_config.c
+++ b/osaf/services/saf/logsv/lgs/lgs_config.c
@@ -205,7 +205,7 @@ static void init_default(void)
* configuration.
*
* NOTE1: Parameter name and value is not validated
- * NOTE2: This function allocates memory pointed to chkpt_buffer_ptr in the
+ * NOTE2: This function allocates memory pointed to by config_data in the
* lgs_config_chg_t structure. This memory has to bee freed after usage
*
* @param name_str[in] String containing the parameter name
@@ -380,36 +380,36 @@ int lgs_cfg_update(const lgs_config_chg_
}
/* Update config data */
- if (strcmp(name_str, "logRootDirectory") == 0) {
+ if (strcmp(name_str, DlogRootDirectory) == 0) {
(void) snprintf(lgs_conf.logRootDirectory, PATH_MAX,
"%s", value_str);
lgs_conf.logRootDirectory_cnfflag = LGS_CNF_OBJ;
- } else if (strcmp(name_str, "logDataGroupname") == 0) {
+ } else if (strcmp(name_str, DlogDataGroupname) == 0) {
(void) snprintf(lgs_conf.logDataGroupname, UT_NAMESIZE,
"%s", value_str);
lgs_conf.logDataGroupname_cnfflag = LGS_CNF_OBJ;
- } else if (strcmp(name_str, "logMaxLogrecsize") == 0) {
+ } else if (strcmp(name_str, DlogMaxLogrecsize) == 0) {
lgs_conf.logMaxLogrecsize = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logStreamSystemHighLimit") == 0) {
+ } else if (strcmp(name_str, DlogStreamSystemHighLimit) == 0) {
lgs_conf.logStreamSystemHighLimit = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logStreamSystemLowLimit") == 0) {
+ } else if (strcmp(name_str, DlogStreamSystemLowLimit) == 0) {
lgs_conf.logStreamSystemLowLimit = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logStreamAppHighLimit") == 0) {
+ } else if (strcmp(name_str, DlogStreamAppHighLimit) == 0) {
lgs_conf.logStreamAppHighLimit = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logStreamAppLowLimit") == 0) {
+ } else if (strcmp(name_str, DlogStreamAppLowLimit) == 0) {
lgs_conf.logStreamAppLowLimit = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logMaxApplicationStreams") == 0) {
+ } else if (strcmp(name_str, DlogMaxApplicationStreams) == 0) {
lgs_conf.logMaxApplicationStreams = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logFileIoTimeout") == 0) {
+ } else if (strcmp(name_str, DlogFileIoTimeout) == 0) {
lgs_conf.logFileIoTimeout = (SaUint32T)
strtoul(value_str, NULL, 0);
- } else if (strcmp(name_str, "logFileSysConfig") == 0) {
+ } else if (strcmp(name_str, DlogFileSysConfig) == 0) {
lgs_conf.logFileSysConfig = (SaUint32T)
strtoul(value_str, NULL, 0);
}
@@ -767,7 +767,7 @@ static void read_logsv_config_obj_2(void
value = attribute->attrValues[0];
- if (!strcmp(attribute->attrName, "logRootDirectory")) {
+ if (!strcmp(attribute->attrName, DlogRootDirectory)) {
n = snprintf(lgs_conf.logRootDirectory, PATH_MAX, "%s",
*((char **) value));
if (n >= PATH_MAX) {
@@ -778,7 +778,7 @@ static void read_logsv_config_obj_2(void
TRACE("Conf obj; logRootDirectory: %s",
lgs_conf.logRootDirectory);
}
- } else if (!strcmp(attribute->attrName, "logDataGroupname")) {
+ } else if (!strcmp(attribute->attrName, DlogDataGroupname)) {
n = snprintf(lgs_conf.logDataGroupname, UT_NAMESIZE,
"%s",
*((char **) value));
if (n >= UT_NAMESIZE) {
@@ -789,40 +789,40 @@ static void read_logsv_config_obj_2(void
TRACE("Conf obj; logDataGroupname: %s",
lgs_conf.logDataGroupname);
}
- } else if (!strcmp(attribute->attrName, "logMaxLogrecsize")) {
+ } else if (!strcmp(attribute->attrName, DlogMaxLogrecsize)) {
lgs_conf.logMaxLogrecsize = *((SaUint32T *) value);
lgs_conf.logMaxLogrecsize_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logMaxLogrecsize: %u",
lgs_conf.logMaxLogrecsize);
- } else if (!strcmp(attribute->attrName,
"logStreamSystemHighLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamSystemHighLimit)) {
lgs_conf.logStreamSystemHighLimit = *((SaUint32T *)
value);
lgs_conf.logStreamSystemHighLimit_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logStreamSystemHighLimit: %u",
lgs_conf.logStreamSystemHighLimit);
- } else if (!strcmp(attribute->attrName,
"logStreamSystemLowLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamSystemLowLimit)) {
lgs_conf.logStreamSystemLowLimit = *((SaUint32T *)
value);
lgs_conf.logStreamSystemLowLimit_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logStreamSystemLowLimit: %u",
lgs_conf.logStreamSystemLowLimit);
- } else if (!strcmp(attribute->attrName,
"logStreamAppHighLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamAppHighLimit)) {
lgs_conf.logStreamAppHighLimit = *((SaUint32T *) value);
lgs_conf.logStreamAppHighLimit_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logStreamAppHighLimit: %u",
lgs_conf.logStreamAppHighLimit);
- } else if (!strcmp(attribute->attrName,
"logStreamAppLowLimit")) {
+ } else if (!strcmp(attribute->attrName, DlogStreamAppLowLimit))
{
lgs_conf.logStreamAppLowLimit = *((SaUint32T *) value);
lgs_conf.logStreamAppLowLimit_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logStreamAppLowLimit: %u",
lgs_conf.logStreamAppLowLimit);
- } else if (!strcmp(attribute->attrName,
"logMaxApplicationStreams")) {
+ } else if (!strcmp(attribute->attrName,
DlogMaxApplicationStreams)) {
lgs_conf.logMaxApplicationStreams = *((SaUint32T *)
value);
lgs_conf.logMaxApplicationStreams_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logMaxApplicationStreams: %u",
lgs_conf.logMaxApplicationStreams);
- } else if (!strcmp(attribute->attrName, "logFileIoTimeout")) {
+ } else if (!strcmp(attribute->attrName, DlogFileIoTimeout)) {
lgs_conf.logFileIoTimeout = *((SaUint32T *) value);
lgs_conf.logFileIoTimeout_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logFileIoTimeout: %u",
lgs_conf.logFileIoTimeout);
- } else if (!strcmp(attribute->attrName, "logFileSysConfig")) {
+ } else if (!strcmp(attribute->attrName, DlogFileSysConfig)) {
lgs_conf.logFileSysConfig = *((SaUint32T *) value);
lgs_conf.logFileSysConfig_cnfflag = LGS_CNF_OBJ;
TRACE("Conf obj; logFileSysConfig: %u",
lgs_conf.logFileSysConfig);
@@ -851,10 +851,6 @@ done:
* the rule is that the configuration object has precedence but there are
* some deviations. The rules are applied here.
*
- * LLDTESTXXX Shall config obj be updated if a parameter is configured from
- * other source than the config obj itself??
- * Remove makeshift solution where actual mailbox limits are written
- * to syslog?
*/
static void read_log_config_environ_var_2(void) {
char *val_str;
@@ -1341,6 +1337,158 @@ void lgs_groupnameconf_set(const char *d
}
/******************************************************************************
+ * Handle Log service configuration runtime object
+ * Used to display log service actual configuration
+
******************************************************************************/
+
+/**
+ * Create runtime object to show log service configuration
+ *
+ * @param immOiHandle[in]
+ */
+void conf_runtime_obj_create(SaImmOiHandleT immOiHandle)
+{
+ SaAisErrorT rc = SA_AIS_OK;
+
+ TRACE_ENTER();
+
+ /* Construct object with dn:
+ * logConfig=2,safApp=safLogService
+ */
+ char namestr[128];
+ strcpy(namestr, "logConfig=2");
+ char *nameptr = namestr;
+ void *valarr[] = { &nameptr };
+ const SaImmAttrValuesT_2 attr_logConfig = {
+ .attrName = "logConfig",
+ .attrValueType = SA_IMM_ATTR_SASTRINGT,
+ .attrValuesNumber = 1,
+ .attrValues = valarr
+ };
+
+ const SaImmAttrValuesT_2 *attrValues[] = {
+ &attr_logConfig,
+ NULL
+ };
+
+ SaNameT parent_name, *parent_name_p;
+ strcpy((char *) parent_name.value, "safApp=safLogService");
+ parent_name.length = strlen((char *) parent_name.value);
+ parent_name_p = &parent_name;
+
+ rc = saImmOiRtObjectCreate_2(immOiHandle,
+ "OpenSafLogConfigRuntime",
+ parent_name_p,
+ attrValues);
+
+ if (rc == SA_AIS_ERR_EXIST) {
+ TRACE("Server runtime configuration object already exist");
+ } else if (rc != SA_AIS_OK) {
+ LOG_NO("%s: Cannot create config runtime object %s",
+ __FUNCTION__, saf_error(rc));
+ }
+
+ TRACE_LEAVE();
+}
+
+/**
+ * Handler for updating runtime configuration object attributes
+ * Called from the SaImmOiRtAttrUpdateCallbackT type function
+ *
+ * @param immOiHandle[in]
+ * @param attributeNames[in]
+ */
+void conf_runtime_obj_hdl(SaImmOiHandleT immOiHandle, const SaImmAttrNameT
*attributeNames)
+{
+ SaImmAttrNameT attributeName;
+ int i = 0;
+ char *str_val = NULL;
+ SaUint32T u32_val = 0;
+
+ TRACE_ENTER();
+
+ while ((attributeName = attributeNames[i++]) != NULL) {
+ TRACE("Attribute %s", attributeName);
+ if (!strcmp(attributeName, DlogRootDirectory)) {
+ str_val = (char *)
+ lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY);
+ (void)immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SASTRINGT,
+ &str_val);
+ } else if (!strcmp(attributeName, DlogDataGroupname)) {
+ str_val = (char *)
+ lgs_cfg_get(LGS_IMM_DATA_GROUPNAME);
+ (void)immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SASTRINGT,
+ &str_val);
+ } else if (!strcmp(attributeName, DlogMaxLogrecsize)) {
+ u32_val = *(SaUint32T *)
+ lgs_cfg_get(LGS_IMM_LOG_MAX_LOGRECSIZE);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogStreamSystemHighLimit)) {
+ u32_val = *(SaUint32T *)
+
lgs_cfg_get(LGS_IMM_LOG_STREAM_SYSTEM_HIGH_LIMIT);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogStreamSystemLowLimit)) {
+ u32_val = *(SaUint32T *)
+
lgs_cfg_get(LGS_IMM_LOG_STREAM_SYSTEM_LOW_LIMIT);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogStreamAppHighLimit)) {
+ u32_val = *(SaUint32T *)
+ lgs_cfg_get(LGS_IMM_LOG_STREAM_APP_HIGH_LIMIT);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogStreamAppLowLimit)) {
+ u32_val = *(SaUint32T *)
+ lgs_cfg_get(LGS_IMM_LOG_STREAM_APP_LOW_LIMIT);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogMaxApplicationStreams)) {
+ u32_val = *(SaUint32T *)
+
lgs_cfg_get(LGS_IMM_LOG_MAX_APPLICATION_STREAMS);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogFileIoTimeout)) {
+ u32_val = *(SaUint32T *)
+ lgs_cfg_get(LGS_IMM_FILEHDL_TIMEOUT);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else if (!strcmp(attributeName, DlogFileSysConfig)) {
+ u32_val = *(SaUint32T *)
+ lgs_cfg_get(LGS_IMM_LOG_FILESYS_CFG);
+ (void) immutil_update_one_rattr(immOiHandle,
+ LGS_CFG_RUNTIME_OBJECT,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &u32_val);
+ } else {
+ TRACE("%s: unknown attribute %s",
+ __FUNCTION__, attributeName);
+ }
+ }
+
+ TRACE_LEAVE();
+}
+
+/******************************************************************************
* Trace functions
*/
diff --git a/osaf/services/saf/logsv/lgs/lgs_config.h
b/osaf/services/saf/logsv/lgs/lgs_config.h
--- a/osaf/services/saf/logsv/lgs/lgs_config.h
+++ b/osaf/services/saf/logsv/lgs/lgs_config.h
@@ -27,6 +27,19 @@
extern "C" {
#endif
+#define LGS_CFG_RUNTIME_OBJECT "logConfig=2,safApp=safLogService"
+
+#define DlogRootDirectory "logRootDirectory"
+#define DlogDataGroupname "logDataGroupname"
+#define DlogMaxLogrecsize "logMaxLogrecsize"
+#define DlogStreamSystemHighLimit "logStreamSystemHighLimit"
+#define DlogStreamSystemLowLimit "logStreamSystemLowLimit"
+#define DlogStreamAppHighLimit "logStreamAppHighLimit"
+#define DlogStreamAppLowLimit "logStreamAppLowLimit"
+#define DlogMaxApplicationStreams "logMaxApplicationStreams"
+#define DlogFileIoTimeout "logFileIoTimeout"
+#define DlogFileSysConfig "logFileSysConfig"
+
typedef enum {
LGS_IMM_LOG_ROOT_DIRECTORY,
LGS_IMM_DATA_GROUPNAME,
@@ -83,6 +96,12 @@ int lgs_cfg_verify_mbox_limit(uint32_t h
int lgs_cfg_verify_max_application_streams(uint32_t max_app_streams);
/*
+ * Handle runtime object for showing actual configuration
+ */
+void conf_runtime_obj_create(SaImmOiHandleT immOiHandle);
+void conf_runtime_obj_hdl(SaImmOiHandleT immOiHandle, const SaImmAttrNameT
*attributeNames);
+
+/*
* Trace functions
*/
void lgs_trace_config(void);
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.c
b/osaf/services/saf/logsv/lgs/lgs_evt.c
--- a/osaf/services/saf/logsv/lgs/lgs_evt.c
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.c
@@ -30,10 +30,6 @@
#include "lgs_mbcsv_v1.h"
#include "lgs_mbcsv_v2.h"
-#if 0 /*LLDTEST1*/
-#include "lgs_mbcsv_v3.h"
-#include "lgs_mbcsv_v5.h"
-#endif
/* Macro to validate the version */
#define m_LOG_VER_IS_VALID(ver) \
diff --git a/osaf/services/saf/logsv/lgs/lgs_filehdl.c
b/osaf/services/saf/logsv/lgs/lgs_filehdl.c
--- a/osaf/services/saf/logsv/lgs/lgs_filehdl.c
+++ b/osaf/services/saf/logsv/lgs/lgs_filehdl.c
@@ -432,7 +432,7 @@ int make_log_dir_hdl(void *indata, void
mpath[path_len] = '\0';
rc = mkdir(mpath, S_IRWXU | S_IRWXG | S_IRWXO);
if ((rc != 0) && (errno != EEXIST)) {
- LOG_ER("Making directory error %s",strerror(errno));
+ LOG_ER("mkdir \"%s\" Fail %s", mpath, strerror(errno));
mldh_rc = -1;
goto done;
}
diff --git a/osaf/services/saf/logsv/lgs/lgs_imm.c
b/osaf/services/saf/logsv/lgs/lgs_imm.c
--- a/osaf/services/saf/logsv/lgs/lgs_imm.c
+++ b/osaf/services/saf/logsv/lgs/lgs_imm.c
@@ -47,6 +47,7 @@
#include "lgs_util.h"
#include "lgs_file.h"
#include "lgs_config.h"
+#include "saf_error.h"
#include "lgs_mbcsv_v1.h"
#include "lgs_mbcsv_v2.h"
@@ -684,8 +685,6 @@ static SaAisErrorT validate_mailbox_limi
* Modification of attributes in log service configuration object.
* Validate given attribute changes and report result to IMM
*
- * LLDTESTXXX Use validation functions in lgs_config.c
- *
* @param immOiHandle
* @param opdata
* @return
@@ -722,7 +721,7 @@ static SaAisErrorT config_ccb_completed_
TRACE("attribute %s", attribute->attrName);
/* Ignore deletion of attributes except for logDataGroupname*/
- if ((strcmp(attribute->attrName, "logDataGroupname") != 0) &&
+ if ((strcmp(attribute->attrName, DlogDataGroupname) != 0) &&
(attribute->attrValuesNumber == 0)) {
report_oi_error(immOiHandle, opdata->ccbId,
"deletion of value is not allowed for
attribute %s stream %s",
@@ -735,7 +734,7 @@ static SaAisErrorT config_ccb_completed_
value = attribute->attrValues[0];
}
- if (!strcmp(attribute->attrName, "logRootDirectory")) {
+ if (!strcmp(attribute->attrName, DlogRootDirectory)) {
if (attribute->attrValuesNumber != 0) {
char *pathName = *((char **)value);
rc = lgs_cfg_verify_root_dir(pathName);
@@ -747,7 +746,7 @@ static SaAisErrorT config_ccb_completed_
}
TRACE("pathName: %s is accepted", pathName);
}
- } else if (!strcmp(attribute->attrName, "logDataGroupname")) {
+ } else if (!strcmp(attribute->attrName, DlogDataGroupname)) {
if (attribute->attrValuesNumber == 0) {
TRACE("Deleting log data group");
} else {
@@ -761,42 +760,42 @@ static SaAisErrorT config_ccb_completed_
}
TRACE("groupname: %s is accepted", groupname);
}
- } else if (!strcmp(attribute->attrName, "logMaxLogrecsize")) {
+ } else if (!strcmp(attribute->attrName, DlogMaxLogrecsize)) {
report_oi_error(immOiHandle, opdata->ccbId,
"%s cannot be changed",
attribute->attrName);
ais_rc = SA_AIS_ERR_FAILED_OPERATION;
goto done;
- } else if (!strcmp(attribute->attrName,
"logStreamSystemHighLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamSystemHighLimit)) {
vattr_v3.logStreamSystemHighLimit = *((SaUint32T
*)value);
vattr_v3.logStreamSystemHighLimit_changed = true;
TRACE("%s %s = %d",__FUNCTION__, attribute->attrName,
vattr_v3.logStreamSystemHighLimit);
- } else if (!strcmp(attribute->attrName,
"logStreamSystemLowLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamSystemLowLimit)) {
vattr_v3.logStreamSystemLowLimit = *((SaUint32T
*)value);
vattr_v3.logStreamSystemLowLimit_changed = true;
TRACE("%s %s = %d",__FUNCTION__, attribute->attrName,
vattr_v3.logStreamSystemHighLimit);
- } else if (!strcmp(attribute->attrName,
"logStreamAppHighLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamAppHighLimit)) {
vattr_v3.logStreamAppHighLimit = *((SaUint32T *)value);
vattr_v3.logStreamAppHighLimit_changed = true;
TRACE("%s %s = %d",__FUNCTION__, attribute->attrName,
vattr_v3.logStreamSystemHighLimit);
- } else if (!strcmp(attribute->attrName,
"logStreamAppLowLimit")) {
+ } else if (!strcmp(attribute->attrName, DlogStreamAppLowLimit))
{
vattr_v3.logStreamAppLowLimit = *((SaUint32T *)value);
vattr_v3.logStreamAppLowLimit_changed = true;
TRACE("%s %s = %d",__FUNCTION__, attribute->attrName,
vattr_v3.logStreamSystemHighLimit);
- } else if (!strcmp(attribute->attrName,
"logMaxApplicationStreams")) {
+ } else if (!strcmp(attribute->attrName,
DlogMaxApplicationStreams)) {
report_oi_error(immOiHandle, opdata->ccbId,
"%s cannot be changed",
attribute->attrName);
ais_rc = SA_AIS_ERR_FAILED_OPERATION;
goto done;
- } else if (!strcmp(attribute->attrName, "logFileIoTimeout")) {
+ } else if (!strcmp(attribute->attrName, DlogFileIoTimeout)) {
report_oi_error(immOiHandle, opdata->ccbId,
"%s cannot be changed",
attribute->attrName);
ais_rc = SA_AIS_ERR_FAILED_OPERATION;
goto done;
- } else if (!strcmp(attribute->attrName, "logFileSysConfig")) {
+ } else if (!strcmp(attribute->attrName, DlogFileSysConfig)) {
report_oi_error(immOiHandle, opdata->ccbId,
"%s cannot be changed",
attribute->attrName);
ais_rc = SA_AIS_ERR_FAILED_OPERATION;
@@ -1907,46 +1906,46 @@ static void config_ccb_apply_modify(cons
* - Add to update buffer. Used for updating configuration data
* and check-pointing
*/
- if (!strcmp(attribute->attrName, "logRootDirectory")) {
+ if (!strcmp(attribute->attrName, DlogRootDirectory)) {
value_str = *((char **)value); /* New directory */
char *old_dir =
(char *)
lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY);
apply_conf_logRootDirectory(old_dir, value_str);
- lgs_cfgupd_list_create("logRootDirectory",
+ lgs_cfgupd_list_create(DlogRootDirectory,
value_str, &config_data);
root_dir_chg_flag = true;
- } else if (!strcmp(attribute->attrName, "logDataGroupname")) {
+ } else if (!strcmp(attribute->attrName, DlogDataGroupname)) {
if (value == NULL) {
value_str = "";
} else {
value_str = *((char **)value);
}
apply_conf_logDataGroupname(value_str);
- lgs_cfgupd_list_create("logDataGroupname",
+ lgs_cfgupd_list_create(DlogDataGroupname,
value_str, &config_data);
- } else if (!strcmp(attribute->attrName,
"logStreamSystemHighLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamSystemHighLimit)) {
uint32_val = *(uint32_t *) value;
snprintf(uint32_str, 20, "%u", uint32_val);
mailbox_lim_upd = true;
- lgs_cfgupd_list_create("logStreamSystemHighLimit",
+ lgs_cfgupd_list_create(DlogStreamSystemHighLimit,
uint32_str, &config_data);
- } else if (!strcmp(attribute->attrName,
"logStreamSystemLowLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamSystemLowLimit)) {
uint32_val = *(uint32_t *) value;
snprintf(uint32_str, 20, "%u", uint32_val);
mailbox_lim_upd = true;
- lgs_cfgupd_list_create("logStreamSystemLowLimit",
+ lgs_cfgupd_list_create(DlogStreamSystemLowLimit,
uint32_str, &config_data);
- } else if (!strcmp(attribute->attrName,
"logStreamAppHighLimit")) {
+ } else if (!strcmp(attribute->attrName,
DlogStreamAppHighLimit)) {
uint32_val = *(uint32_t *) value;
snprintf(uint32_str, 20, "%u", uint32_val);
mailbox_lim_upd = true;
- lgs_cfgupd_list_create("logStreamAppHighLimit",
+ lgs_cfgupd_list_create(DlogStreamAppHighLimit,
uint32_str, &config_data);
- } else if (!strcmp(attribute->attrName,
"logStreamAppLowLimit")) {
+ } else if (!strcmp(attribute->attrName, DlogStreamAppLowLimit))
{
uint32_val = *(uint32_t *) value;
snprintf(uint32_str, 20, "%u", uint32_val);
mailbox_lim_upd = true;
- lgs_cfgupd_list_create("logStreamAppLowLimit",
+ lgs_cfgupd_list_create(DlogStreamAppLowLimit,
uint32_str, &config_data);
}
@@ -1971,9 +1970,7 @@ static void config_ccb_apply_modify(cons
/* Check-point changes */
(void) ckpt_lgs_cfg(root_dir_chg_flag, &config_data);
-#if 1 /*LLDTEST1*/
lgs_trace_config();
-#endif
/* Cleanup and free cfg buffer */
if (config_data.ckpt_buffer_ptr != NULL)
@@ -2347,11 +2344,13 @@ static void ccbAbortCallback(SaImmOiHand
}
/**
- * IMM requests us to update a non cached runtime attribute. The only
- * available attributes are saLogStreamNumOpeners and
logStreamDiscardedCounter.
- * @param immOiHandle
- * @param objectName
- * @param attributeNames
+ * IMM requests us to update a non cached runtime attribute.
+ * Can be non cached attribute in stream runtime object or
+ * runtime configuration object
+ *
+ * @param immOiHandle[in]
+ * @param objectName[in]
+ * @param attributeNames[in]
*
* @return SaAisErrorT
*/
@@ -2361,7 +2360,6 @@ static SaAisErrorT rtAttrUpdateCallback(
SaAisErrorT rc = SA_AIS_ERR_FAILED_OPERATION;
SaImmAttrNameT attributeName;
int i = 0;
- log_stream_t *stream = log_stream_get_by_name((char
*)objectName->value);
TRACE_ENTER2("%s", objectName->value);
@@ -2370,23 +2368,39 @@ static SaAisErrorT rtAttrUpdateCallback(
goto done;
}
- if (stream == NULL) {
- LOG_ER("%s: stream %s not found", __FUNCTION__,
objectName->value);
- goto done;
- }
+ /* Handle configuration runtime object */
+ if (strncmp((char *) objectName->value, LGS_CFG_RUNTIME_OBJECT,
+ objectName->length) == 0) {
+ /* Handle Runtome configuration object */
+ conf_runtime_obj_hdl(immOiHandle, attributeNames);
+ } else {
- while ((attributeName = attributeNames[i++]) != NULL) {
- TRACE("Attribute %s", attributeName);
- if (!strcmp(attributeName, "saLogStreamNumOpeners")) {
- (void)immutil_update_one_rattr(immOiHandle, (char
*)objectName->value,
- attributeName,
SA_IMM_ATTR_SAUINT32T, &stream->numOpeners);
- } else if (!strcmp(attributeName, "logStreamDiscardedCounter"))
{
- (void) immutil_update_one_rattr(immOiHandle, (char *)
objectName->value,
- attributeName, SA_IMM_ATTR_SAUINT64T,
&stream->filtered);
- } else {
- LOG_ER("%s: unknown attribute %s", __FUNCTION__,
attributeName);
+ /* Handle stream object if valid
+ */
+ log_stream_t *stream = log_stream_get_by_name((char
*)objectName->value);
+ if (stream == NULL) {
+ LOG_ER("%s: stream %s not found", __FUNCTION__,
objectName->value);
goto done;
}
+
+ while ((attributeName = attributeNames[i++]) != NULL) {
+ TRACE("Attribute %s", attributeName);
+ if (!strcmp(attributeName, "saLogStreamNumOpeners")) {
+ (void)immutil_update_one_rattr(immOiHandle,
+ (char *)objectName->value,
+ attributeName, SA_IMM_ATTR_SAUINT32T,
+ &stream->numOpeners);
+ } else if (!strcmp(attributeName,
"logStreamDiscardedCounter")) {
+ (void) immutil_update_one_rattr(immOiHandle,
+ (char *) objectName->value,
+ attributeName, SA_IMM_ATTR_SAUINT64T,
+ &stream->filtered);
+ } else {
+ LOG_ER("%s: unknown attribute %s",
+ __FUNCTION__, attributeName);
+ goto done;
+ }
+ }
}
rc = SA_AIS_OK;
@@ -2772,4 +2786,3 @@ SaAisErrorT lgs_imm_init_OI(lgs_cb_t *cb
return rc;
}
-
diff --git a/osaf/services/saf/logsv/lgs/lgs_main.c
b/osaf/services/saf/logsv/lgs/lgs_main.c
--- a/osaf/services/saf/logsv/lgs/lgs_main.c
+++ b/osaf/services/saf/logsv/lgs/lgs_main.c
@@ -333,6 +333,11 @@ static uint32_t log_initialize(void)
rc = NCSCC_RC_FAILURE;
goto done;
}
+
+ /* Create the runtime object for showing the actual
+ * log server configuration
+ */
+ conf_runtime_obj_create(lgs_cb->immOiHandle);
}
/* If AMF started register immediately */
diff --git a/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
b/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
--- a/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
+++ b/osaf/services/saf/logsv/lgs/lgs_mbcsv.c
@@ -265,7 +265,6 @@ uint32_t lgs_mbcsv_change_HA_state(lgs_c
return NCSCC_RC_FAILURE;
}
-#if 1
/* If configured for split file system and becoming active some
* stb stream parameters has to be copied to corresponding active. The
* reason is that standby may have for example another current file in a
@@ -290,7 +289,7 @@ uint32_t lgs_mbcsv_change_HA_state(lgs_c
stream = log_stream_getnext_by_name(stream->name);
}
}
-#endif
+
TRACE_LEAVE();
return NCSCC_RC_SUCCESS;
diff --git a/osaf/services/saf/logsv/lgs/lgs_mbcsv_v5.c
b/osaf/services/saf/logsv/lgs/lgs_mbcsv_v5.c
--- a/osaf/services/saf/logsv/lgs/lgs_mbcsv_v5.c
+++ b/osaf/services/saf/logsv/lgs/lgs_mbcsv_v5.c
@@ -87,22 +87,22 @@ uint32_t ckpt_proc_lgs_cfg_v5(lgs_cb_t *
&cfg_buffer);
while (next_ptr != NULL) {
- if ((strcmp(name_str, "logRootDirectory") == 0) &&
+ if ((strcmp(name_str, DlogRootDirectory) == 0) &&
(lgs_is_split_file_system() == true)){
const char *new_root_path = value_str;
const char *old_root_path =
lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY);
logRootDirectory_filemove(new_root_path, old_root_path,
(time_t *) ¶m->c_file_close_time_stamp);
- } else if ((strcmp(name_str, "logDataGroupname") == 0) &&
+ } else if ((strcmp(name_str, DlogDataGroupname) == 0) &&
(lgs_is_split_file_system() == true)) {
logDataGroupname_fileown(value_str);
- } else if (!strcmp(name_str, "logStreamSystemHighLimit")) {
+ } else if (!strcmp(name_str, DlogStreamSystemHighLimit)) {
mailbox_lim_upd = true;
- } else if (!strcmp(name_str, "logStreamSystemLowLimit")) {
+ } else if (!strcmp(name_str, DlogStreamSystemLowLimit)) {
mailbox_lim_upd = true;
- } else if (!strcmp(name_str, "logStreamAppHighLimit")) {
+ } else if (!strcmp(name_str, DlogStreamAppHighLimit)) {
mailbox_lim_upd = true;
- } else if (!strcmp(name_str, "logStreamAppLowLimit")) {
+ } else if (!strcmp(name_str, DlogStreamAppLowLimit)) {
mailbox_lim_upd = true;
}
@@ -117,7 +117,7 @@ uint32_t ckpt_proc_lgs_cfg_v5(lgs_cb_t *
cfg_buffer.ckpt_buffer_ptr = saved_buf;
rc = lgs_cfg_update(&cfg_buffer);
if (rc == -1) {
- /* LLDTEST1XXX For now */
+ /* Shall not happen */
LOG_ER("%s lgs_cfg_update Fail", __FUNCTION__);
osafassert(0);
}
@@ -137,8 +137,7 @@ uint32_t ckpt_proc_lgs_cfg_v5(lgs_cb_t *
}
lgs_free_edu_mem(param->buffer);
- TRACE("LLDTEST1 %s: Configuration is check-pointed",__FUNCTION__);
- lgs_trace_config(); /*LLDTEST1*/
+ lgs_trace_config();
return NCSCC_RC_SUCCESS;
}
diff --git a/tests/logsv/Makefile.am b/tests/logsv/Makefile.am
--- a/tests/logsv/Makefile.am
+++ b/tests/logsv/Makefile.am
@@ -44,7 +44,8 @@ logtest_SOURCES = \
tet_saLogStreamClose.c \
tet_saLogLimitGet.c \
tet_LogOiOps.c \
- tet_Log_misc.c
+ tet_Log_misc.c \
+ tet_log_runtime_cfgobj.c
logtest_LDADD = \
$(top_builddir)/tests/unit_test_fw/src/libutest.la \
diff --git a/tests/logsv/logtest.h b/tests/logsv/logtest.h
--- a/tests/logsv/logtest.h
+++ b/tests/logsv/logtest.h
@@ -43,6 +43,9 @@
#define DEFAULT_APP_FILE_NAME "saLogApplication1"
#define DEFAULT_MAX_FILE_ROTATED 4
+#define LOGTST_IMM_LOG_CONFIGURATION "logConfig=1,safApp=safLogService"
+#define LOGTST_IMM_LOG_RUNTIME "logConfig=2,safApp=safLogService"
+
extern SaNameT systemStreamName;
extern SaNameT alarmStreamName;
extern SaNameT notificationStreamName;
diff --git a/tests/logsv/tet_log_runtime_cfgobj.c
b/tests/logsv/tet_log_runtime_cfgobj.c
new file mode 100644
--- /dev/null
+++ b/tests/logsv/tet_log_runtime_cfgobj.c
@@ -0,0 +1,105 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2015 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 "logtest.h"
+#include <limits.h>
+#include <unistd.h>
+#include <saf_error.h>
+#include "immutil.h"
+
+static SaVersionT immVersion = { 'A', 2, 11 };
+
+/**
+ * Log configuration config obj <=> runtime obj
+ *
+ * Verfy that the configuration and runtime object for log server configuration
+ * data contains the same number of attributes
+ */
+void log_rt_cf_obj_compare(void)
+{
+ SaImmHandleT omHandle;
+ SaNameT object_name;
+ SaImmAccessorHandleT accessorHandle;
+ SaImmAttrValuesT_2 **attributes;
+ uint32_t r_cnt = 0; /* Counter for attributes in runtime object */
+ uint32_t c_cnt = 0;
+ SaAisErrorT ais_rc = SA_AIS_OK;
+ int tst_res = 0; /* Test result: 0 = PASS */
+
+ /* NOTE: immutil will osaf_assert if error */
+ (void) immutil_saImmOmInitialize(&omHandle, NULL, &immVersion);
+ (void) immutil_saImmOmAccessorInitialize(omHandle, &accessorHandle);
+
+ /* Count attributes in configuration object
+ */
+ sprintf((char *) object_name.value, "%s",
+ LOGTST_IMM_LOG_CONFIGURATION);
+ object_name.length = strlen((char *) object_name.value);
+
+ ais_rc = immutil_saImmOmAccessorGet_2(accessorHandle, &object_name,
NULL,
+ &attributes);
+ if (ais_rc != SA_AIS_OK) {
+ tst_res = 1; /* FAIL */
+ fprintf(stderr, "Could not read config attributes %s\n",
+ saf_error(ais_rc));
+ goto done;
+ }
+
+ c_cnt = 0;
+ while (attributes[c_cnt++] != NULL); /* Count the attributes */
+
+ /* Count attributes in runtime object
+ */
+ sprintf((char *) object_name.value, "%s",
+ LOGTST_IMM_LOG_RUNTIME);
+ object_name.length = strlen((char *) object_name.value);
+
+ ais_rc = immutil_saImmOmAccessorGet_2(accessorHandle, &object_name,
NULL,
+ &attributes);
+ if (ais_rc != SA_AIS_OK) {
+ tst_res = 1; /* FAIL */
+ fprintf(stderr, "Could not read runtime attributes %s\n",
+ saf_error(ais_rc));
+ goto done;
+ }
+
+ r_cnt = 0;
+ while (attributes[r_cnt++] != NULL); /* Count the attributes */
+
+ /* Compare number of attributes. Test pass if the same number
+ */
+ if (c_cnt != r_cnt) {
+ tst_res = 1;
+ fprintf(stderr, "Found %d configuration attributes and"
+ " %d runtime attributes\n", c_cnt, r_cnt);
+ }
+
+ done:
+
+ (void) immutil_saImmOmAccessorFinalize(accessorHandle);
+ (void) immutil_saImmOmFinalize(omHandle);
+
+ rc_validate(tst_res, 0);
+}
+
+
+/* Load tests */
+__attribute__ ((constructor)) static void saOiOperations_constructor(void)
+{
+ test_suite_add(8, "Log configuration runtime object tests");
+ test_case_add(8, log_rt_cf_obj_compare, "Log configuration config obj
<=> runtime obj");
+}
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel