Fsync directory contents
Fsync dirname is not enough for changes to be flushed to disk. Fsync all
entries as well to ensure atomicity.
This change effectively makes update_engine resumable at most points of
interruption.
1. Outside checkpointing (straightforward and has always been resumable)
2. During checkpointing
a. prefs dir deletion (we will resume using prefs_tmp)
b. after rename (If changes aren't flushed, we can continue
using prefs_tmp).
c. during fsync() (This will lead to corrupt prefs on disk)
d. after fsync() -> same as finishing checkpointing
With this change, only an interruption during point c will lead to
corrupt prefs on disk. Since the fsync is relatively fast, update_engine
will essentially be 99% resistant to interrupts. In the off chance that
an interrupt happens during fsync(), we are still able to re-try the OTA
as a fallback
Test: trigger kernel crash at various points during checkpointing
Change-Id: I68fa56b971ed6b5677c47231b51102ae6d01bb9b
diff --git a/common/utils.h b/common/utils.h
index ae07b07..1d8de85 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -161,6 +161,7 @@
bool SendFile(int out_fd, int in_fd, size_t count);
+bool FsyncDirectoryContents(const char* dirname);
bool FsyncDirectory(const char* dirname);
bool DeleteDirectory(const char* dirname);
bool WriteStringToFileAtomic(const std::string& path, std::string_view content);