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);