IMMND will reduce the number of object deleted messages to PBE with sending
only one message containing the root object name instead of sending one message
for each delete object.
---
src/imm/common/immpbe_dump.cc | 541 ++++++++++++++++++++++++++++++++++--------
src/imm/immnd/ImmModel.cc | 18 +-
src/imm/immnd/ImmModel.h | 3 +-
src/imm/immnd/immnd_evt.c | 217 ++++++++---------
4 files changed, 557 insertions(+), 222 deletions(-)
diff --git a/src/imm/common/immpbe_dump.cc b/src/imm/common/immpbe_dump.cc
index 11af674..98aa267 100644
--- a/src/imm/common/immpbe_dump.cc
+++ b/src/imm/common/immpbe_dump.cc
@@ -67,8 +67,6 @@ void pbeClosePrepareTrans() {
static std::string *sPbeFileName;
-#define SQL_STMT_SIZE 31
-
enum {
/* INSERT */
SQL_INS_OBJECTS_INT_MULTI = 0,
@@ -104,7 +102,21 @@ enum {
SQL_DEL_OBJ_TEXT_MULTI_VAL,
SQL_DEL_CCB_COMMITS,
/* UPDATE */
- SQL_UPD_OBJECTS
+ SQL_UPD_OBJECTS,
+ /* INMEMORY DB */
+ SQL_MEM_SEL_DEL_OBJ_CLASSES,
+ SQL_MEM_INS_REVERSE_DN,
+ SQL_MEM_INS_DEL_OBJ,
+ SQL_MEM_DEL_OBJECTS,
+ SQL_MEM_DEL_OBJECT,
+ SQL_MEM_DEL_OBJ_INT_MULTI_ID,
+ SQL_MEM_DEL_OBJ_REAL_MULTI_ID,
+ SQL_MEM_DEL_OBJ_TEXT_MULTI_ID,
+ SQL_MEM_DEL_REVERSE_DN,
+ SQL_MEM_DEL_DELETE_OBJ,
+
+ /* enum size */
+ SQL_STMT_SIZE
};
static const char *preparedSql[] = {
@@ -142,7 +154,24 @@ static const char *preparedSql[] = {
"DELETE FROM objects_text_multi WHERE obj_id = ? AND attr_name = ? AND
text_val = ?",
"DELETE FROM ccb_commits WHERE epoch <= ?",
/* UPDATE */
- "UPDATE objects SET last_ccb = ? WHERE obj_id = ?"};
+ "UPDATE objects SET last_ccb = ? WHERE obj_id = ?",
+ /* INMEMORY DB */
+ "SELECT class_name FROM mem.delete_obj GROUP BY class_name",
+ "INSERT INTO mem.reverse_dn VALUES (?, ?)",
+ "INSERT INTO mem.delete_obj SELECT r.obj_id, c.class_name "
+ "FROM mem.reverse_dn r INNER JOIN objects o ON o.obj_id = r.obj_id "
+ "INNER JOIN classes c on c.class_id = o.class_id "
+ "WHERE r.rev_dn = ? OR r.rev_dn LIKE ?",
+ "DELETE FROM objects WHERE obj_id IN (SELECT obj_id FROM mem.delete_obj)",
+ "DELETE FROM mem.reverse_dn WHERE obj_id = ?",
+
+ "DELETE FROM objects_int_multi WHERE obj_id IN (SELECT obj_id FROM
mem.delete_obj)",
+ "DELETE FROM objects_real_multi WHERE obj_id IN (SELECT obj_id FROM
mem.delete_obj)",
+ "DELETE FROM objects_text_multi WHERE obj_id IN (SELECT obj_id FROM
mem.delete_obj)",
+
+ "DELETE FROM mem.reverse_dn WHERE obj_id IN (SELECT obj_id FROM
mem.delete_obj)",
+ "DELETE FROM mem.delete_obj"
+};
static sqlite3_stmt *preparedStmt[SQL_STMT_SIZE] = {NULL};
@@ -546,6 +575,152 @@ void pbeAtomicSwitchFile(const char *filePath,
std::string localTmpFilename) {
}
}
+static std::string reverseDn(std::string &dn) {
+ std::string revdn;
+ std::string rdn;
+ char ch[2];
+ int escape = 0;
+
+ ch[1] = 0;
+ for(size_t i=0; i<dn.size(); ++i) {
+ ch[0] = dn.at(i);
+ if(escape) {
+ rdn.append(ch);
+ escape = 0;
+ } else if(ch[0] == ',') {
+ if(revdn.empty()) {
+ revdn = rdn;
+ } else {
+ revdn = rdn + "," + revdn;
+ }
+ rdn.clear();
+ } else {
+ rdn.append(ch);
+ escape = (ch[0] == '\\');
+ }
+ }
+
+ if(!rdn.empty()) {
+ if(revdn.empty()) {
+ revdn = rdn;
+ } else {
+ revdn = rdn + "," + revdn;
+ }
+ }
+
+ return revdn;
+}
+
+static bool reverseAndInsertDn(sqlite3 *dbHandle, std::string &dn, int obj_id)
{
+ std::string revdn;
+ sqlite3_stmt *stmt;
+ bool ret = false;
+ int rc;
+
+ revdn = reverseDn(dn);
+ stmt = preparedStmt[SQL_MEM_INS_REVERSE_DN];
+
+ if ((rc = sqlite3_bind_text(stmt, 1, revdn.c_str(), -1, NULL)) !=
+ SQLITE_OK) {
+ LOG_ER("Failed to bind rev_dn with error code: %d", rc);
+ goto bailout;
+ }
+ if ((rc = sqlite3_bind_int(stmt, 2, obj_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind obj_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because with error code: %d",
+ preparedSql[SQL_MEM_INS_REVERSE_DN], rc);
+ goto bailout;
+ }
+
+ ret = true;
+
+bailout:
+ sqlite3_reset(stmt);
+
+ return ret;
+}
+
+static bool prepareReverseDNs(sqlite3 *dbHandle) {
+ sqlite3_stmt *stmt = NULL;
+ const char *sql = "SELECT dn, obj_id FROM objects";
+ int rc;
+ bool ret = false;
+ int obj_id;
+ std::string dn;
+ int count = 0;
+
+ TRACE_ENTER();
+
+ rc = sqlite3_prepare_v2(dbHandle, sql, -1, &stmt, NULL);
+ if (rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement for: %s", sql);
+ goto failed;
+ }
+
+ while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+ dn = (char *)sqlite3_column_text(stmt, 0);
+ obj_id = sqlite3_column_int(stmt, 1);
+
+ ret = reverseAndInsertDn(dbHandle, dn, obj_id);
+ if(!ret) {
+ LOG_ER("Failed to insert reverse DN");
+ goto failed;
+ }
+ ++count;
+ }
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed. Error code: %d", sql, rc);
+ goto failed;
+ }
+
+ TRACE("Added %d reverse DNs to reverse_dn table", count);
+
+ ret = true;
+
+failed:
+ if(stmt) {
+ sqlite3_finalize(stmt);
+ }
+
+ TRACE_LEAVE();
+
+ return ret;
+}
+
+static bool attach_memory_database(sqlite3 *dbHandle) {
+ char *zErr = NULL;
+ int ret = false;
+ int rc;
+ const char *sql[] = {
+ "ATTACH DATABASE ':memory:' AS mem",
+ "CREATE TABLE mem.reverse_dn (rev_dn text primary key, obj_id integer, "
+ "unique (obj_id))",
+ "CREATE TABLE mem.delete_obj (obj_id integer primary key, class_name
text)",
+ "CREATE INDEX mem.del_obj_class_idx ON delete_obj (class_name)",
+ NULL
+ };
+
+ for (int ix = 0; sql[ix] != NULL; ++ix) {
+ rc = sqlite3_exec(dbHandle, sql[ix], NULL, NULL, &zErr);
+ if (rc != SQLITE_OK) {
+ LOG_ER("SQL statement %u/('%s') failed because:\n %s", ix, sql[ix],
+ zErr);
+ sqlite3_free(zErr);
+ goto failed;
+ }
+ TRACE("Successfully executed %s", sql[ix]);
+ }
+
+ ret = true;
+
+failed:
+ return ret;
+}
+
void *pbeRepositoryInit(const char *filePath, bool create,
std::string &localTmpFilename) {
int fd = (-1);
@@ -598,6 +773,7 @@ void *pbeRepositoryInit(const char *filePath, bool create,
"CREATE INDEX ccb_commits_idx on ccb_commits (ccb_id, epoch)",
"COMMIT TRANSACTION",
+
NULL};
TRACE_ENTER();
@@ -719,6 +895,11 @@ void *pbeRepositoryInit(const char *filePath, bool create,
TRACE("Successfully executed %s", sql_tr[ix]);
}
+ if(!attach_memory_database(dbHandle)) {
+ LOG_ER("Failed to attach memory database");
+ goto bailout;
+ }
+
prepareSqlStatements(dbHandle);
*sPbeFileName = std::string(filePath);
@@ -822,8 +1003,15 @@ re_attach:
*sPbeFileName =
std::string(filePath); /* Avoid apend to presumed empty string */
+ if(!attach_memory_database(dbHandle)) {
+ LOG_ER("Failed to attach memory database");
+ goto bailout;
+ }
+
prepareSqlStatements(dbHandle);
+ prepareReverseDNs(dbHandle);
+
TRACE_LEAVE();
return dbHandle;
@@ -2032,6 +2220,192 @@ bailout:
exit(1);
}
+static void oneObjectDeleteToPBE(std::string objectNameString, void
*db_handle) {
+ sqlite3 *dbHandle = (sqlite3 *)db_handle;
+ sqlite3_stmt *stmt;
+ std::string sql("delete from \"");
+
+ int rc = 0;
+ char *zErr = NULL;
+ std::string object_id_str;
+ int object_id;
+ int class_id;
+ std::string class_name;
+ bool badfile = false;
+ std::string revdn;
+ TRACE_ENTER();
+ assert(dbHandle);
+
+ /* First, look up obj_id and class_id from objects where dn == objname. */
+ stmt = preparedStmt[SQL_SEL_OBJECTS_DN];
+ if ((rc = sqlite3_bind_text(stmt, 1, objectNameString.c_str(), -1, NULL)) !=
+ SQLITE_OK) {
+ LOG_ER("Failed to bind dn with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc == SQLITE_DONE) {
+ LOG_ER("Expected 1 row got 0 rows (line: %u)", __LINE__);
+ badfile = true;
+ goto bailout;
+ }
+ if (rc != SQLITE_ROW) {
+ LOG_ER("Could not access object '%s' for delete, error:%s",
+ objectNameString.c_str(), sqlite3_errmsg(dbHandle));
+ badfile = true;
+ goto bailout;
+ }
+
+ object_id = sqlite3_column_int(stmt, 0);
+ object_id_str.append((char *)sqlite3_column_text(stmt, 0));
+ class_id = sqlite3_column_int(stmt, 1);
+
+ if (sqlite3_step(stmt) == SQLITE_ROW) {
+ LOG_ER("Expected 1 row got more then 1 row (line: %u)", __LINE__);
+ badfile = true;
+ goto bailout;
+ }
+ sqlite3_reset(stmt);
+
+ TRACE_2("Successfully accessed object '%s'.", objectNameString.c_str());
+ TRACE_2("object_id:%d class_id:%d", object_id, class_id);
+
+ /*
+ Second, delete the root object tuple in objects for obj_id.
+ */
+ stmt = preparedStmt[SQL_DEL_OBJECTS];
+ if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind obj_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_DEL_OBJECTS], sqlite3_errmsg(dbHandle));
+ goto bailout;
+ }
+ sqlite3_reset(stmt);
+ TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+
+ /* Third get the class-name for the object */
+ stmt = preparedStmt[SQL_SEL_CLASSES_ID];
+ if ((rc = sqlite3_bind_int(stmt, 1, class_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind class_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc == SQLITE_DONE) {
+ LOG_ER("Expected 1 row got 0 rows (line: %u)", __LINE__);
+ badfile = true;
+ goto bailout;
+ }
+ if (rc != SQLITE_ROW) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_SEL_CLASSES_ID], sqlite3_errmsg(dbHandle));
+ goto bailout;
+ }
+
+ class_name.append((char *)sqlite3_column_text(stmt, 0));
+
+ if (sqlite3_step(stmt) == SQLITE_ROW) {
+ LOG_ER("Expected 1 row got more then 1 row (line: %u)", __LINE__);
+ badfile = true;
+ goto bailout;
+ }
+ sqlite3_reset(stmt);
+
+ TRACE_2("Successfully accessed classes class_id:%d class_name:'%s'",
class_id,
+ class_name.c_str());
+
+ /* Fourth delete the base attribute tuple from table 'classname' for obj_id.
+ */
+ sql.append(class_name);
+ sql.append("\" where obj_id = ");
+ sql.append(object_id_str);
+
+ TRACE("GENERATED 4:%s", sql.c_str());
+ rc = sqlite3_exec(dbHandle, sql.c_str(), NULL, NULL, &zErr);
+ if (rc) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s", sql.c_str(), zErr);
+ sqlite3_free(zErr);
+ goto bailout;
+ }
+
+ TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+
+ /*
+ Fifth delete from objects_int_multi, objects_real_multi, objects_text_multi
+ where obj_id ==OBJ_ID
+ */
+ stmt = preparedStmt[SQL_DEL_OBJ_INT_MULTI_ID];
+ if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind obj_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_DEL_OBJ_INT_MULTI_ID], sqlite3_errmsg(dbHandle));
+ goto bailout;
+ }
+ TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+ sqlite3_reset(stmt);
+
+ stmt = preparedStmt[SQL_DEL_OBJ_REAL_MULTI_ID];
+ if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind obj_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_DEL_OBJ_REAL_MULTI_ID], sqlite3_errmsg(dbHandle));
+ goto bailout;
+ }
+ TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+ sqlite3_reset(stmt);
+
+ stmt = preparedStmt[SQL_DEL_OBJ_TEXT_MULTI_ID];
+ if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind obj_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_DEL_OBJ_TEXT_MULTI_ID], sqlite3_errmsg(dbHandle));
+ goto bailout;
+ }
+ TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+ sqlite3_reset(stmt);
+
+ /* Delete from reverse DN table */
+ stmt = preparedStmt[SQL_MEM_DEL_OBJECT];
+ if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
+ LOG_ER("Failed to bind obj_id with error code: %d", rc);
+ goto bailout;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_MEM_DEL_OBJECT], sqlite3_errmsg(dbHandle));
+ goto bailout;
+ }
+ TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+ sqlite3_reset(stmt);
+
+ TRACE_LEAVE();
+ return;
+
+bailout:
+ sqlite3_close((sqlite3 *)dbHandle);
+ if (badfile) {
+ discardPbeFile(*sPbeFileName);
+ }
+ LOG_ER("Exiting (line:%u)", __LINE__);
+ exit(1);
+}
+
unsigned int purgeInstancesOfClassToPBE(SaImmHandleT immHandle,
std::string className,
void *db_handle) {
@@ -2084,7 +2458,7 @@ unsigned int purgeInstancesOfClassToPBE(SaImmHandleT
immHandle,
// assert(attrs[0] == NULL);
- objectDeleteToPBE(std::string(osaf_extended_name_borrow(&objectName)),
+ oneObjectDeleteToPBE(std::string(osaf_extended_name_borrow(&objectName)),
db_handle);
++nrofDeletes;
} while (true);
@@ -2181,156 +2555,114 @@ bailout:
void objectDeleteToPBE(std::string objectNameString, void *db_handle) {
sqlite3 *dbHandle = (sqlite3 *)db_handle;
sqlite3_stmt *stmt;
- std::string sql("delete from \"");
-
+ std::string revDn = reverseDn(objectNameString);
+ std::string likeRevDn = revDn + ",\%";
int rc = 0;
+ bool badfile = false;
char *zErr = NULL;
- std::string object_id_str;
- int object_id;
- int class_id;
std::string class_name;
- bool badfile = false;
+
TRACE_ENTER();
- assert(dbHandle);
- /* First, look up obj_id and class_id from objects where dn == objname. */
- stmt = preparedStmt[SQL_SEL_OBJECTS_DN];
- if ((rc = sqlite3_bind_text(stmt, 1, objectNameString.c_str(), -1, NULL)) !=
+ /* Fill in mem.delete_obj with objects */
+ stmt = preparedStmt[SQL_MEM_INS_DEL_OBJ];
+ if ((rc = sqlite3_bind_text(stmt, 1, revDn.c_str(), -1, NULL)) !=
SQLITE_OK) {
- LOG_ER("Failed to bind dn with error code: %d", rc);
+ LOG_ER("Failed to bind reverse dn with error code: %d", rc);
goto bailout;
}
- rc = sqlite3_step(stmt);
- if (rc == SQLITE_DONE) {
- LOG_ER("Expected 1 row got 0 rows (line: %u)", __LINE__);
- badfile = true;
+ if ((rc = sqlite3_bind_text(stmt, 2, likeRevDn.c_str(), -1, NULL)) !=
+ SQLITE_OK) {
+ LOG_ER("Failed to bind like reverse dn with error code: %d", rc);
goto bailout;
}
- if (rc != SQLITE_ROW) {
- LOG_ER("Could not access object '%s' for delete, error:%s",
- objectNameString.c_str(), sqlite3_errmsg(dbHandle));
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_MEM_INS_DEL_OBJ], zErr);
badfile = true;
goto bailout;
}
+ sqlite3_reset(stmt);
- object_id = sqlite3_column_int(stmt, 0);
- object_id_str.append((char *)sqlite3_column_text(stmt, 0));
- class_id = sqlite3_column_int(stmt, 1);
-
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- LOG_ER("Expected 1 row got more then 1 row (line: %u)", __LINE__);
+ /* cascade delete from objects table */
+ stmt = preparedStmt[SQL_MEM_DEL_OBJECTS];
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s",
+ preparedSql[SQL_MEM_DEL_OBJECTS], zErr);
badfile = true;
goto bailout;
}
sqlite3_reset(stmt);
- TRACE_2("Successfully accessed object '%s'.", objectNameString.c_str());
- TRACE_2("object_id:%d class_id:%d", object_id, class_id);
+ /* Delete objects from each affected class */
+ stmt = preparedStmt[SQL_MEM_SEL_DEL_OBJ_CLASSES];
+ while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+ char *class_name = (char *)sqlite3_column_text(stmt, 0);
+ std::string sql = std::string("DELETE FROM ") + class_name +
+ " WHERE obj_id IN (SELECT obj_id "
+ "FROM mem.delete_obj "
+ "WHERE class_name = '" + class_name + "')";
+ rc = sqlite3_exec(dbHandle, sql.c_str(), NULL, NULL, &zErr);
+ if (rc) {
+ LOG_ER("SQL statement ('%s') failed because:\n %s", sql.c_str(), zErr);
+ sqlite3_free(zErr);
+ goto bailout;
+ }
+ }
+ sqlite3_reset(stmt);
/*
- Second, delete the root object tuple in objects for obj_id.
- */
- stmt = preparedStmt[SQL_DEL_OBJECTS];
- if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
- LOG_ER("Failed to bind obj_id with error code: %d", rc);
- goto bailout;
- }
+ Delete from objects_int_multi, objects_real_multi, objects_text_multi
+ */
+ stmt = preparedStmt[SQL_MEM_DEL_OBJ_INT_MULTI_ID];
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
LOG_ER("SQL statement ('%s') failed because:\n %s",
- preparedSql[SQL_DEL_OBJECTS], sqlite3_errmsg(dbHandle));
+ preparedSql[SQL_MEM_DEL_OBJ_INT_MULTI_ID],
sqlite3_errmsg(dbHandle));
goto bailout;
}
- sqlite3_reset(stmt);
TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+ sqlite3_reset(stmt);
- /* Third get the class-name for the object */
- stmt = preparedStmt[SQL_SEL_CLASSES_ID];
- if ((rc = sqlite3_bind_int(stmt, 1, class_id)) != SQLITE_OK) {
- LOG_ER("Failed to bind class_id with error code: %d", rc);
- goto bailout;
- }
+ stmt = preparedStmt[SQL_MEM_DEL_OBJ_REAL_MULTI_ID];
rc = sqlite3_step(stmt);
- if (rc == SQLITE_DONE) {
- LOG_ER("Expected 1 row got 0 rows (line: %u)", __LINE__);
- badfile = true;
- goto bailout;
- }
- if (rc != SQLITE_ROW) {
+ if (rc != SQLITE_DONE) {
LOG_ER("SQL statement ('%s') failed because:\n %s",
- preparedSql[SQL_SEL_CLASSES_ID], sqlite3_errmsg(dbHandle));
- goto bailout;
- }
-
- class_name.append((char *)sqlite3_column_text(stmt, 0));
-
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- LOG_ER("Expected 1 row got more then 1 row (line: %u)", __LINE__);
- badfile = true;
- goto bailout;
- }
- sqlite3_reset(stmt);
-
- TRACE_2("Successfully accessed classes class_id:%d class_name:'%s'",
class_id,
- class_name.c_str());
-
- /* Fourth delete the base attribute tuple from table 'classname' for obj_id.
- */
- sql.append(class_name);
- sql.append("\" where obj_id = ");
- sql.append(object_id_str);
-
- TRACE("GENERATED 4:%s", sql.c_str());
- rc = sqlite3_exec(dbHandle, sql.c_str(), NULL, NULL, &zErr);
- if (rc) {
- LOG_ER("SQL statement ('%s') failed because:\n %s", sql.c_str(), zErr);
- sqlite3_free(zErr);
+ preparedSql[SQL_MEM_DEL_OBJ_REAL_MULTI_ID],
sqlite3_errmsg(dbHandle));
goto bailout;
}
-
TRACE("Deleted %u values", sqlite3_changes(dbHandle));
+ sqlite3_reset(stmt);
- /*
- Fifth delete from objects_int_multi, objects_real_multi, objects_text_multi
- where obj_id ==OBJ_ID
- */
- stmt = preparedStmt[SQL_DEL_OBJ_INT_MULTI_ID];
- if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
- LOG_ER("Failed to bind obj_id with error code: %d", rc);
- goto bailout;
- }
+ stmt = preparedStmt[SQL_MEM_DEL_OBJ_TEXT_MULTI_ID];
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
LOG_ER("SQL statement ('%s') failed because:\n %s",
- preparedSql[SQL_DEL_OBJ_INT_MULTI_ID], sqlite3_errmsg(dbHandle));
+ preparedSql[SQL_MEM_DEL_OBJ_TEXT_MULTI_ID],
sqlite3_errmsg(dbHandle));
goto bailout;
}
TRACE("Deleted %u values", sqlite3_changes(dbHandle));
sqlite3_reset(stmt);
- stmt = preparedStmt[SQL_DEL_OBJ_REAL_MULTI_ID];
- if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
- LOG_ER("Failed to bind obj_id with error code: %d", rc);
- goto bailout;
- }
+ /* remove objects from reverse_dn table */
+ stmt = preparedStmt[SQL_MEM_DEL_REVERSE_DN];
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
LOG_ER("SQL statement ('%s') failed because:\n %s",
- preparedSql[SQL_DEL_OBJ_REAL_MULTI_ID], sqlite3_errmsg(dbHandle));
+ preparedSql[SQL_MEM_DEL_REVERSE_DN], sqlite3_errmsg(dbHandle));
goto bailout;
}
TRACE("Deleted %u values", sqlite3_changes(dbHandle));
sqlite3_reset(stmt);
- stmt = preparedStmt[SQL_DEL_OBJ_TEXT_MULTI_ID];
- if ((rc = sqlite3_bind_int(stmt, 1, object_id)) != SQLITE_OK) {
- LOG_ER("Failed to bind obj_id with error code: %d", rc);
- goto bailout;
- }
+ /* Clean delete_obj table */
+ stmt = preparedStmt[SQL_MEM_DEL_DELETE_OBJ];
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
LOG_ER("SQL statement ('%s') failed because:\n %s",
- preparedSql[SQL_DEL_OBJ_TEXT_MULTI_ID], sqlite3_errmsg(dbHandle));
+ preparedSql[SQL_MEM_DEL_DELETE_OBJ], sqlite3_errmsg(dbHandle));
goto bailout;
}
TRACE("Deleted %u values", sqlite3_changes(dbHandle));
@@ -2486,6 +2818,11 @@ bool objectToPBE(std::string objectNameString, const
SaImmAttrValuesT_2 **attrs,
sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);
+ if(!reverseAndInsertDn(dbHandle, objectNameString, object_id)) {
+ LOG_ER("Failed to insert reverse DN");
+ goto bailout;
+ }
+
TRACE_LEAVE();
return true;
bailout:
diff --git a/src/imm/immnd/ImmModel.cc b/src/imm/immnd/ImmModel.cc
index 16fd4d8..44069c3 100644
--- a/src/imm/immnd/ImmModel.cc
+++ b/src/imm/immnd/ImmModel.cc
@@ -2476,6 +2476,7 @@ void ImmModel::pbePrtoPurgeMutations(unsigned int nodeId,
ContinuationMap2::iterator ci;
ImmAttrValueMap::iterator oavi;
ObjectInfo* afim = NULL;
+ std::set<SaUint32T> connSet;
TRACE_ENTER();
bool dummy = false;
bool dummy2 = false;
@@ -2504,7 +2505,11 @@ void ImmModel::pbePrtoPurgeMutations(unsigned int nodeId,
be the only proper reply, so we let the client
timeout by not replying.
*/
- connVector.push_back(ci->second.mConn);
+ if(connSet.find(ci->second.mConn) == connSet.end()) {
+ /* Don't add a connection more that once */
+ connSet.insert(ci->second.mConn);
+ connVector.push_back(ci->second.mConn);
+ }
}
sPbeRtReqContinuationMap.erase(ci);
}
@@ -10384,7 +10389,8 @@ SaAisErrorT ImmModel::ccbObjectDelete(
err = deleteObject(oi, reqConn, adminOwner, ccb, doIt, objNameVector,
connVector, continuations,
- pbeConnPtr ? (*pbeConnPtr) : 0, &readLockedObject);
+ pbeConnPtr ? (*pbeConnPtr) : 0, &readLockedObject,
+ true);
if (err == SA_AIS_OK && readLockedObject != NULL) {
safeReadObjSet.insert(readLockedObject);
@@ -10406,7 +10412,8 @@ SaAisErrorT ImmModel::ccbObjectDelete(
--childCount;
err = deleteObject(oi2, reqConn, adminOwner, ccb, doIt,
objNameVector,
connVector, continuations,
- pbeConnPtr ? (*pbeConnPtr) : 0,
&readLockedObject);
+ pbeConnPtr ? (*pbeConnPtr) : 0, &readLockedObject,
+ false);
if (err == SA_AIS_OK && readLockedObject != NULL) {
safeReadObjSet.insert(readLockedObject);
}
@@ -10437,7 +10444,8 @@ SaAisErrorT ImmModel::deleteObject(ObjectMap::iterator&
oi, SaUint32T reqConn,
ConnVector& connVector,
IdVector& continuations,
unsigned int pbeIsLocal,
- ObjectInfo** readLockedObject) {
+ ObjectInfo** readLockedObject,
+ bool sendToPbe) {
/*TRACE_ENTER();*/
bool configObj = true;
std::string objAdminOwnerName;
@@ -10738,7 +10746,7 @@ SaAisErrorT ImmModel::deleteObject(ObjectMap::iterator&
oi, SaUint32T reqConn,
if (nonPersistentRto) {
TRACE_7("Not incrementing op-count for ccb delete of non-persistent
RTO");
- } else {
+ } else if(sendToPbe) {
ccb->mOpCount++;
}
diff --git a/src/imm/immnd/ImmModel.h b/src/imm/immnd/ImmModel.h
index 9e4c54a..8657f7c 100644
--- a/src/imm/immnd/ImmModel.h
+++ b/src/imm/immnd/ImmModel.h
@@ -219,7 +219,8 @@ class ImmModel {
ObjectNameVector& objNameVector,
ConnVector& connVector, IdVector& continuations,
unsigned int pbeIsLocal,
- ObjectInfo** readLockedObject);
+ ObjectInfo** readLockedObject,
+ bool sendToPbe);
void setCcbErrorString(CcbInfo* ccb, const char* errorString, va_list vl);
diff --git a/src/imm/immnd/immnd_evt.c b/src/imm/immnd/immnd_evt.c
index 52d33dc..47f10d6 100644
--- a/src/imm/immnd/immnd_evt.c
+++ b/src/imm/immnd/immnd_evt.c
@@ -8281,15 +8281,6 @@ static void immnd_evt_proc_object_delete(IMMND_CB *cb,
IMMND_EVT *evt,
osafassert(pbeNodeId);
osafassert(pbeNodeId == cb->node_id);
implHandle = m_IMMSV_PACK_HANDLE(pbeConn, pbeNodeId);
- memset(&send_evt, '\0', sizeof(IMMSV_EVT));
- send_evt.type = IMMSV_EVT_TYPE_IMMA;
- /* PBE is internal => can handle long DNs */
- send_evt.info.imma.type = IMMA_EVT_ND2A_OI_OBJ_DELETE_UC;
- send_evt.info.imma.info.objDelete.ccbId =
- evt->info.objDelete.ccbId;
- send_evt.info.imma.info.objDelete.immHandle = implHandle;
- send_evt.info.imma.info.objDelete.adminOwnerId =
- 0; /* No reply!*/
/*Fetch client node for PBE */
immnd_client_node_get(cb, implHandle, &oi_cl_node);
@@ -8314,28 +8305,35 @@ static void immnd_evt_proc_object_delete(IMMND_CB *cb,
IMMND_EVT *evt,
upcalls are generated for cached non-persistent
runtime objects that are delete as a side effect.
*/
- int ix = 0;
- for (; ix < arrSize && err == SA_AIS_OK; ++ix) {
- send_evt.info.imma.info.objDelete.objectName
- .size =
- (SaUint32T)strlen(objNameArr[ix]) + 1;
- send_evt.info.imma.info.objDelete.objectName
- .buf = objNameArr[ix];
- TRACE_2(
- "MAKING PBE-IMPLEMENTER OBJ DELETE upcall");
- if (immnd_mds_msg_send(
- cb, NCSMDS_SVC_ID_IMMA_OI,
- oi_cl_node->agent_mds_dest,
- &send_evt) != NCSCC_RC_SUCCESS) {
- LOG_ER(
- "Immnd upcall over MDS for
ccbObjectDelete "
- "to PBE failed! - aborting ccb %u",
- evt->info.objDelete.ccbId);
- err = SA_AIS_ERR_FAILED_OPERATION;
- immnd_proc_global_abort_ccb(
- cb, evt->info.objDelete.ccbId);
- }
+ /* PBE will handle children objects */
+ memset(&send_evt, '\0', sizeof(IMMSV_EVT));
+ send_evt.type = IMMSV_EVT_TYPE_IMMA;
+ /* PBE is internal => can handle long DNs */
+ send_evt.info.imma.type =
IMMA_EVT_ND2A_OI_OBJ_DELETE_UC;
+ send_evt.info.imma.info.objDelete.ccbId =
+ evt->info.objDelete.ccbId;
+ send_evt.info.imma.info.objDelete.immHandle =
implHandle;
+ send_evt.info.imma.info.objDelete.adminOwnerId =
+ 0; /* No reply!*/
+ send_evt.info.imma.info.objDelete.objectName
+ .size = evt->info.objDelete.objectName.size;
+ send_evt.info.imma.info.objDelete.objectName
+ .buf = evt->info.objDelete.objectName.buf;
+
+ TRACE_2(
+ "MAKING PBE-IMPLEMENTER OBJ DELETE upcall");
+ if (immnd_mds_msg_send(
+ cb, NCSMDS_SVC_ID_IMMA_OI,
+ oi_cl_node->agent_mds_dest,
+ &send_evt) != NCSCC_RC_SUCCESS) {
+ LOG_ER(
+ "Immnd upcall over MDS for ccbObjectDelete "
+ "to PBE failed! - aborting ccb %u",
+ evt->info.objDelete.ccbId);
+ err = SA_AIS_ERR_FAILED_OPERATION;
+ immnd_proc_global_abort_ccb(
+ cb, evt->info.objDelete.ccbId);
}
}
} /* End of PersistentBackEnd handling. */
@@ -8700,16 +8698,6 @@ static void immnd_evt_proc_rt_object_delete(IMMND_CB
*cb, IMMND_EVT *evt,
osafassert(cb->mIsCoord);
osafassert(pbeNodeId == cb->node_id);
implHandle = m_IMMSV_PACK_HANDLE(pbeConn, pbeNodeId);
- memset(&send_evt, '\0', sizeof(IMMSV_EVT));
- send_evt.type = IMMSV_EVT_TYPE_IMMA;
- /* PBE is internal => can handle long DNs */
- send_evt.info.imma.type =
- IMMA_EVT_ND2A_OI_OBJ_DELETE_UC;
- send_evt.info.imma.info.objDelete.ccbId = 0;
- send_evt.info.imma.info.objDelete.adminOwnerId =
- continuationId;
- send_evt.info.imma.info.objDelete.immHandle =
- implHandle;
/*Fetch client node for PBE */
immnd_client_node_get(cb, implHandle, &pbe_cl_node);
@@ -8726,52 +8714,60 @@ static void immnd_evt_proc_rt_object_delete(IMMND_CB
*cb, IMMND_EVT *evt,
goto done;
} else {
/* We have obtained PBE handle & dest info for
- PBE. Iterate through objNameArray and send
- delete upcalls to PBE.
+ PBE. Send delete upcalls to PBE.
*/
- int ix = 0;
- for (; ix < arrSize && err == SA_AIS_OK; ++ix) {
- send_evt.info.imma.info.objDelete
- .objectName.size =
- (SaUint32T)strlen(objNameArr[ix]) +
- 1;
- send_evt.info.imma.info.objDelete
- .objectName.buf = objNameArr[ix];
+ memset(&send_evt, '\0', sizeof(IMMSV_EVT));
+ send_evt.type = IMMSV_EVT_TYPE_IMMA;
+ /* PBE is internal => can handle long DNs */
+ send_evt.info.imma.type =
+ IMMA_EVT_ND2A_OI_OBJ_DELETE_UC;
+ send_evt.info.imma.info.objDelete.ccbId = 0;
+ send_evt.info.imma.info.objDelete.adminOwnerId =
+ continuationId;
+ send_evt.info.imma.info.objDelete.immHandle =
+ implHandle;
- TRACE_2(
- "MAKING PBE-IMPLEMENTER PERSISTENT
RT-OBJ DELETE upcalls");
- if (immnd_mds_msg_send(
- cb, NCSMDS_SVC_ID_IMMA_OI,
- pbe_cl_node->agent_mds_dest,
- &send_evt) !=
- NCSCC_RC_SUCCESS) {
- LOG_WA(
- "Upcall over MDS for
persistent rt obj delete "
- "to PBE failed!");
- /* TODO: we could possibly
- revert the delete here an
- return TRY_AGAIN. We may have
- succeeded in sending some
- deletes, but since we did not
- send the completed, the PRTO
- deletes will not be commited
- by the PBE.
- */
- goto done;
- }
+ send_evt.info.imma.info.objDelete
+ .objectName.size =
evt->info.objDelete.objectName.size;
+ send_evt.info.imma.info.objDelete
+ .objectName.buf =
evt->info.objDelete.objectName.buf;
+
+ if (immnd_mds_msg_send(
+ cb, NCSMDS_SVC_ID_IMMA_OI,
+ pbe_cl_node->agent_mds_dest,
+ &send_evt) !=
+ NCSCC_RC_SUCCESS) {
+ LOG_WA(
+ "Upcall over MDS for persistent
rt obj delete "
+ "to PBE failed!");
+ /* TODO: we could possibly
+ revert the delete here an
+ return TRY_AGAIN. We may have
+ succeeded in sending some
+ deletes, but since we did not
+ send the completed, the PRTO
+ deletes will not be commited
+ by the PBE.
+ */
+ goto done;
}
+ memset(&send_evt, '\0', sizeof(IMMSV_EVT));
send_evt.info.imma.type =
IMMA_EVT_ND2A_OI_CCB_COMPLETED_UC;
send_evt.info.imma.info.ccbCompl.ccbId = 0;
send_evt.info.imma.info.ccbCompl.immHandle =
implHandle;
send_evt.info.imma.info.ccbCompl.implId =
- arrSize;
+ 1;
/* ^^Hack: Use implId to store objCount, see
#1809.^^ This avoids having to change the
protocol.
*/
+ /* It will be always 1 for number of delete
objects.
+ * Cascade delete is done on PBE size, and only
+ * parent DN is sent to PBE
+ */
send_evt.info.imma.info.ccbCompl.invocation =
continuationId;
@@ -8801,17 +8797,6 @@ static void immnd_evt_proc_rt_object_delete(IMMND_CB
*cb, IMMND_EVT *evt,
implHandle =
m_IMMSV_PACK_HANDLE(pbe2BConn, cb->node_id);
- memset(&send_evt, '\0', sizeof(IMMSV_EVT));
- send_evt.type = IMMSV_EVT_TYPE_IMMA;
-
- send_evt.info.imma.type =
- IMMA_EVT_ND2A_OI_OBJ_DELETE_UC;
- send_evt.info.imma.info.objDelete.ccbId = 0;
- send_evt.info.imma.info.objDelete.adminOwnerId =
- continuationId;
- send_evt.info.imma.info.objDelete.immHandle =
- implHandle;
-
/*Fetch client node for Slave PBE */
immnd_client_node_get(cb, implHandle, &pbe_cl_node);
osafassert(pbe_cl_node);
@@ -8821,39 +8806,43 @@ static void immnd_evt_proc_rt_object_delete(IMMND_CB
*cb, IMMND_EVT *evt,
goto done;
} else {
/* We have obtained handle & dest info for Slave
- PBE. Iterate through objNameArray and send
- delete upcalls to Slave PBE.
+ PBE. Send delete upcalls to Slave PBE.
*/
- int ix = 0;
- for (; ix < arrSize && err == SA_AIS_OK; ++ix) {
- send_evt.info.imma.info.objDelete
- .objectName.size =
- (SaUint32T)strlen(objNameArr[ix]) +
- 1;
- send_evt.info.imma.info.objDelete
- .objectName.buf = objNameArr[ix];
+ memset(&send_evt, '\0', sizeof(IMMSV_EVT));
+ send_evt.type = IMMSV_EVT_TYPE_IMMA;
- TRACE_2(
- "MAKING PBE-SLAVE PERSISTENT RT-OBJ
DELETE upcalls");
- if (immnd_mds_msg_send(
- cb, NCSMDS_SVC_ID_IMMA_OI,
- pbe_cl_node->agent_mds_dest,
- &send_evt) !=
- NCSCC_RC_SUCCESS) {
- LOG_WA(
- "Upcall over MDS for
persistent rt obj delete "
- "to Slave PBE failed!");
- /* TODO: we could possibly
- revert the delete here an
- return TRY_AGAIN. We may have
- succeeded in sending some
- deletes, but since we did not
- send the completed, the PRTO
- deletes will not be commited
- by the PBE.
- */
- goto done;
- }
+ send_evt.info.imma.type =
+ IMMA_EVT_ND2A_OI_OBJ_DELETE_UC;
+ send_evt.info.imma.info.objDelete.ccbId = 0;
+ send_evt.info.imma.info.objDelete.adminOwnerId =
+ continuationId;
+ send_evt.info.imma.info.objDelete.immHandle =
+ implHandle;
+ send_evt.info.imma.info.objDelete
+ .objectName.size =
evt->info.objDelete.objectName.size;
+ send_evt.info.imma.info.objDelete
+ .objectName.buf =
evt->info.objDelete.objectName.buf;
+
+ TRACE_2(
+ "MAKING PBE-SLAVE PERSISTENT RT-OBJ
DELETE upcalls");
+ if (immnd_mds_msg_send(
+ cb, NCSMDS_SVC_ID_IMMA_OI,
+ pbe_cl_node->agent_mds_dest,
+ &send_evt) !=
+ NCSCC_RC_SUCCESS) {
+ LOG_WA(
+ "Upcall over MDS for persistent
rt obj delete "
+ "to Slave PBE failed!");
+ /* TODO: we could possibly
+ revert the delete here an
+ return TRY_AGAIN. We may have
+ succeeded in sending some
+ deletes, but since we did not
+ send the completed, the PRTO
+ deletes will not be commited
+ by the PBE.
+ */
+ goto done;
}
}
implHandle = 0LL;
--
1.9.1
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel