init: fsync() persistent properties directory after rename()

See the inline comment on why this is necessary.

Test: persistent properties work without errors
Change-Id: I820a193fb032a1845791a55a76390d396678f151
This commit is contained in:
Tom Cherry 2019-12-06 11:16:10 -08:00
parent 1dd1056f5d
commit 97437a7aae

View file

@ -31,10 +31,11 @@
#include "util.h"
using android::base::Dirname;
using android::base::ReadFdToString;
using android::base::StartsWith;
using android::base::WriteStringToFd;
using android::base::unique_fd;
using android::base::WriteStringToFd;
namespace android {
namespace init {
@ -191,6 +192,18 @@ Result<void> WritePersistentPropertyFile(const PersistentProperties& persistent_
unlink(temp_filename.c_str());
return Error(saved_errno) << "Unable to rename persistent property file";
}
// rename() is atomic with regards to the kernel's filesystem buffers, but the parent
// directories must be fsync()'ed otherwise, the rename is not necessarily written to storage.
// Note in this case, that the source and destination directories are the same, so only one
// fsync() is required.
auto dir = Dirname(persistent_property_filename);
auto dir_fd = unique_fd{open(dir.c_str(), O_DIRECTORY | O_RDONLY)};
if (dir_fd < 0) {
return ErrnoError() << "Unable to open persistent properties directory for fsync()";
}
fsync(dir_fd);
return {};
}