Bug 434805: work harder to recover from url-classifier db corruption. r=tony FENNEC_M4
☠☠ backed out by 1d34b3c0cb89 ☠ ☠
authorDave Camp <dcamp@mozilla.com>
Wed, 25 Jun 2008 20:23:57 -0700
changeset 15547 caeba7562e495a9f604984df0b48b6f99bec3e2e
parent 15546 39d0829ed9e2135163e536302a220b665e916515
child 15548 1d34b3c0cb89b010d94b6a1be32f51b0850db874
push id304
push userdcamp@mozilla.com
push dateThu, 26 Jun 2008 03:24:11 +0000
treeherdermozilla-central@caeba7562e49 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstony
bugs434805
milestone1.9.1a1pre
Bug 434805: work harder to recover from url-classifier db corruption. r=tony
toolkit/components/url-classifier/src/Makefile.in
toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp
--- a/toolkit/components/url-classifier/src/Makefile.in
+++ b/toolkit/components/url-classifier/src/Makefile.in
@@ -26,16 +26,17 @@ CPPSRCS = \
           nsUrlClassifierDBService.cpp \
           nsUrlClassifierStreamUpdater.cpp \
           nsUrlClassifierUtils.cpp \
           nsUrlClassifierHashCompleter.cpp \
           $(NULL)
 
 LOCAL_INCLUDES = \
                  -I$(srcdir)/../../build \
+                 $(SQLITE_CFLAGS) \
                  $(NULL)
 
 
 # Same as JS components that are run through the pre-processor.
 EXTRA_PP_COMPONENTS = nsUrlClassifierLib.js \
                       nsUrlClassifierListManager.js \
                       $(NULL)
 
--- a/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp
@@ -72,16 +72,19 @@
 #include "nsThreadUtils.h"
 #include "nsXPCOMStrings.h"
 #include "prlog.h"
 #include "prlock.h"
 #include "prprf.h"
 #include "prnetdb.h"
 #include "zlib.h"
 
+// Needed to interpert mozIStorageConnection::GetLastError
+#include <sqlite3.h>
+
 /**
  * The DBServices stores a set of Fragments.  A fragment is one URL
  * fragment containing two or more domain components and some number
  * of path components.
  *
  * Fragment examples:
  *   example.com/
  *   www.example.com/foo/bar
@@ -3051,48 +3054,53 @@ nsUrlClassifierDBServiceWorker::FinishUp
 {
   LOG(("nsUrlClassifierDBServiceWorker::FinishUpdate()"));
   if (gShuttingDownThread)
     return NS_ERROR_NOT_INITIALIZED;
 
   NS_ENSURE_STATE(!mInStream);
   NS_ENSURE_STATE(mUpdateObserver);
 
+  // We need to get the error code before ApplyUpdate, because it might
+  // close/open the connection.
+  PRInt32 errcode = SQLITE_OK;
+  mConnection->GetLastError(&errcode);
+
   ApplyUpdate();
 
   if (NS_SUCCEEDED(mUpdateStatus)) {
     mUpdateObserver->UpdateSuccess(mUpdateWait);
   } else {
     mUpdateObserver->UpdateError(mUpdateStatus);
   }
 
-  if (!mResetRequested) {
+  // It's important that we only reset the database on an update
+  // command if the update was successful, otherwise unauthenticated
+  // updates could cause a database reset.
+  PRBool resetDB = (NS_SUCCEEDED(mUpdateStatus) && mResetRequested) ||
+                    errcode == SQLITE_CORRUPT;
+
+  if (!resetDB) {
     if (NS_SUCCEEDED(mUpdateStatus)) {
       PRInt64 now = (PR_Now() / PR_USEC_PER_SEC);
       for (PRUint32 i = 0; i < mUpdateTables.Length(); i++) {
         LOG(("Successfully updated %s", mUpdateTables[i].get()));
         mTableFreshness.Put(mUpdateTables[i], now);
       }
     } else {
       for (PRUint32 i = 0; i < mUpdateTables.Length(); i++) {
         LOG(("Failed updating %s", mUpdateTables[i].get()));
         mTableFreshness.Remove(mUpdateTables[i]);
       }
     }
   }
 
-  // ResetUpdate() clears mResetRequested...
-  PRBool resetRequested = mResetRequested;
-
   ResetUpdate();
 
-  // It's important that we only reset the database if the update was
-  // successful, otherwise unauthenticated updates could cause a
-  // database reset.
-  if (NS_SUCCEEDED(mUpdateStatus) && resetRequested) {
+  if (resetDB) {
     ResetDatabase();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsUrlClassifierDBServiceWorker::ResetDatabase()