Bug 1339081 - Part 13: Move morgue directory cleanup to new upgrade helper; r=asuth

This commit is contained in:
Jan Varga 2017-03-06 18:40:02 +01:00
Родитель ea68f97a21
Коммит 98b838f625
4 изменённых файлов: 143 добавлений и 39 удалений

Просмотреть файл

@ -1639,6 +1639,9 @@ public:
DoUpgrade();
private:
nsresult
MaybeRemoveCorruptData(const OriginProps& aOriginProps);
nsresult
DoProcessOriginDirectories() override;
};
@ -3869,37 +3872,6 @@ QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
return NS_OK;
}
namespace {
// The Cache API was creating top level morgue directories by accident for
// a short time in nightly. This unfortunately prevents all storage from
// working. So recover these profiles by removing these corrupt directories.
// This should be removed at some point in the future.
bool
MaybeRemoveCorruptDirectory(const nsAString& aLeafName, nsIFile* aDir)
{
#ifdef NIGHTLY_BUILD
MOZ_ASSERT(aDir);
if (aLeafName != NS_LITERAL_STRING("morgue")) {
return false;
}
NS_WARNING("QuotaManager removing corrupt morgue directory!");
nsresult rv = aDir->Remove(true /* recursive */);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return true;
#else
return false;
#endif // NIGHTLY_BUILD
}
} // namespace
nsresult
QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
@ -3963,10 +3935,6 @@ QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
return NS_ERROR_UNEXPECTED;
}
if (MaybeRemoveCorruptDirectory(leafName, file)) {
continue;
}
Client::Type clientType;
rv = Client::TypeFromText(leafName, clientType);
if (NS_FAILED(rv)) {
@ -4314,6 +4282,21 @@ QuotaManager::UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection)
// The upgrade consists of a number of logically distinct bugs that
// intentionally got fixed at the same time to trigger just one major
// version bump.
//
//
// Morgue directory cleanup
// [Feature/Bug]:
// The original bug that added "on demand" morgue cleanup is 1165119.
//
// [Mutations]:
// Morgue directories are removed from all origin directories during the
// upgrade process. Origin initialization and usage calculation doesn't try
// to remove morgue directories anymore.
//
// [Downgrade-incompatible changes]:
// Morgue directories can reappear if user runs an already upgraded profile
// in an older version of Firefox. Morgue directories then prevent current
// Firefox from initializing and using the storage.
nsresult rv;
@ -6219,10 +6202,6 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
continue;
}
if (MaybeRemoveCorruptDirectory(leafName, file)) {
continue;
}
Client::Type clientType;
rv = Client::TypeFromText(leafName, clientType);
if (NS_FAILED(rv)) {
@ -8034,6 +8013,15 @@ UpgradeStorageFrom1_0To2_0Helper::DoUpgrade()
return rv;
}
// The Cache API was creating top level morgue directories by accident for
// a short time in nightly. This unfortunately prevents all storage from
// working. So recover these profiles permanently by removing these corrupt
// directories as part of this upgrade.
rv = MaybeRemoveCorruptData(originProps);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
int64_t timestamp;
nsCString group;
nsCString origin;
@ -8079,6 +8067,79 @@ UpgradeStorageFrom1_0To2_0Helper::DoUpgrade()
return NS_OK;
}
nsresult
UpgradeStorageFrom1_0To2_0Helper::MaybeRemoveCorruptData(
const OriginProps& aOriginProps)
{
AssertIsOnIOThread();
MOZ_ASSERT(aOriginProps.mDirectory);
nsCOMPtr<nsISimpleEnumerator> entries;
nsresult rv =
aOriginProps.mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool hasMore;
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) && hasMore) {
nsCOMPtr<nsISupports> entry;
rv = entries->GetNext(getter_AddRefs(entry));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
if (NS_WARN_IF(!file)) {
return rv;
}
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsString leafName;
rv = file->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!isDirectory) {
// Unknown files during upgrade are allowed. Just warn if we find them.
if (!IsOriginMetadata(leafName) &&
!IsTempMetadata(leafName)) {
UNKNOWN_FILE_WARNING(leafName);
}
continue;
}
if (leafName.EqualsLiteral("morgue")) {
QM_WARNING("Deleting accidental morgue directory!");
rv = file->Remove(/* recursive */ true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
Client::Type clientType;
rv = Client::TypeFromText(leafName, clientType);
if (NS_FAILED(rv)) {
UNKNOWN_FILE_WARNING(leafName);
continue;
}
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
UpgradeStorageFrom1_0To2_0Helper::DoProcessOriginDirectories()
{

Двоичные данные
dom/quota/test/unit/morgueCleanup_profile.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,41 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps()
{
const morgueFile = "storage/default/http+++example.com/morgue";
info("Clearing");
clear(continueToNextStepSync);
yield undefined;
info("Installing package");
installPackage("morgueCleanup_profile");
info("Checking morgue file");
let file = getRelativeFile(morgueFile);
let exists = file.exists();
ok(exists, "Morgue file does exist");
info("Initializing");
let request = init(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Initialization succeeded");
info("Checking morgue file");
exists = file.exists();
ok(!exists, "Morgue file doesn't exist");
finishTest();
}

Просмотреть файл

@ -6,8 +6,10 @@
head = head.js
support-files =
basics_profile.zip
morgueCleanup_profile.zip
tempMetadataCleanup_profile.zip
[test_basics.js]
[test_morgueCleanup.js]
[test_tempMetadataCleanup.js]
[test_unknownFiles.js]