Improve atomiticy of update checkpointing
Current check point works by writing different prefs to different files
under a pending directory, and rename the pending directory to actual pref
directory afterwards to achieve atomicity. It has two pitfalls:
1. Before the rename() call, existing prefs dir must be rm -rf'ed , this
deletion process isn't atomic. If device rebooted during rm -rf, we
will end up with a partially deleted old pref.
2. fsync() on the parent directory is needed after rename()
This CL addresses both issues. For #1, we rename() the old pref dir to a
tmp dir first, and then rm -rf the tmp dir. Upon device restart, if the
current prefs dir is empty, we can simply rename() the pending directory
to actual pref directory.
Test: th
Bug: 295252766
Change-Id: Ic671a18245986c579b51d7443c3e8c10e206c448
diff --git a/common/utils.cc b/common/utils.cc
index 15ee05c..f0c045f 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -412,6 +412,17 @@
return true;
}
+bool DeleteDirectory(const char* dirname) {
+ const std::string tmpdir = std::string(dirname) + "_deleted";
+ std::filesystem::remove_all(tmpdir);
+ if (rename(dirname, tmpdir.c_str()) != 0) {
+ PLOG(ERROR) << "Failed to rename " << dirname << " to " << tmpdir;
+ return false;
+ }
+ std::filesystem::remove_all(tmpdir);
+ return true;
+}
+
bool FsyncDirectory(const char* dirname) {
android::base::unique_fd fd(
TEMP_FAILURE_RETRY(open(dirname, O_RDONLY | O_CLOEXEC)));