diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-11 01:40:01 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-11 01:40:01 +0000 |
commit | 9ada117290d556aae78ff69784d11a7dcffe5895 (patch) | |
tree | 012c9e7e2e39e06f5eca627c39ce59b71e094fbd | |
parent | ef6fddadb45bb7e346a3d3e2fbdaca5d476fee03 (diff) | |
download | chromium_src-9ada117290d556aae78ff69784d11a7dcffe5895.zip chromium_src-9ada117290d556aae78ff69784d11a7dcffe5895.tar.gz chromium_src-9ada117290d556aae78ff69784d11a7dcffe5895.tar.bz2 |
Linux: add a switch to support user data migration under singleton lock.
This will be used to support migration to SxS (side-by-side) profiles
on Linux.
BUG=38598
R=thestig@chromium.org
Review URL: https://codereview.chromium.org/23531025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222446 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chrome_browser_main.cc | 6 | ||||
-rw-r--r-- | chrome/browser/sxs_linux.cc | 64 | ||||
-rw-r--r-- | chrome/browser/sxs_linux.h | 7 | ||||
-rw-r--r-- | chrome/common/chrome_result_codes.h | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 8 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 4 |
6 files changed, 91 insertions, 2 deletions
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 4a04a96..4723a10 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -146,6 +146,7 @@ #if defined(OS_LINUX) && !defined(OS_CHROMEOS) #include "chrome/browser/first_run/upgrade_util_linux.h" +#include "chrome/browser/sxs_linux.h" #endif #if defined(OS_CHROMEOS) @@ -1219,6 +1220,11 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { } } +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + if (sxs_linux::ShouldMigrateUserDataDir()) + return sxs_linux::MigrateUserDataDir(); +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) + first_run::CreateSentinelIfNeeded(); #endif // !defined(OS_ANDROID) diff --git a/chrome/browser/sxs_linux.cc b/chrome/browser/sxs_linux.cc index 4b34260..0d6b7dd 100644 --- a/chrome/browser/sxs_linux.cc +++ b/chrome/browser/sxs_linux.cc @@ -6,6 +6,7 @@ #include <vector> +#include "base/command_line.h" #include "base/logging.h" #include "base/file_util.h" #include "base/files/file_path.h" @@ -14,12 +15,16 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_result_codes.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_version_info.h" #include "content/public/browser/browser_thread.h" namespace { -bool DoAddChannelMarkToUserDataDir(const base::FilePath& user_data_dir) { +const char kChannelsFileName[] = "Channels"; + +std::string GetChannelMarkForThisExecutable() { std::string product_channel_name; chrome::VersionInfo::Channel product_channel( chrome::VersionInfo::GetChannel()); @@ -51,7 +56,12 @@ bool DoAddChannelMarkToUserDataDir(const base::FilePath& user_data_dir) { // Rely on -Wswitch compiler warning to detect unhandled enum values. } - base::FilePath channels_path(user_data_dir.AppendASCII("Channels")); + return product_channel_name; +} + +bool DoAddChannelMarkToUserDataDir(const base::FilePath& user_data_dir) { + std::string product_channel_name(GetChannelMarkForThisExecutable()); + base::FilePath channels_path(user_data_dir.AppendASCII(kChannelsFileName)); std::vector<std::string> user_data_dir_channels; // Note: failure to read the channels file is not fatal. It's possible @@ -94,4 +104,54 @@ void AddChannelMarkToUserDataDir() { } } +bool ShouldMigrateUserDataDir() { + return CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMigrateDataDirForSxS); +} + +int MigrateUserDataDir() { + DCHECK(ShouldMigrateUserDataDir()); + + base::FilePath source_path; + if (!PathService::Get(chrome::DIR_USER_DATA, &source_path)) { + LOG(ERROR) << "Failed to get value of chrome::DIR_USER_DATA"; + return chrome::RESULT_CODE_SXS_MIGRATION_FAILED; + } + + base::FilePath channels_path(source_path.AppendASCII(kChannelsFileName)); + + std::string channels_contents; + if (!base::ReadFileToString(channels_path, &channels_contents)) { + LOG(WARNING) << "Failed to read channels file."; + return chrome::RESULT_CODE_SXS_MIGRATION_FAILED; + } + + std::vector<std::string> user_data_dir_channels; + base::SplitString(channels_contents, '\n', &user_data_dir_channels); + + if (user_data_dir_channels.size() != 1) { + LOG(WARNING) << "User data dir migration is only possible when the profile " + << "is only used with a single channel."; + return chrome::RESULT_CODE_SXS_MIGRATION_FAILED; + } + + if (user_data_dir_channels[0] != GetChannelMarkForThisExecutable()) { + LOG(WARNING) << "User data dir migration is only possible when the profile " + << "is used with the same channel."; + return chrome::RESULT_CODE_SXS_MIGRATION_FAILED; + } + + base::FilePath target_path = + CommandLine::ForCurrentProcess()->GetSwitchValuePath( + switches::kMigrateDataDirForSxS); + + if (!base::Move(source_path, target_path)) { + LOG(ERROR) << "Failed to rename '" << source_path.value() + << "' to '" << target_path.value() << "'"; + return chrome::RESULT_CODE_SXS_MIGRATION_FAILED; + } + + return content::RESULT_CODE_NORMAL_EXIT; +} + } // namespace sxs_linux diff --git a/chrome/browser/sxs_linux.h b/chrome/browser/sxs_linux.h index a6d7b42..cff48f2 100644 --- a/chrome/browser/sxs_linux.h +++ b/chrome/browser/sxs_linux.h @@ -19,6 +19,13 @@ namespace sxs_linux { // Must be run on FILE thread. void AddChannelMarkToUserDataDir(); +// Returns true if user data dir migration has been requested. +bool ShouldMigrateUserDataDir() WARN_UNUSED_RESULT; + +// Migrates user data dir to a side-by-side-compatible one. +// Returns exit code - caller should make the process exit with that code. +int MigrateUserDataDir() WARN_UNUSED_RESULT; + } // namespace sxs_linux #endif // CHROME_BROWSER_SXS_LINUX_H_ diff --git a/chrome/common/chrome_result_codes.h b/chrome/common/chrome_result_codes.h index a29de59..5e1106c 100644 --- a/chrome/common/chrome_result_codes.h +++ b/chrome/common/chrome_result_codes.h @@ -85,6 +85,10 @@ enum ResultCode { // Returned when the user has not yet accepted the EULA. RESULT_CODE_EULA_REFUSED, + // Failed to migrate user data directory for side-by-side package support + // (Linux-only). + RESULT_CODE_SXS_MIGRATION_FAILED, + // Last return code (keep this last). RESULT_CODE_CHROME_LAST_CODE, }; diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 9a3947a..30a5657 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1526,6 +1526,14 @@ const char kPasswordStore[] = "password-store"; #endif #endif // OS_POSIX +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +// Triggers migration of user data directory to another directory +// specified as a parameter. The migration is done under singleton lock, +// and sanity checks are made to avoid corrupting the profile. +// The browser exits after migration is complete. +const char kMigrateDataDirForSxS[] = "migrate-data-dir-for-sxs"; +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) + #if defined(OS_MACOSX) // Forcibly disables Lion-style on newer OSes, to allow developers to test the // older, SnowLeopard-style fullscreen. diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 686240e..6bc8a9f 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -426,6 +426,10 @@ extern const char kPasswordStore[]; #endif #endif +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +extern const char kMigrateDataDirForSxS[]; +#endif + #if defined(OS_MACOSX) extern const char kDisableSystemFullscreenForTesting[]; extern const char kEnableAppListShim[]; |