cryptohome: Add UdevAdmSettle
Add a function for UdevAdmSettle(): `udevadm settle` is used to
wait for any outstanding udev requests and optionally uses a
device path to wait. This guarantees the existence of the device
path on completion of the call.
BUG=b:172344853
TEST=unittests
Change-Id: Id508bf8ba4c205d3a02cb552a461d583bef0f439
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2599220
Reviewed-by: Leo Lai <cylai@google.com>
Reviewed-by: Daniil Lunev <dlunev@chromium.org>
Tested-by: Sarthak Kukreti <sarthakkukreti@chromium.org>
Commit-Queue: Sarthak Kukreti <sarthakkukreti@chromium.org>
diff --git a/cryptohome/mock_platform.h b/cryptohome/mock_platform.h
index ed134b8..8eacafe 100644
--- a/cryptohome/mock_platform.h
+++ b/cryptohome/mock_platform.h
@@ -393,6 +393,7 @@
SafeCreateDirAndSetOwnership,
(const base::FilePath&, uid_t, gid_t),
(override));
+ MOCK_METHOD(bool, UdevAdmSettle, (const base::FilePath&, bool), (override));
brillo::ProcessMock* mock_process() { return mock_process_.get(); }
diff --git a/cryptohome/platform.cc b/cryptohome/platform.cc
index eb54d5f..c59a6b9b 100644
--- a/cryptohome/platform.cc
+++ b/cryptohome/platform.cc
@@ -804,6 +804,29 @@
return path_result.second == brillo::SafeFD::Error::kNoError;
}
+bool Platform::UdevAdmSettle(const base::FilePath& device_path,
+ bool wait_for_device) {
+ brillo::ProcessImpl udevadm_process;
+ udevadm_process.AddArg("/bin/udevadm");
+ udevadm_process.AddArg("settle");
+
+ if (wait_for_device) {
+ udevadm_process.AddArg("-t");
+ udevadm_process.AddArg("10");
+ udevadm_process.AddArg("-E");
+ udevadm_process.AddArg(device_path.value());
+ }
+ // Close unused file descriptors in child process.
+ udevadm_process.SetCloseUnusedFileDescriptors(true);
+
+ // Start the process and return.
+ int rc = udevadm_process.Run();
+ if (rc != 0)
+ return false;
+
+ return true;
+}
+
bool Platform::DeleteFile(const FilePath& path) {
return base::DeleteFile(path);
}
@@ -1650,10 +1673,8 @@
}
FileEnumerator::FileInfo::FileInfo(const FilePath& name,
- const base::stat_wrapper_t& stat
- )
- : name_(name), stat_(stat) {
-}
+ const base::stat_wrapper_t& stat)
+ : name_(name), stat_(stat) {}
FileEnumerator::FileInfo::FileInfo(const FileEnumerator::FileInfo& other) {
if (other.info_.get()) {
diff --git a/cryptohome/platform.h b/cryptohome/platform.h
index 787891a..3ba28a4 100644
--- a/cryptohome/platform.h
+++ b/cryptohome/platform.h
@@ -917,6 +917,10 @@
uid_t user_id,
gid_t gid);
+ // Calls "udevadm settle", optionally waiting for the device path to appear.
+ virtual bool UdevAdmSettle(const base::FilePath& device_path,
+ bool wait_for_device);
+
private:
// Returns the process and open file information for the specified process id
// with files open on the given path