osaf/libs/common/immsv/immpbe_dump.cc | 125 +++++++++++++++++++++++++-
osaf/libs/common/immsv/include/immpbe_dump.hh | 3 +
osaf/tools/safimm/immdump/imm_dumper.cc | 35 ++++++-
3 files changed, 156 insertions(+), 7 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
@@ -3521,4 +3521,127 @@ std::list<std::string> getClassNames(SaI
return classNamesList;
}
-
+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;
+ goto step2;
+ }
+
+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;
+}
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,16 @@ int main(int argc, char* argv[])
exit(1);
}
- if(pbeDumpCase) {
+ if(auditPbe) {
+ int rc;
+
+ rc = pbeAuditFile(filename.c_str());
+ if(rc) {
+ 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 <<
@@ -206,7 +229,7 @@ int main(int argc, char* argv[])
if(dbHandle) {
TRACE_1("Opened persistent repository %s", filename.c_str());
} else {
- std::cerr << "immdump: intialize failed - exiting, check syslog
for details"
+ std::cerr << "immdump: intialize failed - exiting, check syslog
for details."
<< std::endl;
exit(1);
}
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel