osaf/libs/common/immsv/immpbe_dump.cc | 2 +- osaf/services/saf/immsv/immloadd/imm_loader.cc | 140 ++++++++++++++++++++++++- osaf/services/saf/immsv/immnd/ImmModel.cc | 36 +++-- osaf/services/saf/immsv/immnd/ImmSearchOp.cc | 2 +- osaf/services/saf/immsv/immnd/ImmSearchOp.hh | 4 +- 5 files changed, 165 insertions(+), 19 deletions(-)
Add support for 64-bit attribute flags to IMM service. If immload finds unknown attribute flag, immload will try to find the attribute flag in the schema defined in the top element of the loading IMM XML file. diff --git a/osaf/libs/common/immsv/immpbe_dump.cc b/osaf/libs/common/immsv/immpbe_dump.cc --- a/osaf/libs/common/immsv/immpbe_dump.cc +++ b/osaf/libs/common/immsv/immpbe_dump.cc @@ -900,7 +900,7 @@ ClassInfo* classToPBE(std::string classN LOG_ER("Failed to bind attr_type with error code: %d", rc); goto bailout; } - if((rc = sqlite3_bind_int(stmt, 4, (*p)->attrFlags)) != SQLITE_OK) { + if((rc = sqlite3_bind_int64(stmt, 4, (*p)->attrFlags)) != SQLITE_OK) { LOG_ER("Failed to bind attr_flags with error code: %d", rc); goto bailout; } diff --git a/osaf/services/saf/immsv/immloadd/imm_loader.cc b/osaf/services/saf/immsv/immloadd/imm_loader.cc --- a/osaf/services/saf/immsv/immloadd/imm_loader.cc +++ b/osaf/services/saf/immsv/immloadd/imm_loader.cc @@ -17,7 +17,9 @@ #include "imm_loader.hh" #include <iostream> +#include <set> #include <libxml/parser.h> +#include <libxml/xpath.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -26,6 +28,7 @@ #include <configmake.h> #include <logtrace.h> #include <sys/stat.h> +#include <errno.h> #include <ncsgl_defs.h> #define MAX_DEPTH 10 @@ -114,6 +117,12 @@ typedef struct ParserStateStruct SaUint32T* preloadEpochPtr; } ParserState; +bool isXsdLoaded; +std::string xsddir; +std::string xsd; +typedef std::set<std::string> AttrFlagSet; +AttrFlagSet attrFlagSet; + /* Helper functions */ static void addToAttrTypeCache(ParserState*, SaImmValueTypeT); @@ -935,6 +944,13 @@ static void startElementHandler(void* us else if (strcmp((const char*)name, "imm:IMM-contents") == 0) { state->state[state->depth] = IMM_CONTENTS; + char *schema = (char *)getAttributeValue(attrs, (xmlChar *)"noNamespaceSchemaLocation"); + if(!schema) { + schema = (char *)getAttributeValue(attrs, (xmlChar *)"xsi:noNamespaceSchemaLocation"); + } + if(schema) { + xsd = schema; + } } else { @@ -1523,6 +1539,106 @@ static xmlEntityPtr return xmlGetPredefinedEntity(name); } +static inline char *getAttrValue(xmlAttributePtr attr) { + if(!attr || !attr->children) { + return NULL; + } + + return (char *)attr->children->content; +} + +static bool loadXsd(const char *xsdFile) { + struct stat st; + if(stat(xsdFile, &st)) { + if(errno == ENOENT) { + LOG_ER("%s does not exist", xsdFile); + } else { + LOG_ER("stat of %s return error: %d", xsdFile, errno); + } + + return false; + } + // It should be a file or a directory + if(!S_ISREG(st.st_mode)) { + LOG_ER("%s is not a file", xsdFile); + return false; + } + + xmlNodePtr xsdDocRoot; + xmlDocPtr xsdDoc = xmlParseFile(xsdFile); + if(!xsdDoc) { + return false; + } + + bool rc = true; + xmlXPathContextPtr ctx = xmlXPathNewContext(xsdDoc); + if(!ctx) { + rc = false; + goto freedoc; + } + + // Add namespace of the first element + xsdDocRoot = xmlDocGetRootElement(xsdDoc); + if(xsdDocRoot->ns) { + ctx->namespaces = (xmlNsPtr *)malloc(sizeof(xmlNsPtr)); + ctx->namespaces[0] = xsdDocRoot->ns; + ctx->nsNr = 1; + } + + xmlXPathObjectPtr xpathObj; + xpathObj = xmlXPathEval((const xmlChar*)"/xs:schema/xs:simpleType[@name=\"attr-flags\"]/xs:restriction/xs:enumeration", ctx); + if(!xpathObj || !xpathObj->nodesetval) { + rc = false; + goto freectx; + } + + xmlElementPtr element; + xmlAttributePtr attr; + char *value; + int size; + + size = xpathObj->nodesetval->nodeNr; + for(int i=0; i<size; i++) { + value = NULL; + element = (xmlElementPtr)xpathObj->nodesetval->nodeTab[i]; + attr = element->attributes; + while(attr) { + if(!strcmp((char *)attr->name, "value")) { + value = getAttrValue(attr); + } + + if(value) { + break; + } + + attr = (xmlAttributePtr)attr->next; + } + + if(value) { + if(strcmp(value, "SA_RUNTIME") && strcmp(value, "SA_CONFIG") && + strcmp(value, "SA_MULTI_VALUE") && strcmp(value, "SA_WRITABLE") && + strcmp(value, "SA_INITIALIZED") && strcmp(value, "SA_PERSISTENT") && + strcmp(value, "SA_CACHED") && strcmp(value, "SA_NOTIFY") && + strcmp(value, "SA_NO_DUPLICATES") && strcmp(value, "SA_NO_DANGLING")) { + attrFlagSet.insert(value); + } + } + } + + isXsdLoaded = true; + + xmlXPathFreeObject(xpathObj); +freectx: + if(ctx->nsNr) { + free(ctx->namespaces); + } + xmlXPathFreeContext(ctx); +freedoc: + xmlFreeDoc(xsdDoc); + + return rc; +} + /** * Takes a string and returns the corresponding flag */ @@ -1573,7 +1689,24 @@ static SaImmAttrFlagsT charsToFlagsHelpe return SA_IMM_ATTR_NO_DANGLING; } - LOG_ER("UNKNOWN FLAGS, %s", str); + std::string unflag((char *)str, len); + if(!isXsdLoaded) { + std::string xsdPath = xsddir; + if(xsdPath.size() > 0) + xsdPath.append("/"); + xsdPath.append(xsd); + LOG_WA("Found unknown flag (%s). Trying to load a schema %s", unflag.c_str(), xsdPath.c_str()); + loadXsd(xsdPath.c_str()); + } + + if(isXsdLoaded) { + AttrFlagSet::iterator it = attrFlagSet.find(unflag); + if(it != attrFlagSet.end()) { + return 0; + } + } + + LOG_ER("UNKNOWN FLAGS, %s", unflag.c_str()); exit(1); } @@ -1984,6 +2117,11 @@ int loadImmXML(std::string xmldir, std:: state.ccbHandle = 0LL; state.preloadEpochPtr=preloadEpochPtr; + isXsdLoaded = false; + xsddir = xmldir; + xsd = ""; + attrFlagSet.clear(); + /* Build the filename */ filename = xmldir; filename.append("/"); diff --git a/osaf/services/saf/immsv/immnd/ImmModel.cc b/osaf/services/saf/immsv/immnd/ImmModel.cc --- a/osaf/services/saf/immsv/immnd/ImmModel.cc +++ b/osaf/services/saf/immsv/immnd/ImmModel.cc @@ -70,7 +70,7 @@ struct AttrInfo { AttrInfo():mValueType(0), mFlags(0), mNtfId(0){} SaUint32T mValueType; - SaUint32T mFlags; + SaImmAttrFlagsT mFlags; SaUint32T mNtfId; ImmAttrValue mDefaultValue; }; @@ -445,13 +445,13 @@ static SaImmRepositoryInitModeT immInitM struct AttrFlagIncludes { - AttrFlagIncludes(SaUint32T attrFlag) : mFlag(attrFlag) { } + AttrFlagIncludes(SaImmAttrFlagsT attrFlag) : mFlag(attrFlag) { } bool operator() (AttrMap::value_type& item) const { return (item.second->mFlags & mFlag) != 0; } - SaUint32T mFlag; + SaImmAttrFlagsT mFlag; }; struct IdIs @@ -2635,6 +2635,7 @@ ImmModel::classCreate(const ImmsvOmClass int illegal=0; bool persistentRt = false; bool persistentRdn = false; + bool useUnknownFlag = false; ClassInfo* classInfo = NULL; ClassInfo* prevClassInfo = NULL; ClassInfo dummyClass(req->classCategory); @@ -2878,7 +2879,10 @@ ImmModel::classCreate(const ImmsvOmClass } } err = attrCreate(classInfo, attr, attrName); - if(err != SA_AIS_OK) { + if(err == SA_AIS_ERR_NOT_SUPPORTED) { + useUnknownFlag = true; + err = SA_AIS_OK; + } else if(err != SA_AIS_OK) { illegal = 1; } list = list->next; @@ -2931,6 +2935,10 @@ ImmModel::classCreate(const ImmsvOmClass goto done; } + if(useUnknownFlag) { + LOG_NO("At least one attribute in class %s has unsupported attribute flag", className.c_str()); + } + /* All checks passed, now install the class def. */ if(!schemaChange) { @@ -3787,18 +3795,18 @@ ImmModel::attrCreate(ClassInfo* classInf SA_IMM_ATTR_NO_DANGLING); if(unknownFlags) { - LOG_NO("ERR_INVALID_PARAM: invalid search option 0x%llx", - unknownFlags); - err = SA_AIS_ERR_INVALID_PARAM; - goto done; - } - - TRACE_5("create attribute '%s'", attrName.c_str()); - + /* This error means that at least one attribute flag is not supported by OpenSAF, + * but because of forward compatibility, future flags must be supported. + */ + err = SA_AIS_ERR_NOT_SUPPORTED; + TRACE_5("create attribute '%s' with unknown flag(s), attribute flag: %llu", attrName.c_str(), attr->attrFlags); + } else { + TRACE_5("create attribute '%s'", attrName.c_str()); + } + AttrInfo* attrInfo = new AttrInfo; attrInfo->mValueType = attr->attrValueType; - osafassert(attr->attrFlags < 0xffffffff); - attrInfo->mFlags = (SaUint32T) attr->attrFlags; + attrInfo->mFlags = attr->attrFlags; attrInfo->mNtfId = attr->attrNtfId; if(attr->attrDefaultValue) { IMMSV_OCTET_STRING tmpos; //temporary octet string diff --git a/osaf/services/saf/immsv/immnd/ImmSearchOp.cc b/osaf/services/saf/immsv/immnd/ImmSearchOp.cc --- a/osaf/services/saf/immsv/immnd/ImmSearchOp.cc +++ b/osaf/services/saf/immsv/immnd/ImmSearchOp.cc @@ -52,7 +52,7 @@ ImmSearchOp::addObject( void ImmSearchOp::addAttribute(const std::string& attributeName, SaUint32T valueType, - SaUint32T flags) + SaImmAttrFlagsT flags) { SearchObject& obj = mResultList.back(); diff --git a/osaf/services/saf/immsv/immnd/ImmSearchOp.hh b/osaf/services/saf/immsv/immnd/ImmSearchOp.hh --- a/osaf/services/saf/immsv/immnd/ImmSearchOp.hh +++ b/osaf/services/saf/immsv/immnd/ImmSearchOp.hh @@ -32,7 +32,7 @@ struct SearchAttribute std::string name; ImmAttrValue* valuep; SaImmValueTypeT valueType; - SaUint32T flags; + SaImmAttrFlagsT flags; ~SearchAttribute(); }; @@ -63,7 +63,7 @@ public: void addAttribute( const std::string& attributeName, SaUint32T valueType, - SaUint32T flags); + SaImmAttrFlagsT flags); void addAttrValue(const ImmAttrValue& value); void setImplementer( SaUint32T conn, ------------------------------------------------------------------------------ Managing the Performance of Cloud-Based Applications Take advantage of what the Cloud has to offer - Avoid Common Pitfalls. Read the Whitepaper. http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel