Bug 1470811 - Update FF 62 to know about upcoming new quota client; r=asuth a=lizzard
authorJan Varga <jan.varga@gmail.com>
Fri, 29 Jun 2018 09:58:09 +0200
changeset 477838 89c03b4aab112da9d4a0ac3a8d0e4be32315f366
parent 477837 4f29d9433d69f95e01796fd687f7035c267cb62c
child 477839 13622431fb712c21c582fe78b6f1154146b0d7a8
push id9444
push userarchaeopteryx@coole-files.de
push dateSat, 07 Jul 2018 21:01:06 +0000
treeherdermozilla-beta@3c8ab5a011e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth, lizzard
bugs1470811
milestone62.0
Bug 1470811 - Update FF 62 to know about upcoming new quota client; r=asuth a=lizzard
dom/quota/ActorsParent.cpp
dom/quota/Client.h
dom/quota/QuotaManager.h
dom/quota/test/unit/removeLocalStorage1_profile.zip
dom/quota/test/unit/removeLocalStorage2_profile.zip
dom/quota/test/unit/test_removeLocalStorage.js
dom/quota/test/unit/xpcshell.ini
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -203,16 +203,19 @@ enum AppId {
 // The name of the file that we use to load/save the last access time of an
 // origin.
 // XXX We should get rid of old metadata files at some point, bug 1343576.
 #define METADATA_FILE_NAME ".metadata"
 #define METADATA_TMP_FILE_NAME ".metadata-tmp"
 #define METADATA_V2_FILE_NAME ".metadata-v2"
 #define METADATA_V2_TMP_FILE_NAME ".metadata-v2-tmp"
 
+#define LS_ARCHIVE_FILE_NAME "ls-archive.sqlite"
+#define LS_ARCHIVE_TMP_FILE_NAME "ls-archive-tmp.sqlite"
+
 /******************************************************************************
  * SQLite functions
  ******************************************************************************/
 
 int32_t
 MakeStorageVersion(uint32_t aMajorStorageVersion,
                    uint32_t aMinorStorageVersion)
 {
@@ -4821,16 +4824,216 @@ QuotaManager::UpgradeStorageFrom2_0To2_1
   rv = aConnection->SetSchemaVersion(MakeStorageVersion(2, 1));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
+nsresult
+QuotaManager::MaybeRemoveLocalStorageData()
+{
+  AssertIsOnIOThread();
+
+  // Cleanup the tmp file first, if there's any.
+  nsCOMPtr<nsIFile> lsArchiveTmpFile;
+  nsresult rv = NS_NewLocalFile(mStoragePath,
+                                false,
+                                getter_AddRefs(lsArchiveTmpFile));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = lsArchiveTmpFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_TMP_FILE_NAME));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool exists;
+  rv = lsArchiveTmpFile->Exists(&exists);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (exists) {
+    rv = lsArchiveTmpFile->Remove(false);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+  }
+
+  // Now check the real archive file.
+  nsCOMPtr<nsIFile> lsArchiveFile;
+  rv = NS_NewLocalFile(mStoragePath,
+                       false,
+                       getter_AddRefs(lsArchiveFile));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = lsArchiveFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_FILE_NAME));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = lsArchiveFile->Exists(&exists);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (!exists) {
+    // If the ls archive doesn't exist then ls directories can't exist either.
+    return NS_OK;
+  }
+
+  rv = MaybeRemoveLocalStorageDirectories();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  // Finally remove the ls archive, so we don't have to check all origin
+  // directories next time this method is called.
+  rv = lsArchiveFile->Remove(false);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return NS_OK;
+}
+
+nsresult
+QuotaManager::MaybeRemoveLocalStorageDirectories()
+{
+  AssertIsOnIOThread();
+
+  nsCOMPtr<nsIFile> defaultStorageDir;
+  nsresult rv = NS_NewLocalFile(mDefaultStoragePath,
+                                false,
+                                getter_AddRefs(defaultStorageDir));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool exists;
+  rv = defaultStorageDir->Exists(&exists);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (!exists) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsISimpleEnumerator> entries;
+  rv = defaultStorageDir->GetDirectoryEntries(getter_AddRefs(entries));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (!entries) {
+    return NS_OK;
+  }
+
+  while (true) {
+    bool hasMore;
+    rv = entries->HasMoreElements(&hasMore);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!hasMore) {
+      break;
+    }
+
+    nsCOMPtr<nsISupports> entry;
+    rv = entries->GetNext(getter_AddRefs(entry));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    nsCOMPtr<nsIFile> originDir = do_QueryInterface(entry);
+    MOZ_ASSERT(originDir);
+
+    rv = originDir->Exists(&exists);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    MOZ_ASSERT(exists);
+
+    bool isDirectory;
+    rv = originDir->IsDirectory(&isDirectory);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!isDirectory) {
+      nsString leafName;
+      rv = originDir->GetLeafName(leafName);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+
+      // Unknown files during upgrade are allowed. Just warn if we find them.
+      if (!IsOSMetadata(leafName)) {
+        UNKNOWN_FILE_WARNING(leafName);
+      }
+
+      continue;
+    }
+
+    nsCOMPtr<nsIFile> lsDir;
+    rv = originDir->Clone(getter_AddRefs(lsDir));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    rv = lsDir->Append(NS_LITERAL_STRING(LS_DIRECTORY_NAME));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    rv = lsDir->Exists(&exists);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!exists) {
+      continue;
+    }
+
+    rv = lsDir->IsDirectory(&isDirectory);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!isDirectory) {
+      QM_WARNING("ls entry is not a directory!");
+
+      continue;
+    }
+
+    nsString path;
+    rv = lsDir->GetPath(path);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    QM_WARNING("Deleting %s directory!", NS_ConvertUTF16toUTF8(path).get());
+
+    rv = lsDir->Remove(/* aRecursive */ true);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+  }
+
+  return NS_OK;
+}
+
 #ifdef DEBUG
 
 void
 QuotaManager::AssertStorageIsInitialized() const
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mStorageInitialized);
 }
@@ -5000,16 +5203,21 @@ QuotaManager::EnsureStorageIsInitialized
     }
 
     rv = transaction.Commit();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
+  rv = MaybeRemoveLocalStorageData();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
   mStorageInitialized = true;
 
   return NS_OK;
 }
 
 void
 QuotaManager::OpenDirectory(PersistenceType aPersistenceType,
                             const nsACString& aGroup,
--- a/dom/quota/Client.h
+++ b/dom/quota/Client.h
@@ -14,16 +14,17 @@
 #include "PersistenceType.h"
 
 class nsIFile;
 class nsIRunnable;
 
 #define IDB_DIRECTORY_NAME "idb"
 #define ASMJSCACHE_DIRECTORY_NAME "asmjs"
 #define DOMCACHE_DIRECTORY_NAME "cache"
+#define LS_DIRECTORY_NAME "ls"
 
 BEGIN_QUOTA_NAMESPACE
 
 class QuotaManager;
 class UsageInfo;
 
 // An abstract interface for quota manager clients.
 // Each storage API must provide an implementation of this interface in order
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -478,16 +478,22 @@ private:
 
   nsresult
   UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection);
 
   nsresult
   UpgradeStorageFrom2_0To2_1(mozIStorageConnection* aConnection);
 
   nsresult
+  MaybeRemoveLocalStorageData();
+
+  nsresult
+  MaybeRemoveLocalStorageDirectories();
+
+  nsresult
   InitializeRepository(PersistenceType aPersistenceType);
 
   nsresult
   InitializeOrigin(PersistenceType aPersistenceType,
                    const nsACString& aGroup,
                    const nsACString& aOrigin,
                    int64_t aAccessTime,
                    bool aPersisted,
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..19e971433cf24ec2c7420f5cb1bf12a5ac468d55
GIT binary patch
literal 1187
zc$^FHW@h1H00D!^^L!YP00)B%LvcxdQDS<kerO0M19P?W^QZu~=TW5<+zgB?Ul|z~
zSVVy80)QrnfYon`E%#Y|s8Z1wq@9U@fe&GVUU6YgW=Sg8ob$J~M7d&`!_D{Qq>g8(
z$7%gjzB+*hX$eUQDJca30SQ3Bn&ie-)4<8`kvWXbb|&v0fvt-Z1elPl-nsaWk0WQ&
zvl5`S3=ND7vPh24Db`IaO3uhEOVusOEkJgOoTh0s2&1{=?Zt!H%AqpsA3P_Q1#(tM
zep5K{AT{<zn~Lf?q0WeGzN1Sw-8$5?A$6AD?G2OtX3U)RM$YV8y}*Cv{C|@3_Evp(
zbftIc-LUmszkeQ(e)jj?d+YZfpWRmPKb|TioBC5lZ*lK~_61?wcKwSKI9{FpxP5At
z$+|Pyr*G|F$-egc|BN`3eZO=go?K;SzzZ7wH-5f#YVPjW-?N_2@AK!MTsf`3|M>FX
z=O>H*u0NZ8($QwFnCr}^p4<0*JzG#*F7ftlj{Qw(x7*h7eDmG%)fTNUUzEMFKfXL?
zTB@C$h4$n}2aP_5etP5>^7P&O{o%WdzsHrf?KQIVn4JAGd-Bw$jAiEgD{S`c^DarA
zol*Xy<ol_()0Kv&mYw|c_h;(Y-xjvjv3u{Y$y@sI)%S#trym_ZdiWJ90S|0Hnclng
zS%N^@@ycsmmrMQ_&EAr>IdXM<(6r0{7Jsw9+P`T{vB2}W?_XuV-uu^}rYub5XINR3
z+UKI*1s8UoP<>e<bbj(_pWXFW>Nl^ik52yjvG>(u>G^Bcm{#vKn3J+t+IIWZRWaL7
zmG0iUHEp?YTk6EQOFn9N>s#lAt@7D@YRmn#dW$z|G`Vj4QTg%pqvij99mnrph7Z?%
zWNfwM$j0j2z-gsYYp;Hdi>O9*XNL;dovYtUf8`IK9r{~E`tG(nu|E^G-sHTm+5JYP
z*FCbTbmL$30B=SnIc8irQ3A>mV0h~Yq7nI$6_PJ8@+8PKT)9#LZt{{wCxmJ6oWTmo
nqj=23%x(xX8yfc_xe!O@V})cs3@cdKKt?bFAuCX@1Dpo{8C0uF
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..04d1a3462b535b6832db6a47f8d768220d36f725
GIT binary patch
literal 2827
zc$^FHW@h1H00D!^^L!YP00)B%LvcxdQDS<kerO0M19P?W^QZu~=TW5<+zgB?Ul|z~
zSVVy80^lYXp_w3nWI{@6T4HHV3B;rZLMClRGf5GPNf{+21=`x$Ir+(nIT`uIP@_v-
za2hQF_LOmIl}|c<hqw}urv=7D7_FC^T9TNOSds{~Bk|l0Y<46koc(Zm+Ul#R2?-C*
zob>lQbMl0~9%B)Uk(U?OnlE1klaO4&+&j-_S&URB$Q9;5tV@zBbjysu4!LT9)w4i{
zh(&#MbnIf}EqL}sUHw_g6Y=Q`mQ0eWs;ptZesLHgh4gB)kX9kaAvwj6z)m6**dWs%
zclrD;14=PSFfiy7X*$T0dc}n~nI)<CEP6Zbyw_m|fn(*9uXP0oEV<%c$j7Sfwz?un
z->o;O=l>%vG5$o~aOqiQw{l#nH|IaR{8J(B%(VbV!-{R6llR|D`Lyv&3(u2BcfKuc
zxV_>2Qz0{tz5uT>1`frlMK(X3yr+1t51pqr%lG^J3n#Vqh<(+%XzEttoP4XgP5P(!
zo{+6hJ3|&7PCc2=bn($7?Wf;lPN#?&6kp%wkeYQt@ce-_+HC25k8hOBDo8Qqt$5<7
zWA|Bod8c0PZ3g`}_rAM|bc&hy%_z;VeB8bvUv|cHvu0CfCOOZ`pM{h^?^ZgzYs(7%
zsoTA${Mb9KqD!tRg)c_#bV14cRln|(ieBArXZz~)9I;bVxnz$$-j`Qla__7B-<3JM
zhxXM!|Gsbg;#Vc|JH?O3hNp$knpN4)exCWGdwEsK6Mm!kLm3tOnVJ-YT?_@U-uKuf
z!16O*=fa;;SGHW6_Ni`l9KTaP`&)xaD)(pZzGo9XU;ga>AM52DCv+ycvCgSyaTH*g
zsbPl{y_;goeU=}pR5S*q93}<^K1B2)$KLr{TcTVsV~?Bf%Sj#2P><94r+jq+4bl>l
z5>iqM0s<0%fHldDt)_vK<0Eqzo9#^AJpx-7CkQYhS$(%;yN@Gh(z6nvwG0i643bDG
zE2mgDu_!qsvkb)*4-;6UK^Q#^T|Ahr94f>9!E<t1AZLZ-H-!@qQe$tlsi?ja>Ws+d
zJGyk!twT*4QfK+y-Z0s3#>`o7<jlU+3;b8k|0g+bZ`FrKS9+J;4O`Fk`{x1aXMgX#
zw|@We*=_ay<EcWjsXtZp7WY1AUl7J^*S|=C<JIYp+oxuktUHr^`quuH>}$XO&xkYG
z_e(e8$yH_syrAKK<L6ta=I(y|J?r`WK7annmDBqBk1zjyezN%Q`m^aL9c|`{xz2p*
zxqaW)vjxTF5^vw;*x!_PyKNoMH{UH^ZPEJjMcFI+<I8iVrP|q9Xit80(CBmMr$>$<
zPv6boAHKWzdt7PTUL!k?$=NTnCr^FKSZ2Pz!e-At?~>%%8Rb7pzMqOaU1@k~*~w3T
zf2Mx@ZDCs-yZ8Q@yrmyseNXs!`qA;DhhMQ0@WA$y>AhQ@B?z<~ue{cEx#W-0>@8`V
zBUjf4O}qSW@i+Uc{hQVl3p}6u{#Ewty?+gA%EDBBhLuIBeJ=W4aAEfe)t4ng=O>@`
z*<F97e)IbJ=;W^-dtW`4p1)>|Y4u)%IVp>!ZMR=t6|?<R>F%vt)0PXjrB0l?<fDeS
zzI9&MDxck_w%lK<w|JvQlk3JGl^<U}TK@mnas2LO_;Bq<##T#?Y^=@=oK`Be_UhNT
zh-y@KcBp{ex%#d2SN`zXp}$q6?{2#j`!iwdP0st8-EUNS-6N|?H~v)*@MdI^W5!kO
zN<dix3~wDlG@=q_g;c^A#Vx`#%qke!G$$m}5EU{jq(a7HDrR+zY-$e{Q?XRetdPnX
zt2MZ)W(l~JOB$aOV+~S8%?hcg@z{r12_xH=%SeiS;3}CFQYGUFNzCdNIV8UkV<ouq
zWrfs<csz$$^&)#Ngo!wtP%2`=mSR>2$d($jFkn;<tdQyfkC~VyJ;Ka}#&rlYv6cI*
Xka8cxcvd!$c1|E{02aNa>>wThzGI@}
new file mode 100644
--- /dev/null
+++ b/dom/quota/test/unit/test_removeLocalStorage.js
@@ -0,0 +1,85 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var testGenerator = testSteps();
+
+function* testSteps()
+{
+  const lsArchiveFile = "storage/ls-archive.sqlite";
+  const lsArchiveTmpFile = "storage/ls-archive-tmp.sqlite";
+  const lsDir = "storage/default/http+++localhost/ls";
+
+  // Profile 1
+  info("Clearing");
+
+  clear(continueToNextStepSync);
+  yield undefined;
+
+  info("Installing package");
+
+  installPackage("removeLocalStorage1_profile");
+
+  info("Checking ls archive tmp file");
+
+  let archiveTmpFile = getRelativeFile(lsArchiveTmpFile);
+
+  let exists = archiveTmpFile.exists();
+  ok(exists, "ls archive tmp file does exist");
+
+  info("Initializing");
+
+  let request = init(continueToNextStepSync);
+  yield undefined;
+
+  ok(request.resultCode == NS_OK, "Initialization succeeded");
+
+  info("Checking ls archive file");
+
+  exists = archiveTmpFile.exists();
+  ok(!exists, "ls archive tmp file doesn't exist");
+
+  // Profile 2
+  info("Clearing");
+
+  clear(continueToNextStepSync);
+  yield undefined;
+
+  info("Installing package");
+
+  installPackage("removeLocalStorage2_profile");
+
+  info("Checking ls archive file");
+
+  let archiveFile = getRelativeFile(lsArchiveFile);
+
+  exists = archiveFile.exists();
+  ok(exists, "ls archive file does exist");
+
+  info("Checking ls dir");
+
+  let dir = getRelativeFile(lsDir);
+
+  exists = dir.exists();
+  ok(exists, "ls directory does exist");
+
+  info("Initializing");
+
+  request = init(continueToNextStepSync);
+  yield undefined;
+
+  ok(request.resultCode == NS_OK, "Initialization succeeded");
+
+  info("Checking ls archive file");
+
+  exists = archiveFile.exists();
+  ok(!exists, "ls archive file doesn't exist");
+
+  info("Checking ls dir");
+
+  exists = dir.exists();
+  ok(!exists, "ls directory doesn't exist");
+
+  finishTest();
+}
--- a/dom/quota/test/unit/xpcshell.ini
+++ b/dom/quota/test/unit/xpcshell.ini
@@ -9,27 +9,30 @@ support-files =
   defaultStorageUpgrade_profile.zip
   getUsage_profile.zip
   idbSubdirUpgrade1_profile.zip
   idbSubdirUpgrade2_profile.zip
   morgueCleanup_profile.zip
   obsoleteOriginAttributes_profile.zip
   originAttributesUpgrade_profile.zip
   removeAppsUpgrade_profile.zip
+  removeLocalStorage1_profile.zip
+  removeLocalStorage2_profile.zip
   storagePersistentUpgrade_profile.zip
   tempMetadataCleanup_profile.zip
   version2_1upgrade_profile.zip
 
 [test_basics.js]
 [test_bad_origin_directory.js]
 skip-if = release_or_beta
 [test_defaultStorageUpgrade.js]
 [test_getUsage.js]
 [test_idbSubdirUpgrade.js]
 [test_morgueCleanup.js]
 [test_obsoleteOriginAttributesUpgrade.js]
 [test_originAttributesUpgrade.js]
 [test_persist.js]
 [test_removeAppsUpgrade.js]
+[test_removeLocalStorage.js]
 [test_storagePersistentUpgrade.js]
 [test_tempMetadataCleanup.js]
 [test_unknownFiles.js]
 [test_version2_1upgrade.js]