Hi zoran,
Reviewed and tested the patch.
Ack.
/Neel.
On Friday 05 June 2015 06:23 PM, Zoran Milinkovic wrote:
> osaf/libs/common/immsv/immpbe_dump.cc | 137
> +++++++++++++++++++++++++-
> osaf/libs/common/immsv/include/immpbe_dump.hh | 3 +
> osaf/tools/safimm/immdump/imm_dumper.cc | 38 ++++++-
> 3 files changed, 172 insertions(+), 6 deletions(-)
>
>
> The patch covers only aditing no dangling references. It's required by
> critical ticket #1377.
> The patch first check no dangling references for multi-value attributes, then
> it checks no dangling references for non multi value attributes.
> This is done in two steps because values for multi value attributes are
> stored in another table.
>
> The patch is done in libs/common/immsv, so that it can be used by IMM PBE in
> later implementation.
> If the audit fails, one line is written in the console. Other auditing
> details are logged in syslog.
>
> 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
> @@ -3121,6 +3121,130 @@ void fsyncPbeJournalFile()
> }
> }
>
> +static int pbeAuditNoDangling(sqlite3 *dbHandle) {
> + sqlite3_stmt *stmt = NULL;
> + sqlite3_stmt *tblStmt = NULL;
> + std::string query;
> + int rc;
> + int err = 0;
> + /* SA_IMM_ATTR_NO_DANGLING = 67108864
> + * SA_IMM_ATTR_MULTI_VALUE = 1
> + * SA_IMM_ATTR_NO_DANGLING | SA_IMM_ATTR_MULTI_VALUE = 67108865 */
> + const char *sqlMultiVal = "select distinct obj.dn, ad.attr_name,
> otm.text_val "
> + "from attr_def ad, objects obj, objects_text_multi otm "
> + "where (ad.attr_flags & 67108865) = 67108865 "
> + "and obj.class_id = ad.class_id "
> + "and otm.obj_id = obj.obj_id "
> + "and otm.attr_name = ad.attr_name "
> + "and otm.text_val != '' "
> + "and not exists (select 1 "
> + "from objects "
> + "where dn = otm.text_val)";
> + const char *sqlSelectNoDanglingClasses = "select cls.class_name,
> ad.attr_name "
> + "from attr_def ad, classes cls "
> + "where (ad.attr_flags & 67108865) = 67108864 "
> + "and cls.class_id = ad.class_id";
> +
> + /* Audit NO_DANGLING multi-value attribute */
> + rc = sqlite3_prepare_v2(dbHandle, sqlMultiVal, -1, &stmt, NULL);
> + if(rc != SQLITE_OK) {
> + LOG_ER("Failed to prepare SQL statement for(%d): %s", rc,
> sqlMultiVal);
> + err = 1;
> + goto step2;
> + }
> +
> + while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
> + LOG_ER("Missing reference object '%s' from '%s:%s' (multi value
> check)",
> + sqlite3_column_text(stmt, 2),
> + sqlite3_column_text(stmt, 0),
> + sqlite3_column_text(stmt, 1));
> + err = 1;
> + }
> +
> + if(rc != SQLITE_DONE) {
> + LOG_ER("SQL statement ('%s') failed with error code: %d\n",
> sqlMultiVal, rc);
> + err = 1;
> + }
> +
> +step2:
> + if(stmt) {
> + sqlite3_reset(stmt);
> + stmt = NULL;
> + }
> +
> + /* Audit non-multi-value NO_DANGLING attributes */
> + rc = sqlite3_prepare_v2(dbHandle, sqlSelectNoDanglingClasses, -1,
> &stmt, NULL);
> + if(rc != SQLITE_OK) {
> + LOG_ER("Failed to prepare SQL statement for(%d): %s", rc,
> sqlMultiVal);
> + err = 1;
> + goto end;
> + }
> +
> + while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
> + query = "select obj.dn, tbl.";
> + query.append((char *)sqlite3_column_text(stmt, 1));
> + query.append(" from ");
> + query.append((char *)sqlite3_column_text(stmt, 0));
> + query.append(" tbl, objects obj where obj.obj_id = tbl.obj_id
> and tbl.");
> + query.append((char *)sqlite3_column_text(stmt, 1));
> + query.append(" != '' and not exists (select 1 from objects o
> where o.dn = tbl.");
> + query.append((char *)sqlite3_column_text(stmt, 1));
> + query.append(")");
> +
> + rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1, &tblStmt,
> NULL);
> + if(rc != SQLITE_OK) {
> + LOG_ER("Failed to prepare SQL statement for(%d): %s",
> rc, query.c_str());
> + err = 1;
> + continue;
> + }
> +
> + if(sqlite3_step(tblStmt) == SQLITE_ROW) {
> + LOG_ER("Missing reference object '%s' from '%s':'%s'",
> + sqlite3_column_text(tblStmt, 1),
> + sqlite3_column_text(tblStmt, 0),
> + sqlite3_column_text(stmt, 1));
> + err = 1;
> + }
> +
> + sqlite3_reset(tblStmt);
> + }
> +
> + if(rc != SQLITE_DONE) {
> + LOG_ER("SQL statement ('%s') failed with error code: %d\n",
> + sqlSelectNoDanglingClasses, rc);
> + err = 1;
> + }
> +
> +end:
> + if(stmt) {
> + sqlite3_reset(stmt);
> + }
> +
> + return err;
> +}
> +
> +int pbeAudit(void *db_handle) {
> + return pbeAuditNoDangling((sqlite3 *)db_handle);
> +}
> +
> +int pbeAuditFile(const char *filename) {
> + int rc;
> + sqlite3 *dbHandle = NULL;
> +
> + rc = sqlite3_open(filename, &dbHandle);
> + if(rc != SQLITE_OK) {
> + LOG_ER("Can't open PBE file '%s', cause:%s",
> + filename, sqlite3_errmsg(dbHandle));
> + return 1;
> + }
> +
> + rc = pbeAudit(dbHandle);
> +
> + sqlite3_close(dbHandle);
> +
> + return rc;
> +}
> +
> #else
>
> bool pbeTransStarted()
> @@ -3288,6 +3412,18 @@ void fsyncPbeJournalFile()
> abort();
> }
>
> +int pbeAudit(void *db_handle) {
> + abort();
> + return 1;
> +}
> +
> +int pbeAuditFile(const char *filename) {
> + /* pbeAuditFile should be used by tools, and should not abort.
> + * pbeAuditFile returns 2, which means that PBE was not enabled in the
> build.
> + */
> + return 2;
> +}
> +
> #endif
>
> /* Note: a version of this function exists as 'escalatePbe()' in
> @@ -3521,4 +3657,3 @@ std::list<std::string> getClassNames(SaI
> return classNamesList;
> }
>
> -
> diff --git a/osaf/libs/common/immsv/include/immpbe_dump.hh
> b/osaf/libs/common/immsv/include/immpbe_dump.hh
> --- a/osaf/libs/common/immsv/include/immpbe_dump.hh
> +++ b/osaf/libs/common/immsv/include/immpbe_dump.hh
> @@ -125,5 +125,8 @@ SaAisErrorT getCcbOutcomeFromPbe(void* d
> void discardPbeFile(std::string filename);
> void fsyncPbeJournalFile();
>
> +int pbeAudit(void *db_handle);
> +int pbeAuditFile(const char *filename);
> +
>
> #endif /* IMM_PBE_DUMP_HH_ */
> 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
> @@ -61,6 +61,9 @@ static void usage(const char *progname)
> printf("\t-c, --class {<class name>}\n");
> printf("\t\tOnly dump objects of this class\n\n");
>
> + printf("\t-a, --audit {<pbe file name>}\n");
> + printf("\t\tAudit PBE database\n\n");
> +
> printf("\nEXAMPLE\n");
> printf("\t%s /tmp/imm.xml\n", progname);
> printf("\t%s /tmp/imm.xml -c ClassA -c ClassB\n", progname);
> @@ -88,6 +91,7 @@ int main(int argc, char* argv[])
> {"pbe", required_argument, 0, 'p'},
> {"xmlwriter", required_argument, 0, 'x'},
> {"class", required_argument, 0, 'c'},
> + {"audit", required_argument, 0, 'a'},
> {0, 0, 0, 0}
> };
> SaImmHandleT immHandle;
> @@ -113,6 +117,7 @@ int main(int argc, char* argv[])
> const char* logPath;
> unsigned int category_mask = 0;
> bool pbeDumpCase = false;
> + bool auditPbe = false;
> void* dbHandle=NULL;
> const char* dump_trace_label = "immdump";
> const char* trace_label = dump_trace_label;
> @@ -141,7 +146,7 @@ int main(int argc, char* argv[])
> }
>
> while (1) {
> - if ((c = getopt_long(argc, argv, "hp:x:c:", long_options, NULL)) == -1)
> + if ((c = getopt_long(argc, argv, "hp:x:c:a:", long_options, NULL)) == -1)
> break;
>
> switch (c) {
> @@ -151,9 +156,8 @@ int main(int argc, char* argv[])
> break;
>
> case 'p':
> - pbeDumpCase = true;
> -
> - filename.append(optarg);
> + pbeDumpCase = true;
> + filename.append(optarg);
> break;
>
> case 'x':
> @@ -164,6 +168,11 @@ int main(int argc, char* argv[])
> selectedClassList.push_back(std::string(optarg));
> break;
>
> + case 'a':
> + auditPbe = true;
> + filename.append(optarg);
> + break;
> +
> default:
> fprintf(stderr, "Try '%s --help' for more
> information\n",
> argv[0]);
> @@ -172,6 +181,11 @@ int main(int argc, char* argv[])
> }
> }
>
> + if(pbeDumpCase && auditPbe) {
> + usage(basename(argv[0]));
> + exit(EXIT_FAILURE);
> + }
> +
> version.releaseCode = RELEASE_CODE;
> version.majorVersion = MAJOR_VERSION;
> version.minorVersion = MINOR_VERSION;
> @@ -192,7 +206,21 @@ int main(int argc, char* argv[])
> exit(1);
> }
>
> - if(pbeDumpCase) {
> + if(auditPbe) {
> + int rc;
> +
> + rc = pbeAuditFile(filename.c_str());
> + if(!rc) {
> + std::cout << "Audit successful" << std::endl;
> + } else if(rc == 2) {
> + std::cerr << "Option --enable-imm-pbe must be enabled in the
> build to be able to audit PBE file"
> + << std::endl;
> + } else {
> + std::cerr << "Audit failed. Check syslog for more details."
> + << std::endl;
> + }
> + exit(rc);
> + } else if(pbeDumpCase) {
> /* Generate PBE database file from current IMM state */
>
> std::cout <<
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel