osaf/libs/common/immsv/immpbe_dump.cc            |  66 +++++++++++++----------
 osaf/libs/common/immsv/include/immpbe_dump.hh    |  10 +-
 osaf/services/saf/immsv/immpbed/immpbe.cc        |  32 +++++++++-
 osaf/services/saf/immsv/immpbed/immpbe_daemon.cc |   8 ++-
 osaf/tools/safimm/immdump/imm_dumper.cc          |  19 +++++-
 5 files changed, 91 insertions(+), 44 deletions(-)


Symptoms of the problem are dropped imm.db.xxxxxx files, mkstemp(3), and
imm.db.xxxxxx-journal files. The journal files are actually consistently dropped
as empty files even on successfull generation of imm.db.

The cause is simply an omission to unlink the temp file when exiting on error 
and
the fact that that sqlite never unlinks the journal file when journaling mode is
TRUNCATE. The journaling mode was altered for PBE a few years ago.

Solution is to catch all cases of controlled exit of PBE during the generation 
of
the temporary imm.db file and unlink these files before exiting. This ticket 
does
not take care of cleaning up files dropped by an uncontrolled crash of PBE.
To solve that problem safely and reliably we need to create all temporary imm.db
files in a sub directory to the configured IMMSV_PBE_TMP_DIR in immnd.conf. That
is a change of file representation that is more risky, needs more righorous 
sytem
testing and will thus be added as an enhancement.

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
@@ -463,6 +463,10 @@ void pbeAtomicSwitchFile(const char* fil
 
        if(!localTmpFilename.empty()) {
                int rc=(-1);
+               std::string localTmpJournalFileName(localTmpFilename);
+               localTmpJournalFileName.append("-journal");
+               unlink(localTmpJournalFileName.c_str()); /* Should be an 
existing but empty file. */
+
                std::string shellCommand("/bin/cp ");
                shellCommand.append(localTmpFilename);
                shellCommand.append(" ");
@@ -775,6 +779,13 @@ void* pbeRepositoryInit(const char* file
        if(badfile) {
                discardPbeFile(std::string(filePath));
        }
+       if(!localTmpFilename.empty()) {
+               std::string localTmpJournalFileName(localTmpFilename);
+               localTmpJournalFileName.append("-journal");
+               unlink(localTmpJournalFileName.c_str());
+               unlink(localTmpFilename.c_str());
+               localTmpFilename.clear();
+       }
        TRACE_LEAVE();
        return NULL;
 }
@@ -1985,7 +1996,7 @@ unsigned int purgeInstancesOfClassToPBE(
        exit(1);        
 }
 
-unsigned int dumpInstancesOfClassToPBE(SaImmHandleT immHandle, ClassMap 
*classIdMap,
+int dumpInstancesOfClassToPBE(SaImmHandleT immHandle, ClassMap *classIdMap,
        std::string className, unsigned int* objIdCount, void* db_handle)
 {
        unsigned int obj_count=0;
@@ -2041,12 +2052,12 @@ unsigned int dumpInstancesOfClassToPBE(S
 
                assert(attrs[0] != NULL);
 
-               objectToPBE(std::string((const char*)objectName.value),
-                       (const SaImmAttrValuesT_2**) attrs, classIdMap, 
dbHandle, 
-                       ++(*objIdCount), (SaImmClassNameT) className.c_str(), 
0);
+               if(!objectToPBE(std::string((const char*)objectName.value),
+                       (const SaImmAttrValuesT_2**) attrs, classIdMap, 
dbHandle,
+                       ++(*objIdCount), (SaImmClassNameT) className.c_str(), 
0)) 
+               {goto bailout;}
 
                ++obj_count;
-
        } while (true);
 
        if (SA_AIS_ERR_NOT_EXIST != errorCode)
@@ -2061,8 +2072,7 @@ unsigned int dumpInstancesOfClassToPBE(S
        return obj_count;
  bailout:
        sqlite3_close(dbHandle);
-       LOG_ER("Exiting (line:%u)", __LINE__);
-       exit(1);
+       return(-1);
 }
 
 
@@ -2236,7 +2246,7 @@ void objectDeleteToPBE(std::string objec
        exit(1);
 }
 
-void objectToPBE(std::string objectNameString,
+bool objectToPBE(std::string objectNameString,
        const SaImmAttrValuesT_2** attrs,
        ClassMap *classIdMap,
        void* db_handle,
@@ -2375,14 +2385,13 @@ void objectToPBE(std::string objectNameS
        sqlite3_clear_bindings(stmt);
 
        TRACE_LEAVE();
-       return;
+       return true;
  bailout:
        sqlite3_close(dbHandle);
-       LOG_ER("Exiting (line:%u)", __LINE__);
-       exit(1);
+       return false;
 }
 
-void dumpClassesToPbe(SaImmHandleT immHandle, ClassMap *classIdMap,
+bool dumpClassesToPbe(SaImmHandleT immHandle, ClassMap *classIdMap,
        void* db_handle)
 {
        std::list<std::string> classNameList;
@@ -2421,15 +2430,14 @@ void dumpClassesToPbe(SaImmHandleT immHa
        fsyncPbeJournalFile();
 
        TRACE_LEAVE();
-       return;
+       return true;
 
  bailout:
        sqlite3_close(dbHandle);
-       LOG_ER("Exiting (line:%u)", __LINE__);
-       exit(1);        
+       return false;
 }
 
-unsigned int verifyPbeState(SaImmHandleT immHandle, ClassMap *classIdMap, 
void* db_handle)
+int verifyPbeState(SaImmHandleT immHandle, ClassMap *classIdMap, void* 
db_handle)
 {
        /* Function used only when re-connecting to an already existing DB 
file. */
        std::list<std::string> classNameList;
@@ -2438,7 +2446,7 @@ unsigned int verifyPbeState(SaImmHandleT
        char *execErr=NULL;     
        sqlite3* dbHandle = (sqlite3 *) db_handle;
        std::string sqlQ("SELECT MAX(obj_id) FROM objects");
-       unsigned int obj_count;
+       int obj_count=0;
        char **result=NULL;
        char *qErr=NULL;
        int nrows=0;
@@ -2509,7 +2517,7 @@ unsigned int verifyPbeState(SaImmHandleT
        return 0;
 }
 
-unsigned int dumpObjectsToPbe(SaImmHandleT immHandle, ClassMap* classIdMap,
+int dumpObjectsToPbe(SaImmHandleT immHandle, ClassMap* classIdMap,
        void* db_handle)
 {
        int                    rc=0;
@@ -2583,9 +2591,12 @@ unsigned int dumpObjectsToPbe(SaImmHandl
                        continue;
                }
 
-               objectToPBE(std::string((char*)objectName.value, 
objectName.length),
+               if(!objectToPBE(std::string((char*)objectName.value, 
objectName.length),
                        (const SaImmAttrValuesT_2**) attrs, classIdMap, 
dbHandle, ++object_id, 
-                       NULL, 0);
+                       NULL, 0)) {
+                       goto bailout;
+               }
+
        } while (true);
 
        if (SA_AIS_ERR_NOT_EXIST != errorCode)
@@ -2610,8 +2621,7 @@ unsigned int dumpObjectsToPbe(SaImmHandl
        return object_id; /* == number of dumped objects */
  bailout:
        sqlite3_close(dbHandle);
-       LOG_ER("Exiting (line:%u)", __LINE__);
-       exit(1);
+       return(-1);
 }
 
 SaAisErrorT pbeBeginTrans(void* db_handle)
@@ -2953,7 +2963,7 @@ void pbeAtomicSwitchFile(const char* fil
        abort();
 }
 
-void dumpClassesToPbe(SaImmHandleT immHandle, ClassMap *classIdMap,
+bool dumpClassesToPbe(SaImmHandleT immHandle, ClassMap *classIdMap,
        void* db_handle)
 {
        abort();
@@ -2965,11 +2975,11 @@ unsigned int purgeInstancesOfClassToPBE(
        return 0;
 }
 
-unsigned int dumpInstancesOfClassToPBE(SaImmHandleT immHandle, ClassMap 
*classIdMap,
+int dumpInstancesOfClassToPBE(SaImmHandleT immHandle, ClassMap *classIdMap,
        std::string className, unsigned int* objIdCount, void* db_handle)
 {
        abort();
-       return 0;
+       return (-1);
 }
 
 int finalizeSqlStatement(void *stmt) {
@@ -2992,7 +3002,7 @@ void deleteClassToPBE(std::string classN
        abort();
 }
 
-unsigned int dumpObjectsToPbe(SaImmHandleT immHandle, ClassMap* classIdMap,
+int dumpObjectsToPbe(SaImmHandleT immHandle, ClassMap* classIdMap,
        void* db_handle)
 {
        abort();
@@ -3042,7 +3052,7 @@ void objectModifyDiscardMatchingValuesOf
        abort();
 }
 
-void objectToPBE(std::string objectNameString,
+bool objectToPBE(std::string objectNameString,
        const SaImmAttrValuesT_2** attrs,
        ClassMap *classIdMap,
        void* db_handle,
@@ -3058,7 +3068,7 @@ SaAisErrorT getCcbOutcomeFromPbe(void* d
        return SA_AIS_ERR_LIBRARY;
 }
 
-unsigned int verifyPbeState(SaImmHandleT immHandle, ClassMap *classIdMap, 
void* db_handle)
+int verifyPbeState(SaImmHandleT immHandle, ClassMap *classIdMap, void* 
db_handle)
 {
        abort();
        return 0;
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
@@ -64,11 +64,11 @@ std::string valueToString(SaImmAttrValue
 void* pbeRepositoryInit(const char* filePath, bool create, std::string& 
localTmpFilename);
 void pbeAtomicSwitchFile(const char* filePath, std::string localTmpFilename);
 void pbeRepositoryClose(void* dbHandle);
-void dumpClassesToPbe(SaImmHandleT immHandle, ClassMap *classIdMap,
+bool dumpClassesToPbe(SaImmHandleT immHandle, ClassMap *classIdMap,
        void* db_handle);
 
 unsigned int purgeInstancesOfClassToPBE(SaImmHandleT immHandle, std::string 
className, void* db_handle);
-unsigned int dumpInstancesOfClassToPBE(SaImmHandleT immHandle, ClassMap 
*classIdMap,
+int dumpInstancesOfClassToPBE(SaImmHandleT immHandle, ClassMap *classIdMap,
        std::string className, unsigned int* objidCount, void* db_handle);
 
 ClassInfo* classToPBE(std::string classNameString, SaImmHandleT immHandle,
@@ -77,12 +77,12 @@ ClassInfo* classToPBE(std::string classN
 void deleteClassToPBE(std::string classNameString, void* db_handle,
        ClassInfo* theClass);
 
-unsigned int verifyPbeState(SaImmHandleT immHandle, ClassMap *classIdMap,
+int verifyPbeState(SaImmHandleT immHandle, ClassMap *classIdMap,
        void* db_handle);
 
-unsigned int dumpObjectsToPbe(SaImmHandleT immHandle, ClassMap* classIdMap,
+int dumpObjectsToPbe(SaImmHandleT immHandle, ClassMap* classIdMap,
        void* db_handle);
-void objectToPBE(std::string objectNameString,
+bool objectToPBE(std::string objectNameString,
        const SaImmAttrValuesT_2** attrs,
        ClassMap* classIdMap, void* db_handle, unsigned int object_id,
        SaImmClassNameT className,
diff --git a/osaf/services/saf/immsv/immpbed/immpbe.cc 
b/osaf/services/saf/immsv/immpbed/immpbe.cc
--- a/osaf/services/saf/immsv/immpbed/immpbe.cc
+++ b/osaf/services/saf/immsv/immpbed/immpbe.cc
@@ -112,7 +112,7 @@ int main(int argc, char* argv[])
        const char* dump_trace_label = "osafimmpbed";
        const char* trace_label = dump_trace_label;
        ClassMap classIdMap;
-       unsigned int objCount=0;
+       int objCount=0;
        bool fileReOpened=false;
 
        unsigned int            retryInterval = 1000000;        /* 1 sec */
@@ -215,7 +215,7 @@ int main(int argc, char* argv[])
                if(dbHandle) {
                        objCount = verifyPbeState(immHandle, &classIdMap, 
dbHandle);
                        TRACE("Classes Verified");
-                       if(!objCount) {dbHandle = NULL;}
+                       if(objCount <= 0) {dbHandle = NULL;}
                }
 
                if(!dbHandle) {
@@ -234,14 +234,36 @@ int main(int argc, char* argv[])
                if(dbHandle) {
                        TRACE_1("Opened persistent repository %s", 
filename.c_str());
                } else {
-                       LOG_WA("osafimmpbed: pbe intialize failed - exiting");
+                       /* Any localTmpFile was removed in pbeRepositoryInit */
+                       LOG_ER("osafimmpbed: pbe intialize failed - exiting");
                        exit(1);
                }
 
-               dumpClassesToPbe(immHandle, &classIdMap, dbHandle);
+               if(!dumpClassesToPbe(immHandle, &classIdMap, dbHandle)) {
+                       if(!localTmpFilename.empty()) {
+                               std::string 
localTmpJournalFileName(localTmpFilename);
+                               localTmpJournalFileName.append("-journal");
+                               unlink(localTmpJournalFileName.c_str());
+                               unlink(localTmpFilename.c_str());
+                               localTmpFilename.clear();
+                       }
+                       LOG_ER("immPbe.cc exiting (line:%u)", __LINE__);
+                       exit(1);
+               }
                TRACE("Dump classes OK");
 
                objCount = dumpObjectsToPbe(immHandle, &classIdMap, dbHandle);
+               if(objCount <= 0) {
+                       if(!localTmpFilename.empty()) {
+                               std::string 
localTmpJournalFileName(localTmpFilename);
+                               localTmpJournalFileName.append("-journal");
+                               unlink(localTmpJournalFileName.c_str());
+                               unlink(localTmpFilename.c_str());
+                               localTmpFilename.clear();
+                       }
+                       LOG_ER("immPbe.cc exiting (line:%u)", __LINE__);
+                       exit(1);
+               }
                TRACE("Dump objects OK");
 
                /* Discard the old classIdMap, will otherwise contain invalid
@@ -263,7 +285,7 @@ int main(int argc, char* argv[])
                   to be used by the pbeDaemon.
                 */
                if(fileReOpened) {
-                       LOG_ER("osafimmpbed: will not re-open twice");
+                       LOG_ER("osafimmpbed: will not re-open twice. immPbe.cc 
exiting (line:%u)", __LINE__);
                        exit(1);
                }
 
diff --git a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc 
b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
--- a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
+++ b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
@@ -101,10 +101,14 @@ static SaAisErrorT sqlite_prepare_ccb(Sa
                                do {
                                        TRACE("Create of object with DN: %s",
                                                
ccbUtilOperationData->objectName.value);
-                                       objectToPBE(std::string((const char *) 
ccbUtilOperationData->objectName.value), 
+                                       if(!objectToPBE(std::string((const char 
*) ccbUtilOperationData->objectName.value), 
                                                
ccbUtilOperationData->param.create.attrValues,
                                                sClassIdMap, sDbHandle, 
++sObjCount,
-                                               
ccbUtilOperationData->param.create.className, ccbId);
+                                               
ccbUtilOperationData->param.create.className, ccbId))
+                                       {
+                                               rc = 
SA_AIS_ERR_FAILED_OPERATION;
+                                               goto ccb_abort;
+                                       }
                                } while (0);
                                break;
 
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
@@ -109,7 +109,7 @@ int main(int argc, char* argv[])
     const char* dump_trace_label = "immdump";
     const char* trace_label = dump_trace_label;
     ClassMap classIdMap;
-    unsigned int objCount=0;
+    int objCount=0;
 
     if ((logPath = getenv("IMMSV_TRACE_PATHNAME")))
     {
@@ -197,11 +197,22 @@ int main(int argc, char* argv[])
             exit(1);
         }
 
-        dumpClassesToPbe(immHandle, &classIdMap, dbHandle);
-        TRACE("Dump classes OK");
+        if(dumpClassesToPbe(immHandle, &classIdMap, dbHandle)) {
+            TRACE("Dump classes OK");
+       } else {
+            std::cerr << "immdump: dumpClassesToPbe failed - exiting, check 
syslog for details"
+                << std::endl;
+            exit(1);
+       }
 
         objCount = dumpObjectsToPbe(immHandle, &classIdMap, dbHandle);
-        TRACE("Dump %u objects OK", objCount);
+       if(objCount > 0) {
+            TRACE("Dump %u objects OK", objCount);
+       } else {
+            std::cerr << "immdump: dumpObjectsToPbe failed - exiting, check 
syslog for details"
+                << std::endl;
+            exit(1);
+       }
 
         /* Discard the old classIdMap, will otherwise contain invalid
            pointer/member 'sqlStmt' after handle close below. */

------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to