Bug 1124126 - Retry database connection for the case of corrupted permissions.sqlite. r=bsmedberg, a=jocheng
authorRex Hung <rhung@mozilla.com>
Thu, 21 May 2015 11:56:11 +0800
changeset 238456 fd7b06b22d0084beee052712b140365351d7a44c
parent 238455 01ff28063f841d6dfe3b483a09b97c17acc6ff29
child 238457 ea23ecdeb6e82a6a824837573b21a82a25040a5e
push id630
push userryanvm@gmail.com
push dateThu, 21 May 2015 22:22:58 +0000
treeherdermozilla-b2g37_v2_2@fd7b06b22d00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, jocheng
bugs1124126
milestone37.0
Bug 1124126 - Retry database connection for the case of corrupted permissions.sqlite. r=bsmedberg, a=jocheng
extensions/cookie/nsPermissionManager.cpp
toolkit/components/telemetry/Histograms.json
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -31,16 +31,18 @@
 #include "nsIAppsService.h"
 #include "mozIApplication.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocument.h"
 #include "mozilla/net/NeckoMessageUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsReadLine.h"
+#include "mozilla/Telemetry.h"
+#include "nsIConsoleService.h"
 
 static nsPermissionManager *gPermissionManager = nullptr;
 
 using mozilla::dom::ContentParent;
 using mozilla::dom::ContentChild;
 using mozilla::unused; // ha!
 
 static bool
@@ -61,16 +63,28 @@ ChildProcess()
     if (!cpc)
       NS_RUNTIMEABORT("Content Process is nullptr!");
     return cpc;
   }
 
   return nullptr;
 }
 
+static void
+LogToConsole(const nsAString& aMsg)
+{
+  nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
+  if (!console) {
+    NS_WARNING("Failed to log message to console.");
+    return;
+  }
+
+  nsAutoString msg(aMsg);
+  console->LogStringMessage(msg.get());
+}
 
 #define ENSURE_NOT_CHILD_PROCESS_(onError) \
   PR_BEGIN_MACRO \
   if (IsChildProcess()) { \
     NS_ERROR("Cannot perform action in content process!"); \
     onError \
   } \
   PR_END_MACRO
@@ -469,39 +483,62 @@ nsPermissionManager::InitDB(bool aRemove
   }
 
   nsCOMPtr<mozIStorageService> storage = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
   if (!storage)
     return NS_ERROR_UNEXPECTED;
 
   // cache a connection to the hosts database
   rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (rv == NS_ERROR_FILE_CORRUPTED) {
+    LogToConsole(NS_LITERAL_STRING("permissions.sqlite is corrupted! Try again!"));
+
+    // Add telemetry probe
+    mozilla::Telemetry::Accumulate(mozilla::Telemetry::PERMISSIONS_SQL_CORRUPTED, 1);
+
+    // delete corrupted permissions.sqlite and try again
+    rv = permissionsFile->Remove(false);
+    NS_ENSURE_SUCCESS(rv, rv);
+    LogToConsole(NS_LITERAL_STRING("Corrupted permissions.sqlite has been removed."));
+
+    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
+    NS_ENSURE_SUCCESS(rv, rv);
+    LogToConsole(NS_LITERAL_STRING("OpenDatabase to permissions.sqlite is successful!"));
+  }
 
   bool ready;
   mDBConn->GetConnectionReady(&ready);
   if (!ready) {
+    LogToConsole(NS_LITERAL_STRING("Fail to get connection to permissions.sqlite! Try again!"));
+
     // delete and try again
     rv = permissionsFile->Remove(false);
     NS_ENSURE_SUCCESS(rv, rv);
+    LogToConsole(NS_LITERAL_STRING("Defective permissions.sqlite has been removed."));
+
+    // Add telemetry probe
+    mozilla::Telemetry::Accumulate(mozilla::Telemetry::DEFECTIVE_PERMISSIONS_SQL_REMOVED, 1);
 
     rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
     NS_ENSURE_SUCCESS(rv, rv);
+    LogToConsole(NS_LITERAL_STRING("OpenDatabase to permissions.sqlite is successful!"));
 
     mDBConn->GetConnectionReady(&ready);
     if (!ready)
       return NS_ERROR_UNEXPECTED;
   }
 
+  LogToConsole(NS_LITERAL_STRING("Get a connection to permissions.sqlite."));
+
   bool tableExists = false;
   mDBConn->TableExists(NS_LITERAL_CSTRING("moz_hosts"), &tableExists);
   if (!tableExists) {
     rv = CreateTable();
     NS_ENSURE_SUCCESS(rv, rv);
-
+    LogToConsole(NS_LITERAL_STRING("DB table(moz_hosts) is created!"));
   } else {
     // table already exists; check the schema version before reading
     int32_t dbSchemaVersion;
     rv = mDBConn->GetSchemaVersion(&dbSchemaVersion);
     NS_ENSURE_SUCCESS(rv, rv);
 
     switch (dbSchemaVersion) {
     // upgrading.
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7309,10 +7309,20 @@
     "high": 500,
     "n_buckets": 5,
     "description": "The number of Sync 1.5 'complete upgrade/migration' notifications offered by Android Sync."
   },
   "FENNEC_SYNC11_MIGRATIONS_COMPLETED": {
     "expires_in_version": "45",
     "kind": "count",
     "description": "The number of Sync 1.5 migrations completed by Android Sync."
+  },
+  "PERMISSIONS_SQL_CORRUPTED": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Record the permissions.sqlite init failure"
+  },
+  "DEFECTIVE_PERMISSIONS_SQL_REMOVED": {
+    "expires_in_version": "never",
+    "kind": "count",
+    "description": "Record the removal of defective permissions.sqlite"
   }
 }