Merge lp:~widelands-dev/widelands/bug-1746270-rolling-autosave-file-permissions into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 8854
Proposed branch: lp:~widelands-dev/widelands/bug-1746270-rolling-autosave-file-permissions
Merge into: lp:widelands
Diff against target: 66 lines (+37/-5)
1 file modified
src/logic/save_handler.cc (+37/-5)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1746270-rolling-autosave-file-permissions
Reviewer Review Type Date Requested Status
Klaus Halfmann testplay on windows Approve
Review via email: mp+353758@code.launchpad.net

Commit message

Handle file permissions problems during autosave.

- When a file can't be renamed, try to find an unused filename instead
- Skip the autosave interval as a last resort

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3836. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/420887444.
Appveyor build 3634. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1746270_rolling_autosave_file_permissions-3634.

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Looks like Its time to switch on the debugger.
Will compile this and think about all kind of nasty ways to break this :-)

Could we inform the player if this finally failes?

Code LGTM.

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Tested this on OSX, but found the original Problem was on Windows.
The code works as expected but I did not trigger the original Problem.
e.g. when I make the complete save dir unreadable the save completly
fails, well.

OSX and *nixes behave differnt compared Windows when it comes to open files.

Alas I approve this I will do another round of testing on Windows, tomorrow.

review: Approve (review, compile, debug)
Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

OK, tested along the original Bug, works as desigend.

@bunnybot merge

review: Approve (testplay on windows)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/logic/save_handler.cc'
--- src/logic/save_handler.cc 2018-07-18 15:01:33 +0000
+++ src/logic/save_handler.cc 2018-09-25 18:47:39 +0000
@@ -68,9 +68,14 @@
68 const std::string filename_next =68 const std::string filename_next =
69 create_file_name(kSaveDir, (boost::format("%s_%02d") % filename % rolls).str());69 create_file_name(kSaveDir, (boost::format("%s_%02d") % filename % rolls).str());
70 if (g_fs->file_exists(filename_next)) {70 if (g_fs->file_exists(filename_next)) {
71 g_fs->fs_rename(71 try {
72 filename_next, filename_previous); // e.g. wl_autosave_08 -> wl_autosave_0972 g_fs->fs_rename(
73 log("Autosave: Rolled %s to %s\n", filename_next.c_str(), filename_previous.c_str());73 filename_next, filename_previous); // e.g. wl_autosave_08 -> wl_autosave_09
74 log("Autosave: Rolled %s to %s\n", filename_next.c_str(), filename_previous.c_str());
75 } catch (const std::exception& e) {
76 log("Autosave: Unable to rename file %s to %s: %s\n", filename_previous.c_str(),
77 filename_next.c_str(), e.what());
78 }
74 }79 }
75 filename_previous = filename_next;80 filename_previous = filename_next;
76 rolls--;81 rolls--;
@@ -167,7 +172,7 @@
167 }172 }
168173
169 // Saving now174 // Saving now
170 const std::string complete_filename = create_file_name(kSaveDir, filename);175 std::string complete_filename = create_file_name(kSaveDir, filename);
171 std::string backup_filename;176 std::string backup_filename;
172177
173 // always overwrite a file178 // always overwrite a file
@@ -177,7 +182,34 @@
177 if (g_fs->file_exists(backup_filename)) {182 if (g_fs->file_exists(backup_filename)) {
178 g_fs->fs_unlink(backup_filename);183 g_fs->fs_unlink(backup_filename);
179 }184 }
180 g_fs->fs_rename(complete_filename, backup_filename);185 if (save_requested_) {
186 // Exceptions (e.g. no file permissions) will be handled in UI
187 g_fs->fs_rename(complete_filename, backup_filename);
188 } else {
189 // We're autosaving, try to handle file permissions issues
190 try {
191 g_fs->fs_rename(complete_filename, backup_filename);
192 } catch (const std::exception& e) {
193 log("Autosave: Unable to rename file %s to %s: %s\n", complete_filename.c_str(),
194 backup_filename.c_str(), e.what());
195 // See if we can find a file that doesn't exist and save to that
196 int current_autosave = 0;
197 do {
198 filename = create_file_name(
199 kSaveDir,
200 (boost::format("%s_0%d") % autosave_filename_ % (++current_autosave)).str());
201 } while (current_autosave < 9 && g_fs->file_exists(filename));
202 complete_filename = filename;
203 log("Autosave: saving as %s instead\n", complete_filename.c_str());
204 try {
205 g_fs->fs_rename(complete_filename, backup_filename);
206 } catch (const std::exception&) {
207 log("Autosave failed, skipping this interval\n");
208 saving_next_tick_ = check_next_tick(game, realtime);
209 return;
210 }
211 }
212 }
181 }213 }
182214
183 if (!save_and_handle_error(game, complete_filename, backup_filename)) {215 if (!save_and_handle_error(game, complete_filename, backup_filename)) {

Subscribers

People subscribed via source and target branches

to status/vote changes: