Just to be clear: currently its a NACK from me for these patches.
This untill the principle of how this should work is clear.

There is a distinction between flags that impact integrity/validation
(SA_IMM_ATTR_NO_DUPLICATES and SA_IMM_ATTR_NO_DANGLING) and flags that dont
(SA_IMM_ATTR_NOTIFY).

Only the latter (SA_IMM_ATTR_NOTIFY) can pass through an older system unscathed
i.e. be loaded and then dumped.

The consistency maintaining flags can only be coped with by older systems by
Being discarded at loading and then of course they will not be dumped nor 
vissible in immlist 
At runtime.

One then should also ask if we really want that kind of backwards forwards 
"compatibility"
for the integrity maintaining flags ? You may then end up loading a backup from 
an older
system on to a newer with the intefrity flags missing, or alternatively trying 
to 
incrementally load data from an older system (immcfg -f) but fail to do so 
because the
data is not consistent with some integrity flags set in the newer system.
You would have to be very carefull doing such "washing" of the data back and 
forth in
an organisation. 

The "cleansing" of unsuported integrity maintaining flags has to be done at 
loading.
Anything else would just cause confusion. I see no point in immlist printing a 
class
Definition on a 4.2 system that includes NO_DUPLICATES or NO_DANGLING because 
it 
would just give the false impression that the flag is supported and enforced in 
the system. 

/AndersBj


-----Original Message-----
From: Anders Bjornerstedt [mailto:anders.bjornerst...@ericsson.com] 
Sent: den 18 februari 2014 18:09
To: Zoran Milinkovic
Cc: opensaf-devel@lists.sourceforge.net
Subject: Re: [devel] [PATCH 2 of 2] IMMTOOLS: add support for forwards 
compatibility of attribute flags [#116]

General comment: In essence Good work!
This was a complicated fix to do.

But I have one big problem with the tools patches.
Basically I dont undersand what we are trying to do with the tools.
Comment inlined below.



Zoran Milinkovic wrote:
>  osaf/tools/safimm/immcfg/imm_cfg.c         |   31 +++-
>  osaf/tools/safimm/immcfg/imm_import.cc     |  196 
> ++++++++++++++++++++++++++++-
>  osaf/tools/safimm/immdump/imm_dumper.cc    |  170 +++++++++++++++++++++++-
>  osaf/tools/safimm/immdump/imm_dumper.hh    |    2 +
>  osaf/tools/safimm/immdump/imm_xmlw_dump.cc |   13 +-
>  osaf/tools/safimm/immlist/Makefile.am      |    4 +
>  osaf/tools/safimm/immlist/imm_list.c       |  191 
> ++++++++++++++++++++++++++++-
>  osaf/tools/safimm/immload/imm_loader.cc    |  164 ++++++++++++++++++++++++-
>  8 files changed, 749 insertions(+), 22 deletions(-)
>
>
> For forwards compatibility, OpenSAF schema, where unknown attribute flags are 
> defined, must be provided to IMM tools (immcfg, immlist, immfind) using -X 
> flag.
> 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/tools/safimm/immcfg/imm_cfg.c 
> b/osaf/tools/safimm/immcfg/imm_cfg.c
> --- a/osaf/tools/safimm/immcfg/imm_cfg.c
> +++ b/osaf/tools/safimm/immcfg/imm_cfg.c
> @@ -56,7 +56,7 @@ typedef enum {
>  #define VERBOSE_INFO(format, args...) if (verbose) { fprintf(stderr, 
> format, ##args); }
>  
>  // The interface function which implements the -f opton 
> (imm_import.cc) -int importImmXML(char* xmlfileC, char* 
> adminOwnerName, int verbose, int ccb_safe);
> +int importImmXML(char* xmlfileC, char* adminOwnerName, int verbose, 
> +int ccb_safe, const char *xsdPath);
>  
>  const SaImmCcbFlagsT defCcbFlags = SA_IMM_CCB_REGISTERED_OI | 
> SA_IMM_CCB_ALLOW_NULL_OI;
>  
> @@ -86,6 +86,7 @@ static void usage(const char *progname)
>       printf("\t--ignore-duplicates  (only valid with -f/--file option, 
> default)\n");
>       printf("\t--delete-class <classname> [classname2]... \n");
>       printf("\t-u, --unsafe\n");
> +     printf("\t-X, --xsd <path_to_schema.xsd>\n");
>  
>       printf("\nEXAMPLE\n");
>       printf("\timmcfg -a saAmfNodeSuFailoverMax=7 
> safAmfNode=Node01,safAmfCluster=1\n");
> @@ -102,6 +103,10 @@ static void usage(const char *progname)
>       printf("\t\tremove a value from an attribute\n");
>       printf("\timmcfg -u .....\n");
>       printf("\t\tThe CCBs generated by immcfg will have 
> SA_IMM_CCB_REGISTERED_OI set to false, allowing ccb commit when OIs 
> are missing\n");
> +     printf("\timmcfg -X /etc/opensaf/schema.xsd -f imm.xml\n");
> +     printf("\t\timmcfg will load unsupported attribute flags in the current 
> OpenSAF version from /etc/opensaf/schema.xsd, and use them to successfully 
> import imm.xml");
> +     printf("\timmcfg -X /etc/opensaf -f imm.xml\n");
> +     printf("\t\timmcfg will load unsupported attribute flags in the 
> +current OpenSAF version from the schema specified in imm.xml which is 
> +stored in /etc/opensaf, and use loaded flags to successfully import 
> +imm.xml");
>  }
>  
>  /* signal handler for SIGALRM */
> @@ -682,6 +687,7 @@ int main(int argc, char *argv[])
>               {"timeout", required_argument, NULL, 't'},
>               {"verbose", no_argument, NULL, 'v'},
>               {"unsafe", no_argument, NULL, 'u'},
> +             {"xsd", required_argument, NULL, 'X'},
>               {0, 0, 0, 0}
>       };
>       SaAisErrorT error;
> @@ -703,9 +709,11 @@ int main(int argc, char *argv[])
>       int i;
>       unsigned long timeoutVal = 60;
>  
> +     char *xsdPath = NULL;
> +
>       while (1) {
>               int option_index = 0;
> -             c = getopt_long(argc, argv, "a:c:f:t:dhmvu", long_options, 
> &option_index);
> +             c = getopt_long(argc, argv, "a:c:f:t:dhmvuX:", long_options, 
> +&option_index);
>  
>               if (c == -1)    /* have all command-line options have been 
> parsed? */
>                       break;
> @@ -751,6 +759,13 @@ int main(int argc, char *argv[])
>                       op = verify_setoption(op, MODIFY_OBJECT);
>                       break;
>               }
> +             case 'X':
> +                     if(xsdPath) {
> +                             fprintf(stderr, "XSD path is already set\n");
> +                             exit(EXIT_FAILURE);
> +                     }
> +                     xsdPath = strdup(optarg);
> +                     break;
>               default:
>                       fprintf(stderr, "Try '%s --help' for more 
> information\n", argv[0]);
>                       exit(EXIT_FAILURE);
> @@ -767,7 +782,7 @@ int main(int argc, char *argv[])
>       
>       if (op == LOAD_IMMFILE) {
>               VERBOSE_INFO("importImmXML(xmlFilename=%s, verbose=%d)\n", 
> xmlFilename, verbose);
> -             rc = importImmXML(xmlFilename, adminOwnerName, verbose, 
> ccb_safe);
> +             rc = importImmXML(xmlFilename, adminOwnerName, verbose, 
> ccb_safe, 
> +xsdPath);
>               exit(rc);
>       }
>  
> @@ -854,10 +869,14 @@ int main(int argc, char *argv[])
>   done_om_finalize:
>       error = immutil_saImmOmFinalize(immHandle);
>       if (SA_AIS_OK != error) {
> -                fprintf(stderr, "error - saImmOmFinalize FAILED: %s\n", 
> saf_error(error));
> -                rc = EXIT_FAILURE;
> -        }
> +             fprintf(stderr, "error - saImmOmFinalize FAILED: %s\n", 
> saf_error(error));
> +             rc = EXIT_FAILURE;
> +     }
>  
> +     if(xsdPath) {
> +             free(xsdPath);
> +             xsdPath = NULL;
> +     }
>  
>       exit(rc);
>  }
> diff --git a/osaf/tools/safimm/immcfg/imm_import.cc 
> b/osaf/tools/safimm/immcfg/imm_import.cc
> --- a/osaf/tools/safimm/immcfg/imm_import.cc
> +++ b/osaf/tools/safimm/immcfg/imm_import.cc
> @@ -21,6 +21,8 @@
>  #include <set>
>  #include <string>
>  #include <libxml/parser.h>
> +#include <libxml/tree.h>
> +#include <libxml/xpath.h>
>  #include <string.h>
>  #include <stdio.h>
>  #include <stdlib.h>
> @@ -28,6 +30,8 @@
>  #include <assert.h>
>  #include <syslog.h>
>  #include <configmake.h>
> +#include <sys/stat.h>
> +#include <errno.h>
>  
>  #include <saAis.h>
>  #include <saImmOm.h>
> @@ -68,7 +72,7 @@ static char base64_dec_table[] = {
>  
>  extern "C"
>  {
> -     int importImmXML(char* xmlfileC, char* adminOwnerName, int verbose, int 
> ccb_safe);
> +     int importImmXML(char* xmlfileC, char* adminOwnerName, int verbose, 
> +int ccb_safe, const char *xsdPath);
>  }
>  
>  extern ImmutilErrorFnT immutilError;
> @@ -141,6 +145,20 @@ typedef struct ParserStateStruct {
>       SaImmHandleT         ccbHandle;
>  } ParserState;
>  
> +bool isXsdLoaded = false;
> +static const char *imm_xsd_file;
> +typedef std::map<std::string, SaImmAttrFlagsT> AttrFlagMap; 
> +AttrFlagMap attrFlagMap;
> +
> +static SaImmAttrFlagsT attrFlagMask = (SA_IMM_ATTR_RUNTIME
> +             | SA_IMM_ATTR_CONFIG
> +             | SA_IMM_ATTR_MULTI_VALUE
> +             | SA_IMM_ATTR_WRITABLE
> +             | SA_IMM_ATTR_INITIALIZED
> +             | SA_IMM_ATTR_PERSISTENT
> +             | SA_IMM_ATTR_CACHED
> +             | SA_IMM_ATTR_NOTIFY
> +             | SA_IMM_ATTR_NO_DUPLICATES);
>   

Here in 4.2 you are using two new flags:
SA_IMM_ATTR_DUPLICATES which is actually defined in saImmOm_A_2_11.h (part of 
4.2) but was never implemented until 4.3.
SA_IMM_ATTR_NOTIFY was defined and implemented in 4.3.

At the start of this file I also see that these are ifdef defined since earlier.
I am not sure why this was the case, i.e. why these future flags where already 
defined in the immdump code for 4.2 ?

But *IF* future (4.3) flags are to be defined for 4.2 dump, then why is not 
also the 4.4 flag NO_DANGLING define here also ?

I have great trouble understanding the principle here.

Also, does this means that we are eternally obliged to update all older OpenSAF 
versions on the tools to support all future changes to the xml format ?

In principle we should then also update 4.1 and 4.0, in principle even 3.x and 
2.x .........

So again the question is what is the *principle* we are supposed to follow here 
?

Is the requirement really to be forwards compatible for DUMPING from older 
releases ?!
I think that is pretty controversial.

I accept of course being forwards compatible in loading from newer releases.
This is the main point of this ticket as I understood it.

But dumping andf displaying unsupported flags is dangerous because they are 
unsupported.
Thus creating an xml dump with a class defining NO_DUPLIUCATEs for an attribute 
and then having instances with duplicates on that very attribute is not only 
pointless but will just crate a dump that is not compatible with newer systems. 
A 4.3 system will not be able to load the file if it is not consistent with the 
flags supported in 4.3.

So we end up here actually having to support all future flags retroactively 
(functionally) in the system.
Which is not reasonable.




>  
>  /* Prototypes */
>  
> @@ -1001,6 +1019,160 @@ static inline bool isBase64Encoded(const
>       return isB64;
>  }
>  
> +static inline char *getAttrValue(xmlAttributePtr attr) {
> +     if(!attr || !attr->children) {
> +             return NULL;
> +     }
> +
> +     return (char *)attr->children->content;
> +}
> +
> +static bool loadXsd(const xmlChar** attrs) {
> +     if(!imm_xsd_file) {
> +             return true;
> +     }
> +
> +     // Check if schema path exist
> +     struct stat st;
> +     if(stat(imm_xsd_file, &st)) {
> +             if(errno == ENOENT) {
> +                     LOG_ER("%s does not exist", imm_xsd_file);
> +             } else {
> +                     LOG_ER("stat of %s return error: %d", imm_xsd_file, 
> errno);
> +             }
> +
> +             return false;
> +     }
> +     // It should be a file or a directory
> +     if(!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
> +             LOG_ER("%s is not a file or directory", imm_xsd_file);
> +             return false;
> +     }
> +
> +     std::string xsdFile = imm_xsd_file;
> +     if(S_ISDIR(st.st_mode)) {
> +             // Schema path is a directory, so we shall add a schema file 
> from XML file
> +             if(xsdFile.at(xsdFile.size() - 1) != '/') {
> +                     xsdFile.append("/");
> +             }
> +             char *xsd = (char *)getAttributeValue(attrs, (xmlChar 
> *)"noNamespaceSchemaLocation");
> +             if(!xsd) {
> +                     // try with a namespace
> +                     xsd = (char *)getAttributeValue(attrs, (xmlChar 
> *)"xsi:noNamespaceSchemaLocation");
> +                     if(!xsd) {
> +                             LOG_ER("Schema is not defined in XML file");
> +                             return false;
> +                     }
> +             }
> +             xsdFile.append(xsd);
> +
> +             // Check if schema file exists and that it's a file
> +             if(stat(xsdFile.c_str(), &st)) {
> +                     if(errno == ENOENT) {
> +                             LOG_ER("XSD file %s does not exist", 
> imm_xsd_file);
> +                     } else {
> +                             LOG_ER("Stat of XSD file %s return error: %d", 
> imm_xsd_file, errno);
> +                     }
> +
> +                     return false;
> +             }
> +             if(!S_ISREG(st.st_mode)) {
> +                     LOG_ER("Schema %s is not a file", xsdFile.c_str());
> +                     return false;
> +             }
> +     }
> +
> +     xmlNodePtr xsdDocRoot;
> +     xmlDocPtr xsdDoc = xmlParseFile(xsdFile.c_str());
> +     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 *id;
> +     char *value;
> +     int size;
> +
> +     size = xpathObj->nodesetval->nodeNr;
> +     for(int i=0; i<size; i++) {
> +             id = NULL;
> +             value = NULL;
> +             element = (xmlElementPtr)xpathObj->nodesetval->nodeTab[i];
> +             attr = element->attributes;
> +             while(attr) {
> +                     if(!strcmp((char *)attr->name, "ID")) {
> +                             id = getAttrValue(attr);
> +                     } else if(!strcmp((char *)attr->name, "value")) {
> +                             value = getAttrValue(attr);
> +                     }
> +
> +                     if(id && value) {
> +                             break;
> +                     }
> +
> +                     attr = (xmlAttributePtr)attr->next;
> +             }
> +
> +             if(value) {
> +                     SaImmAttrFlagsT attrFlag = 0;
> +
> +                     if(id) {
> +                             char *end;
> +                             if(!strncmp(id, "0x", 2)) {
> +                                     attrFlag = strtoull(id, &end, 16);
> +                             } else {
> +                                     attrFlag = strtoull(id, &end, 10);
> +                             }
> +
> +                             if(*end) {
> +                                     LOG_WA("INVALID ID(%s) FOR FLAG %s. 
> Attribute flag is set to 0", id, value);
> +                                     attrFlag = 0;
> +                             }
> +                     }
> +
> +                     if((attrFlag & ~attrFlagMask) || attrFlag == 0) {
> +                             attrFlagMap[value] = attrFlag;
> +                     }
> +             }
> +     }
> +
> +     isXsdLoaded = true;
> +
> +     xmlXPathFreeObject(xpathObj);
> +freectx:
> +     if(ctx->nsNr) {
> +             free(ctx->namespaces);
> +     }
> +     xmlXPathFreeContext(ctx);
> +freedoc:
> +     xmlFreeDoc(xsdDoc);
> +
> +     return rc;
> +}
> +
>  /**
>   * This is the handler for start tags
>   */
> @@ -1125,6 +1297,12 @@ static void startElementHandler(void* us
>               /* <imm:IMM-contents> */
>       } else if (strcmp((const char*)name, "imm:IMM-contents") == 0) {
>               state->state[state->depth] = IMM_CONTENTS;
> +             if(imm_xsd_file) {
> +                     if(!loadXsd(attrs)) {
> +                             LOG_ER("Failed to load XML schema", name);
> +                             exit(1);
> +                     }
> +             }
>       } else {
>               LOG_ER("UNKNOWN TAG! (%s)", name);
>               exit(1);
> @@ -1568,7 +1746,15 @@ static SaImmAttrFlagsT charsToFlagsHelpe
>               return SA_IMM_ATTR_NOTIFY;
>       }
>  
> -     LOG_ER("UNKNOWN FLAGS, %s", str);
> +     std::string flag((char *)str, len);
> +     if(isXsdLoaded) {
> +             AttrFlagMap::iterator it = attrFlagMap.find(flag);
> +             if(it != attrFlagMap.end()) {
> +                     return it->second;
> +             }
> +     }
> +
> +     LOG_ER("UNKNOWN FLAGS, %s", flag.c_str());
>  
>       exit(1);
>  }
> @@ -2036,7 +2222,7 @@ int loadImmXML(std::string xmlfile)
>  // C and c++ caller wrapper
>  //  The objective is to keep the code copied from imm_load.cc as close to 
> original as possible
>  //  to ease a future refactoring towards common codebase
> -int importImmXML(char* xmlfileC, char* adminOwnerName, int verbose, int 
> ccb_safe)
> +int importImmXML(char* xmlfileC, char* adminOwnerName, int verbose, int 
> ccb_safe, const char *xsdPath)
>  {
>       std::string xmlfile(xmlfileC);
>       imm_import_adminOwnerName = adminOwnerName;
> @@ -2044,6 +2230,10 @@ int importImmXML(char* xmlfileC, char* a
>       imm_import_ccb_safe = ccb_safe;
>       LOG_IN("file: %s adminOwner: %s", xmlfileC, adminOwnerName);
>  
> +     imm_xsd_file = xsdPath;
> +     isXsdLoaded = false;
> +     attrFlagMap.clear();
> +
>       // assign own immutil errorhandler (no call to abort())
>       immutilError = imm_importImmutilError;
>  
> diff --git a/osaf/tools/safimm/immdump/imm_dumper.cc 
> b/osaf/tools/safimm/immdump/imm_dumper.cc
> --- a/osaf/tools/safimm/immdump/imm_dumper.cc
> +++ b/osaf/tools/safimm/immdump/imm_dumper.cc
> @@ -24,16 +24,31 @@
>  #include <limits.h>
>  #include <libxml/parser.h>
>  #include <libxml/xmlmemory.h>
> +#include <libxml/xpath.h>
>  #include <getopt.h>
>  #include <assert.h>
>  #include <libgen.h>
>  #include <unistd.h>
> +#include <sys/stat.h>
> +#include <errno.h>
> +
>  
>  #define XML_VERSION "1.0"
>  
>  /* Prototypes */
>  static std::map<std::string, std::string> cacheRDNs(SaImmHandleT);
>  
> +AttrFlagMap attrFlagMap;
> +
> +static SaImmAttrFlagsT attrFlagMask = (SA_IMM_ATTR_RUNTIME
> +        | SA_IMM_ATTR_CONFIG
> +        | SA_IMM_ATTR_MULTI_VALUE
> +        | SA_IMM_ATTR_WRITABLE
> +        | SA_IMM_ATTR_INITIALIZED
> +        | SA_IMM_ATTR_PERSISTENT
> +        | SA_IMM_ATTR_CACHED
> +        | SA_IMM_ATTR_NO_DUPLICATES);
> +
>  static void usage(const char *progname)
>  {
>      printf("\nNAME\n");
> @@ -54,6 +69,9 @@ static void usage(const char *progname)
>      printf("\t-p, --pbe   {<file name>}\n");
>      printf("\t\tInstead of xml file, generate/populate persistent back-end 
> database/file\n");
>  
> +    printf("\t-X, --xsd   {<file name>}\n");
> +    printf("\t\tLoad missing data from IMM schema\n\n");
> +
>      printf("\nEXAMPLE\n");
>      printf("\timmdump /tmp/imm.xml\n");
>  }
> @@ -84,6 +102,122 @@ static const SaImmCallbacksT callbacks =
>      saImmOmAdminOperationInvokeCallback
>  };
>  
> +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 *id;
> +    char *value;
> +    int size;
> +
> +    size = xpathObj->nodesetval->nodeNr;
> +    for(int i=0; i<size; i++) {
> +        id = NULL;
> +        value = NULL;
> +        element = (xmlElementPtr)xpathObj->nodesetval->nodeTab[i];
> +        attr = element->attributes;
> +        while(attr) {
> +            if(!strcmp((char *)attr->name, "ID")) {
> +                id = getAttrValue(attr);
> +            } else if(!strcmp((char *)attr->name, "value")) {
> +                value = getAttrValue(attr);
> +            }
> +
> +            if(id && value) {
> +                break;
> +            }
> +
> +            attr = (xmlAttributePtr)attr->next;
> +        }
> +
> +        if(id && value) {
> +            SaImmAttrFlagsT attrFlag;
> +            char *end;
> +            if(!strncmp(id, "0x", 2)) {
> +                attrFlag = strtoull(id, &end, 16);
> +            } else {
> +                attrFlag = strtoull(id, &end, 10);
> +            }
> +
> +            if(*end) {
> +                LOG_WA("INVALID ID(%s) FOR FLAG %s.", id, value);
> +                attrFlagMap.clear();
> +                rc = false;
> +                goto freexpath;
> +            } else if(((attrFlag & ~attrFlagMask) || (attrFlag == 0)) &&
> +                    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")) {
> +                attrFlagMap[value] = attrFlag;
> +            }
> +        }
> +    }
> +
> +freexpath:
> +    xmlXPathFreeObject(xpathObj);
> +freectx:
> +    if(ctx->nsNr) {
> +        free(ctx->namespaces);
> +    }
> +    xmlXPathFreeContext(ctx);
> +freedoc:
> +    xmlFreeDoc(xsdDoc);
> +
> +    return rc;
> +}
>  
>  /* Functions */
>  int main(int argc, char* argv[])
> @@ -95,6 +229,7 @@ int main(int argc, char* argv[])
>          {"pbe", required_argument, 0, 'p'},
>          {"recover", no_argument, 0, 'r'},
>          {"xmlwriter", no_argument, 0, 'x'},
> +        {"xsd", required_argument, 0, 'X'},
>          {0, 0, 0, 0}
>      };
>      SaImmHandleT           immHandle;
> @@ -129,6 +264,8 @@ int main(int argc, char* argv[])
>      const char* trace_label = dump_trace_label;
>      ClassMap classIdMap;
>      unsigned int objCount=0;
> +    std::string xsd;
> +    std::string schema = "SAI-AIS-IMM-XSD-A.02.12.xsd";
>  
>      unsigned int           retryInterval = 1000000; /* 1 sec */
>      unsigned int           maxTries = 70;          /* 70 times == max 70 
> secs */
> @@ -151,12 +288,12 @@ int main(int argc, char* argv[])
>      if ((argc < 2) || (argc > 5))
>      {
>          printf("Usage: %s <xmldumpfile>\n", argv[0]);
> -     usage(argv[0]);
> +        usage(argv[0]);
>          exit(1);
>      }
>  
>      while (1) {
> -    if ((c = getopt_long(argc, argv, "hdrp:x:y:", long_options, NULL)) == -1)
> +    if ((c = getopt_long(argc, argv, "hdrp:x:y:X:", long_options, NULL)) == 
> -1)
>              break;
>  
>              switch (c) {
> @@ -171,22 +308,26 @@ int main(int argc, char* argv[])
>                      break;
>  
>                  case 'p':
> -                 if(!pbeRecoverFile) {
> -                         pbeDumpCase = true;
> -                 }
> +                    if(!pbeRecoverFile) {
> +                        pbeDumpCase = true;
> +                    }
>  
> -                 filename.append(optarg);
> +                    filename.append(optarg);
>                      break;
>  
>                  case 'r':
> -                 pbeDumpCase = false;
> -                 pbeRecoverFile = true;
> +                    pbeDumpCase = false;
> +                    pbeRecoverFile = true;
>                      break;
>  
>                  case 'x':
>                      filename.append(optarg);
>                      break;
>  
> +                case 'X':
> +                    xsd = optarg;
> +                    break;
> +
>                  default:
>                      fprintf(stderr, "Try '%s --help' for more 
> information\n", 
>                          argv[0]);
> @@ -196,7 +337,7 @@ int main(int argc, char* argv[])
>      }
>  
>      if(filename.empty()) {
> -         filename.append(argv[1]);
> +         filename.append(argv[optind]);
>      }
>  
>      version.releaseCode = RELEASE_CODE;
> @@ -217,6 +358,15 @@ int main(int argc, char* argv[])
>          exit(1);
>      }
>  
> +    if(xsd.size() > 0) {
> +        if(!loadXsd(xsd.c_str())) {
> +            std::cerr << "Failed to load schema - exiting\n";
> +            exit(1);
> +        }
> +
> +        schema = basename((char *)xsd.c_str());
> +    }
> +
>      if(pbeDaemonCase && !pbeDumpCase && pbeRecoverFile) {
>          /* This is the re-attachement case. 
>          The PBE has crashed, 
> @@ -378,7 +528,7 @@ int main(int argc, char* argv[])
>  
>       if(xmlTextWriterWriteAttributeNS(writer,
>          (xmlChar*)"xsi",(xmlChar *)"noNamespaceSchemaLocation", NULL,
> -        (xmlChar*)"SAI-AIS-IMM-XSD-A.01.02.xsd") < 0) {
> +        (xmlChar*)schema.c_str()) < 0) {
>               std::cout <<"Error at xmlTextWriterWriteAttribute (attribute 
> 2)" << std::endl;
>               exit(1);
>       }
> diff --git a/osaf/tools/safimm/immdump/imm_dumper.hh 
> b/osaf/tools/safimm/immdump/imm_dumper.hh
> --- a/osaf/tools/safimm/immdump/imm_dumper.hh
> +++ b/osaf/tools/safimm/immdump/imm_dumper.hh
> @@ -106,6 +106,8 @@ SaAisErrorT getCcbOutcomeFromPbe(void* d
>  void discardPbeFile(std::string filename);
>  void fsyncPbeJournalFile();
>  
> +typedef std::map<std::string, SaImmAttrFlagsT> AttrFlagMap;
> +
>  /* XML-Writer related functions */
>  
>  void dumpClassesXMLw(SaImmHandleT, xmlTextWriterPtr);
> diff --git a/osaf/tools/safimm/immdump/imm_xmlw_dump.cc 
> b/osaf/tools/safimm/immdump/imm_xmlw_dump.cc
> --- a/osaf/tools/safimm/immdump/imm_xmlw_dump.cc
> +++ b/osaf/tools/safimm/immdump/imm_xmlw_dump.cc
> @@ -23,6 +23,7 @@
>  #include <osaf_unicode.h>
>  
>  
> +extern AttrFlagMap attrFlagMap;
>  
>  /* Functions */
>  
> @@ -490,7 +491,17 @@ void flagsToXMLw(SaImmAttrDefinitionT_2*
>              exit(1);
>          }
>      }
> -    
> +
> +    AttrFlagMap::iterator it;
> +    for(it = attrFlagMap.begin(); it != attrFlagMap.end(); ++it) {
> +     if(flags & it->second) {
> +            if(xmlTextWriterWriteElement(writer, (xmlChar*) "flag",
> +                    (xmlChar*) it->first.c_str()) < 0 ) {
> +                std::cout << "Error at xmlTextWriterWriteElement (flag - " 
> << it->first << ")" << std::endl;
> +                exit(1);
> +            }
> +     }
> +    }
>  }
>  
>  void typeToXMLw(SaImmAttrDefinitionT_2* p, xmlTextWriterPtr writer)
> diff --git a/osaf/tools/safimm/immlist/Makefile.am 
> b/osaf/tools/safimm/immlist/Makefile.am
> --- a/osaf/tools/safimm/immlist/Makefile.am
> +++ b/osaf/tools/safimm/immlist/Makefile.am
> @@ -20,6 +20,8 @@ MAINTAINERCLEANFILES = Makefile.in
>  
>  bin_PROGRAMS = immlist
>  
> +immlist_CFLAGS = $(AM_CFLAGS) @XML2_CFLAGS@
> +
>  immlist_CPPFLAGS = \
>       $(AM_CPPFLAGS) \
>       -I$(top_srcdir)/osaf/tools/safimm/include \
> @@ -30,6 +32,8 @@ immlist_SOURCES = \
>       $(top_srcdir)/osaf/tools/safimm/src/saf_error.c \
>       imm_list.c
>  
> +immlist_LDFLAGS = @XML2_LIBS@
> +
>  immlist_LDADD = \
>       $(top_builddir)/osaf/libs/core/libopensaf_core.la \
>       $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la \
> diff --git a/osaf/tools/safimm/immlist/imm_list.c 
> b/osaf/tools/safimm/immlist/imm_list.c
> --- a/osaf/tools/safimm/immlist/imm_list.c
> +++ b/osaf/tools/safimm/immlist/imm_list.c
> @@ -36,6 +36,10 @@
>  #include <libgen.h>
>  #include <time.h>
>  #include <signal.h>
> +#include <sys/stat.h>
> +#include <libxml/parser.h>
> +#include <libxml/xmlmemory.h>
> +#include <libxml/xpath.h>
>  
>  #include <saAis.h>
>  #include <saImmOm.h>
> @@ -55,6 +59,23 @@
>  static SaVersionT immVersion = { 'A', 2, 11 };
>  extern struct ImmutilWrapperProfile immutilWrapperProfile;
>  
> +typedef struct AttrFlagList {
> +     char *name;
> +     SaImmAttrFlagsT value;
> +     struct AttrFlagList *next;
> +} AttrFlagList;
> +AttrFlagList *attrFlagList = NULL;
> +
> +static SaImmAttrFlagsT attrFlagMask = (SA_IMM_ATTR_RUNTIME
> +             | SA_IMM_ATTR_CONFIG
> +             | SA_IMM_ATTR_MULTI_VALUE
> +             | SA_IMM_ATTR_WRITABLE
> +             | SA_IMM_ATTR_INITIALIZED
> +             | SA_IMM_ATTR_PERSISTENT
> +             | SA_IMM_ATTR_CACHED
> +             | SA_IMM_ATTR_NOTIFY
> +             | SA_IMM_ATTR_NO_DUPLICATES);
> +
>  /* signal handler for SIGALRM */ 
>  void sigalarmh(int sig) 
>  {
> @@ -81,6 +102,7 @@ static void usage(const char *progname)
>       printf("\t-p, --pretty-print=<yes|no> - select pretty print, default 
> yes\n");
>       printf("\t-t, --timeout <sec>\n");
>       printf("\t\tutility timeout in seconds\n");
> +     printf("\t-X, --xsd <schema.xsd>\n");
>  
>       printf("\nEXAMPLE\n");
>       printf("\timmlist -a saAmfApplicationAdminState safApp=OpenSAF\n");
> @@ -353,6 +375,14 @@ static void display_class_definition(con
>                               printf(", NO_DUPLICATES");
>               }
>  
> +             AttrFlagList *attrFlag = attrFlagList;
> +             while(attrFlag) {
> +                     if(attrFlag->value & attrDefinition->attrFlags) {
> +                             printf(", %s", attrFlag->name);
> +                     }
> +                     attrFlag = attrFlag->next;
> +             }
> +
>               printf("}\n");
>       }
>  
> @@ -411,6 +441,138 @@ static void display_object(const char *n
>       }
>  }
>  
> +static inline char *getAttrValue(xmlAttributePtr attr) {
> +     if(!attr || !attr->children) {
> +             return NULL;
> +     }
> +
> +     return (char *)attr->children->content;
> +}
> +
> +static int loadXsd(const char *xsdFile) {
> +     struct stat st;
> +     if(stat(xsdFile, &st)) {
> +             if(errno == ENOENT) {
> +                     fprintf(stderr, "%s does not exist", xsdFile);
> +             } else {
> +                     fprintf(stderr, "stat of %s return error: %d", xsdFile, 
> errno);
> +             }
> +
> +             return 0;
> +     }
> +     // It should be a file or a directory
> +     if(!S_ISREG(st.st_mode)) {
> +             fprintf(stderr, "%s is not a file", xsdFile);
> +             return 0;
> +     }
> +
> +     xmlNodePtr xsdDocRoot;
> +     xmlDocPtr xsdDoc = xmlParseFile(xsdFile);
> +     if(!xsdDoc) {
> +             return 0;
> +     }
> +
> +     int rc = 1;
> +     xmlXPathContextPtr ctx = xmlXPathNewContext(xsdDoc);
> +     if(!ctx) {
> +             rc = 0;
> +             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 = 0;
> +             goto freectx;
> +     }
> +
> +     xmlElementPtr element;
> +     xmlAttributePtr attr;
> +     char *id;
> +     char *value;
> +     int size;
> +     int i;
> +
> +     size = xpathObj->nodesetval->nodeNr;
> +     for(i=0; i<size; i++) {
> +             id = NULL;
> +             value = NULL;
> +             element = (xmlElementPtr)xpathObj->nodesetval->nodeTab[i];
> +             attr = element->attributes;
> +             while(attr) {
> +                     if(!strcmp((char *)attr->name, "ID")) {
> +                             id = getAttrValue(attr);
> +                     } else if(!strcmp((char *)attr->name, "value")) {
> +                             value = getAttrValue(attr);
> +                     }
> +
> +                     if(id && value) {
> +                             break;
> +                     }
> +
> +                     attr = (xmlAttributePtr)attr->next;
> +             }
> +
> +             if(id && value) {
> +                     AttrFlagList *flag;
> +                     SaImmAttrFlagsT attrFlag;
> +                     char *end;
> +                     if(!strncmp(id, "0x", 2)) {
> +                             attrFlag = strtoull(id, &end, 16);
> +                     } else {
> +                             attrFlag = strtoull(id, &end, 10);
> +                     }
> +
> +                     if(*end) {
> +                             fprintf(stdout, "INVALID ID(%s) FOR FLAG %s.", 
> id, value);
> +
> +                             AttrFlagList *tmp;
> +                             flag = attrFlagList;
> +                             while(flag) {
> +                                     tmp = flag->next;
> +                                     free(flag->name);
> +                                     free(flag);
> +                                     flag = tmp;
> +                             }
> +                             attrFlagList = NULL;
> +                             rc = 0;
> +                             goto freexpath;
> +                     } else if(((attrFlag & ~attrFlagMask) || (attrFlag == 
> 0)) &&
> +                                     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")) {
> +                             flag = (AttrFlagList 
> *)malloc(sizeof(AttrFlagList));
> +                             flag->name = strdup(value);
> +                             flag->value = attrFlag;
> +                             flag->next = attrFlagList;
> +                             attrFlagList = flag;
> +                     }
> +             }
> +     }
> +
> +freexpath:
> +     xmlXPathFreeObject(xpathObj);
> +freectx:
> +     if(ctx->nsNr) {
> +             free(ctx->namespaces);
> +     }
> +     xmlXPathFreeContext(ctx);
> +freedoc:
> +     xmlFreeDoc(xsdDoc);
> +
> +     return rc;
> +}
> +
>  int main(int argc, char *argv[])
>  {
>       int c;
> @@ -420,6 +582,7 @@ int main(int argc, char *argv[])
>               {"timeout", required_argument, 0, 't'},
>               {"help", no_argument, 0, 'h'},
>               {"pretty-print", required_argument, 0, 'p'},
> +             {"xsd", required_argument, 0, 'X'},
>               {0, 0, 0, 0}
>       };
>       SaAisErrorT error;
> @@ -431,9 +594,10 @@ int main(int argc, char *argv[])
>       int class_desc_print = 0;
>       int rc = EXIT_SUCCESS;
>       unsigned long timeoutVal = 60;
> +     char *xsd = NULL;
>  
>       while (1) {
> -             c = getopt_long(argc, argv, "a:p:t:ch", long_options, NULL);
> +             c = getopt_long(argc, argv, "a:p:t:cX:h", long_options, NULL);
>  
>               if (c == -1)    /* have all command-line options have been 
> parsed? */
>                       break;
> @@ -459,6 +623,13 @@ int main(int argc, char *argv[])
>                       if (!strcasecmp(optarg, "no"))
>                               pretty_print = 0;
>                       break;
> +             case 'X':
> +                     if(xsd) {
> +                             fprintf(stderr, "Cannot set more then one 
> schema\n");
> +                             exit(EXIT_FAILURE);
> +                     }
> +                     xsd = strdup(optarg);
> +                     break;
>               default:
>                       fprintf(stderr, "Try '%s --help' for more 
> information\n", argv[0]);
>                       exit(EXIT_FAILURE);
> @@ -487,6 +658,13 @@ int main(int argc, char *argv[])
>               goto done;
>       }
>  
> +     if(xsd) {
> +             if(!loadXsd(xsd)) {
> +                     rc = EXIT_FAILURE;
> +                     goto done;
> +             }
> +     }
> +
>       if (class_desc_print) {
>               while (optind < argc) {
>                       display_class_definition(argv[optind], immHandle);
> @@ -515,6 +693,17 @@ int main(int argc, char *argv[])
>       }
>  
>  done_finalize:
> +
> +     if(attrFlagList) {
> +             AttrFlagList *attrFlag;
> +             while(attrFlagList) {
> +                     attrFlag = attrFlagList->next;
> +                     free(attrFlagList->name);
> +                     free(attrFlagList);
> +                     attrFlagList = attrFlag;
> +             }
> +     }
> +
>       error = immutil_saImmOmFinalize(immHandle);
>       if (SA_AIS_OK != error) {
>               fprintf(stderr, "error - saImmOmFinalize FAILED: %s\n", 
> saf_error(error));
> diff --git a/osaf/tools/safimm/immload/imm_loader.cc 
> b/osaf/tools/safimm/immload/imm_loader.cc
> --- a/osaf/tools/safimm/immload/imm_loader.cc
> +++ b/osaf/tools/safimm/immload/imm_loader.cc
> @@ -18,6 +18,7 @@
>  #include "imm_loader.hh"
>  #include <iostream>
>  #include <libxml/parser.h>
> +#include <libxml/xpath.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <unistd.h>
> @@ -26,6 +27,7 @@
>  #include <configmake.h>
>  #include <logtrace.h>
>  #include <sys/stat.h>
> +#include <errno.h>
>  
>  
>  #ifndef SA_IMM_ATTR_NO_DUPLICATES
> @@ -121,6 +123,22 @@ typedef struct ParserStateStruct
>      SaImmHandleT         ccbHandle;
>  } ParserState;
>  
> +bool isXsdLoaded;
> +std::string xsddir;
> +std::string xsd;
> +typedef std::map<std::string, SaImmAttrFlagsT> AttrFlagMap;
> +AttrFlagMap attrFlagMap;
> +
> +static SaImmAttrFlagsT attrFlagMask = (SA_IMM_ATTR_RUNTIME
> +             | SA_IMM_ATTR_CONFIG
> +             | SA_IMM_ATTR_MULTI_VALUE
> +             | SA_IMM_ATTR_WRITABLE
> +             | SA_IMM_ATTR_INITIALIZED
> +             | SA_IMM_ATTR_PERSISTENT
> +             | SA_IMM_ATTR_CACHED
> +             | SA_IMM_ATTR_NOTIFY
> +             | SA_IMM_ATTR_NO_DUPLICATES);
> +
>  /* Helper functions */
>  
>  static void addToAttrTypeCache(ParserState*, SaImmValueTypeT);
> @@ -884,6 +902,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
>      {
> @@ -1426,6 +1451,121 @@ 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 *id;
> +     char *value;
> +     int size;
> +
> +     size = xpathObj->nodesetval->nodeNr;
> +     for(int i=0; i<size; i++) {
> +             id = NULL;
> +             value = NULL;
> +             element = (xmlElementPtr)xpathObj->nodesetval->nodeTab[i];
> +             attr = element->attributes;
> +             while(attr) {
> +                     if(!strcmp((char *)attr->name, "ID")) {
> +                             id = getAttrValue(attr);
> +                     } else if(!strcmp((char *)attr->name, "value")) {
> +                             value = getAttrValue(attr);
> +                     }
> +
> +                     if(id && value) {
> +                             break;
> +                     }
> +
> +                     attr = (xmlAttributePtr)attr->next;
> +             }
> +
> +             if(value) {
> +                     char *end;
> +                     SaImmAttrFlagsT attrFlag = 0;
> +                     if(id) {
> +                             if(!strncmp(id, "0x", 2)) {
> +                                     attrFlag = strtoull(id, &end, 16);
> +                             } else {
> +                                     attrFlag = strtoull(id, &end, 10);
> +                             }
> +
> +                             if(*end) {
> +                                     LOG_WA("INVALID ID(%s) FOR FLAG %s. 
> Unknown attribute flag is set to 0", id, value);
> +                                     attrFlag = 0;
> +                             }
> +                     }
> +
> +                     if((attrFlag & ~attrFlagMask) || (attrFlag == 0)) {
> +                             attrFlagMap[value] = attrFlag;
> +                     }
> +             }
> +     }
> +
> +     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
>   */
> @@ -1472,7 +1612,24 @@ static SaImmAttrFlagsT charsToFlagsHelpe
>          return SA_IMM_ATTR_NOTIFY;
>      }
>  
> -    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) {
> +     AttrFlagMap::iterator it = attrFlagMap.find(unflag);
> +     if(it != attrFlagMap.end()) {
> +             return it->second;
> +     }
> +    }
> +
> +     LOG_ER("UNKNOWN FLAGS, %s", unflag.c_str());
>  
>      exit(1);
>  }
> @@ -1881,6 +2038,11 @@ int loadImmXML(std::string xmldir, std::
>      state.adminInit = 0;
>      state.ccbInit   = 0;
>  
> +    isXsdLoaded = false;
> +    xsddir = xmldir;
> +    xsd = "";
> +    attrFlagMap.clear();
> +
>      /* Build the filename */
>      filename = xmldir;
>      filename.append("/");
>
> ------------------------------------------------------------------------------
> 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
>   


------------------------------------------------------------------------------
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

------------------------------------------------------------------------------
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

Reply via email to