Skip to content

Commit

Permalink
Use a copy+delete instead of a move operation for config migration
Browse files Browse the repository at this point in the history
This can handle migration across filesystems.
  • Loading branch information
cgutman committed Mar 15, 2024
1 parent 8c9e14e commit 15c5e76
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/platform/linux/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,30 @@ namespace platf {
// migrate from the old config location if necessary
migrate_envvar = getenv("SUNSHINE_MIGRATE_CONFIG");
if (migrate_config && found && migrate_envvar && strcmp(migrate_envvar, "1") == 0) {
std::error_code ec;
fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv;
if (old_config_path != config_path && fs::exists(old_config_path)) {
if (!fs::exists(config_path)) {
if (old_config_path != config_path && fs::exists(old_config_path, ec)) {
if (!fs::exists(config_path, ec)) {
std::cout << "Migrating config from "sv << old_config_path << " to "sv << config_path << std::endl;
std::error_code ec;
fs::rename(old_config_path, config_path, ec);
if (!ec) {
// Create the new directory tree if it doesn't already exist
fs::create_directories(config_path, ec);
}
if (!ec) {
// Copy the old directory into the new location
// NB: We use a copy instead of a move so that cross-volume migrations work
fs::copy(old_config_path, config_path, fs::copy_options::recursive | fs::copy_options::copy_symlinks, ec);
}
if (!ec) {
// If the copy was successful, delete the original directory
fs::remove_all(old_config_path, ec);
if (ec) {
std::cerr << "Failed to clean up old config directory: " << ec.message() << std::endl;

// This is not fatal. Next time we start, we'll warn the user to delete the old one.
ec.clear();
}
}
if (ec) {
std::cerr << "Migration failed: " << ec.message() << std::endl;
config_path = old_config_path;
Expand Down

0 comments on commit 15c5e76

Please sign in to comment.