Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(940)

Unified Diff: chrome/installer/util/delete_old_versions.cc

Issue 1764053002: Revert of Delete old files after an update. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/installer/util/delete_old_versions.h ('k') | chrome/installer/util/delete_old_versions_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/installer/util/delete_old_versions.cc
diff --git a/chrome/installer/util/delete_old_versions.cc b/chrome/installer/util/delete_old_versions.cc
deleted file mode 100644
index 222f5109ba18c772c59c343364b9e4717e4cedd8..0000000000000000000000000000000000000000
--- a/chrome/installer/util/delete_old_versions.cc
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/installer/util/delete_old_versions.h"
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/file_version_info.h"
-#include "base/files/file.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/stl_util.h"
-#include "base/strings/string16.h"
-#include "base/version.h"
-#include "chrome/installer/util/callback_work_item.h"
-#include "chrome/installer/util/installer_state.h"
-#include "chrome/installer/util/util_constants.h"
-#include "chrome/installer/util/work_item_list.h"
-
-namespace installer {
-
-namespace {
-
-using PathVector = std::vector<base::FilePath>;
-using DirectorySet = std::set<base::FilePath>;
-using ExecutableMap = std::map<base::FilePath, PathVector>;
-
-// Returns the name of the version directory for executable |exe_path|.
-base::FilePath GetExecutableVersionDirName(const base::FilePath& exe_path) {
- scoped_ptr<FileVersionInfo> file_version_info(
- FileVersionInfo::CreateFileVersionInfo(exe_path));
- if (!file_version_info.get())
- return base::FilePath();
- return base::FilePath(file_version_info->file_version());
-}
-
-// Returns the names of the old version directories found in |install_dir|. The
-// directories named after the version of chrome.exe or new_chrome.exe are
-// excluded.
-DirectorySet GetOldVersionDirectories(const base::FilePath& install_dir) {
- const base::FilePath new_chrome_exe_version_dir_name =
- GetExecutableVersionDirName(install_dir.Append(kChromeNewExe));
- const base::FilePath chrome_exe_version_dir_name =
- GetExecutableVersionDirName(install_dir.Append(kChromeExe));
-
- DirectorySet directories;
- base::FileEnumerator enum_directories(install_dir, false,
- base::FileEnumerator::DIRECTORIES);
- for (base::FilePath directory_path = enum_directories.Next();
- !directory_path.empty(); directory_path = enum_directories.Next()) {
- const base::FilePath directory_name = directory_path.BaseName();
- const base::Version version(directory_name.AsUTF8Unsafe());
- const size_t kNumChromeVersionComponents = 4;
- if (version.IsValid() &&
- version.components().size() == kNumChromeVersionComponents &&
- directory_name != new_chrome_exe_version_dir_name &&
- directory_name != chrome_exe_version_dir_name) {
- directories.insert(directory_name);
- }
- }
- return directories;
-}
-
-// Returns a map where the keys are version directory names and values are paths
-// of old_chrome*.exe executables found in |install_dir|.
-ExecutableMap GetOldExecutables(const base::FilePath& install_dir) {
- ExecutableMap executables;
- base::FileEnumerator enum_executables(install_dir, false,
- base::FileEnumerator::FILES,
- FILE_PATH_LITERAL("old_chrome*.exe"));
- for (base::FilePath exe_path = enum_executables.Next(); !exe_path.empty();
- exe_path = enum_executables.Next()) {
- executables[GetExecutableVersionDirName(exe_path)].push_back(exe_path);
- }
- return executables;
-}
-
-// Deletes directories that are in |directories| and don't have a matching
-// executable in |executables|. Returns false if any such directories could not
-// be deleted.
-bool DeleteDirectoriesWithoutMatchingExecutable(
- const DirectorySet& directories,
- const ExecutableMap& executables,
- const base::FilePath& install_dir) {
- bool success = true;
- for (const base::FilePath& directory_name : directories) {
- // Delete the directory if it doesn't have a matching executable.
- if (!ContainsKey(executables, directory_name)) {
- const base::FilePath directory_path = install_dir.Append(directory_name);
- LOG(WARNING) << "Attempting to delete stray directory "
- << directory_path.value();
- if (!base::DeleteFile(directory_path, true)) {
- PLOG(ERROR) << "Failed to delete stray directory "
- << directory_path.value();
- success = false;
- }
- }
- }
- return success;
-}
-
-// Deletes executables that are in |executables| and don't have a matching
-// directory in |directories|. Returns false if any such files could not be
-// deleted.
-bool DeleteExecutablesWithoutMatchingDirectory(
- const DirectorySet& directories,
- const ExecutableMap& executables) {
- bool success = true;
- for (const auto& version_and_executables : executables) {
- const auto& version_dir_name = version_and_executables.first;
- const auto& executables_for_version = version_and_executables.second;
-
- // Don't delete the executables if they have a matching directory.
- if (ContainsValue(directories, version_dir_name))
- continue;
-
- // Delete executables for version |version_dir_name|.
- for (const auto& executable_path : executables_for_version) {
- const base::FilePath executable_name = executable_path.BaseName();
- LOG(WARNING) << "Attempting to delete stray executable "
- << executable_path.value();
- if (!base::DeleteFile(executable_path, false)) {
- PLOG(ERROR) << "Failed to delete stray executable "
- << executable_path.value();
- success = false;
- }
- }
- }
- return success;
-}
-
-// Opens |path| with options that prevent the file from being read or written
-// via another handle. As long as the returned object is alive, it is guaranteed
-// that |path| isn't in use. It can however be deleted.
-base::File GetFileLock(const base::FilePath& path) {
- return base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
- base::File::FLAG_EXCLUSIVE_READ |
- base::File::FLAG_EXCLUSIVE_WRITE |
- base::File::FLAG_SHARE_DELETE);
-}
-
-// Deletes |version_directory| and all executables in |version_executables| if
-// no .exe or .dll file for the version is in use. Returns false if any file
-// or directory for the version could not be deleted.
-bool DeleteVersion(const base::FilePath& version_directory,
- const PathVector& version_executables) {
- std::vector<base::File> locks;
- PathVector locked_file_paths;
-
- // Lock .exe/.dll files in |version_directory|.
- base::FileEnumerator enum_version_directory(version_directory, true,
- base::FileEnumerator::FILES);
- for (base::FilePath path = enum_version_directory.Next(); !path.empty();
- path = enum_version_directory.Next()) {
- if (!path.MatchesExtension(FILE_PATH_LITERAL(".exe")) &&
- !path.MatchesExtension(FILE_PATH_LITERAL(".dll"))) {
- continue;
- }
- locks.push_back(GetFileLock(path));
- if (!locks.back().IsValid()) {
- LOG(WARNING) << "Failed to delete old version "
- << version_directory.value() << " because " << path.value()
- << " is in use.";
- return false;
- }
- locked_file_paths.push_back(path);
- }
-
- // Lock executables in |version_executables|.
- for (const base::FilePath& executable_path : version_executables) {
- locks.push_back(GetFileLock(executable_path));
- if (!locks.back().IsValid()) {
- LOG(WARNING) << "Failed to delete old version "
- << version_directory.value() << " because "
- << executable_path.value() << " is in use.";
- return false;
- }
- locked_file_paths.push_back(executable_path);
- }
-
- bool success = true;
-
- // Delete locked files. The files won't actually be deleted until the locks
- // are released.
- for (const base::FilePath& locked_file_path : locked_file_paths) {
- if (!base::DeleteFile(locked_file_path, false)) {
- PLOG(ERROR) << "Failed to delete locked file "
- << locked_file_path.value();
- success = false;
- }
- }
-
- // Release the locks, causing the locked files to actually be deleted. The
- // version directory can't be deleted before this is done.
- locks.clear();
-
- // Delete the version directory.
- if (!base::DeleteFile(version_directory, true)) {
- PLOG(ERROR) << "Failed to delete version directory "
- << version_directory.value();
- success = false;
- }
-
- return success;
-}
-
-// For each executable in |executables| that has a matching directory in
-// |directories|, tries to delete the executable and the matching directory. No
-// deletion occurs for a given version if a .exe or .dll file for that version
-// is in use. Returns false if any directory/executables pair could not be
-// deleted.
-bool DeleteMatchingExecutablesAndDirectories(
- const DirectorySet& directories,
- const ExecutableMap& executables,
- const base::FilePath& install_dir) {
- bool success = true;
- for (const auto& directory_name : directories) {
- // Don't delete the version unless the directory has at least one matching
- // executable.
- auto version_executables_it = executables.find(directory_name);
- if (version_executables_it == executables.end())
- continue;
-
- // Try to delete all files for the version.
- success &= DeleteVersion(install_dir.Append(directory_name),
- version_executables_it->second);
- }
- return success;
-}
-
-bool DeleteOldVersions(const base::FilePath& install_dir) {
- const DirectorySet old_directories = GetOldVersionDirectories(install_dir);
- const ExecutableMap old_executables = GetOldExecutables(install_dir);
-
- bool success = true;
- success &= DeleteDirectoriesWithoutMatchingExecutable(
- old_directories, old_executables, install_dir);
- success &= DeleteExecutablesWithoutMatchingDirectory(old_directories,
- old_executables);
- success &= DeleteMatchingExecutablesAndDirectories(
- old_directories, old_executables, install_dir);
-
- return success;
-}
-
-bool DeleteOldVersionsCallback(const InstallerState& installer_state,
- const CallbackWorkItem& work_item) {
- // No rollback is possible for this action.
- if (work_item.IsRollback())
- return true;
-
- installer_state.UpdateStage(REMOVING_OLD_VERSIONS);
- return DeleteOldVersions(installer_state.target_path());
-}
-
-} // namespace
-
-void AddDeleteOldVersionsWorkItem(const InstallerState& installer_state,
- WorkItemList* work_item_list) {
- DCHECK(work_item_list);
-
- // TODO(fdoray): Launch a cleanup process when this fails during a regular
- // update or after a rename. crbug.com/451546
- work_item_list
- ->AddCallbackWorkItem(base::Bind(&DeleteOldVersionsCallback,
- base::ConstRef(installer_state)))
- ->set_ignore_failure(true);
-}
-
-} // namespace installer
« no previous file with comments | « chrome/installer/util/delete_old_versions.h ('k') | chrome/installer/util/delete_old_versions_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698