aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Macnak <natsu@google.com>2024-04-24 19:47:33 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-04-24 19:47:33 +0000
commit53d315479d9ad006344a81f37149509b64ad741e (patch)
tree51a3372262bc2f440c21b5d4f63a057e798a2f0c
parent1294bb53b4ec148a21c258f03596343bdd030b1e (diff)
parent85841353f2fe9a6b71e03edc72c94522426d8df7 (diff)
downloadcuttlefish-53d315479d9ad006344a81f37149509b64ad741e.tar.gz
Merge "Make main crosvm wait for vhost user gpu device socket available" into main
-rw-r--r--common/libs/utils/files.cpp52
-rw-r--r--common/libs/utils/files.h2
-rw-r--r--host/libs/vm_manager/crosvm_manager.cpp15
3 files changed, 63 insertions, 6 deletions
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index 5fa1e6ecf..0f9f93ec1 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -52,6 +52,7 @@
#include <numeric>
#include <ostream>
#include <ratio>
+#include <regex>
#include <string>
#include <vector>
@@ -663,6 +664,57 @@ Result<void> WaitForUnixSocket(const std::string& path, int timeoutSec) {
return CF_ERR("This shouldn't be executed");
}
+
+Result<void> WaitForUnixSocketListeningWithoutConnect(const std::string& path,
+ int timeoutSec) {
+ const auto targetTime =
+ std::chrono::system_clock::now() + std::chrono::seconds(timeoutSec);
+
+ CF_EXPECT(WaitForFile(path, timeoutSec),
+ "Waiting for socket path creation failed");
+ CF_EXPECT(FileIsSocket(path), "Specified path is not a socket");
+
+ std::regex socket_state_regex("TST=(.*)");
+
+ while (true) {
+ const auto currentTime = std::chrono::system_clock::now();
+
+ if (currentTime >= targetTime) {
+ return CF_ERR("Timed out");
+ }
+
+ Command lsof("lsof");
+ lsof.AddParameter(/*"format"*/ "-F", /*"connection state"*/ "TST");
+ lsof.AddParameter(path);
+ std::string lsof_out;
+ std::string lsof_err;
+ int rval =
+ RunWithManagedStdio(std::move(lsof), nullptr, &lsof_out, &lsof_err);
+ if (rval != 0) {
+ return CF_ERR("Failed to run `lsof`, stderr: " << lsof_err);
+ }
+
+ LOG(DEBUG) << "lsof stdout:" << lsof_out;
+
+ std::smatch socket_state_match;
+ if (!std::regex_search(lsof_out, socket_state_match, socket_state_regex)) {
+ return CF_ERR("Failed to find state in `lsof` stdout: " << lsof_out);
+ }
+ if (socket_state_match.size() != 2) {
+ return CF_ERR(
+ "Unexpected number of matches in `lsof` stdout: " << lsof_out);
+ }
+
+ const std::string& socket_state = socket_state_match[1];
+ if (socket_state == "LISTEN") {
+ return {};
+ }
+
+ sched_yield();
+ }
+
+ return CF_ERR("This shouldn't be executed");
+}
#endif
namespace {
diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h
index cf13dea72..6e423cda4 100644
--- a/common/libs/utils/files.h
+++ b/common/libs/utils/files.h
@@ -84,6 +84,8 @@ Result<void> WalkDirectory(
#ifdef __linux__
Result<void> WaitForFile(const std::string& path, int timeoutSec);
Result<void> WaitForUnixSocket(const std::string& path, int timeoutSec);
+Result<void> WaitForUnixSocketListeningWithoutConnect(const std::string& path,
+ int timeoutSec);
#endif
// parameter to EmulateAbsolutePath
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index fb8f4605c..c26da188e 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -212,12 +212,6 @@ Result<VhostUserDeviceCommands> BuildVhostUserGpu(
auto gpu_device_socket_path =
instance.PerInstanceInternalUdsPath("vhost-user-gpu-socket");
- auto gpu_device_socket = SharedFD::SocketLocalServer(
- gpu_device_socket_path.c_str(), false, SOCK_STREAM, 0777);
- CF_EXPECT(gpu_device_socket->IsOpen(),
- "Failed to create socket for crosvm vhost user gpu's control"
- << gpu_device_socket->StrError());
-
auto gpu_device_logs_path =
instance.PerInstanceInternalPath("crosvm_vhost_user_gpu.fifo");
auto gpu_device_logs = CF_EXPECT(SharedFD::Fifo(gpu_device_logs_path, 0666));
@@ -318,6 +312,15 @@ Result<VhostUserDeviceCommands> BuildVhostUserGpu(
// Connect device to main crosvm:
gpu_device_cmd.Cmd().AddParameter("--socket=", gpu_device_socket_path);
+
+ main_crosvm_cmd->AddPrerequisite([gpu_device_socket_path]() -> Result<void> {
+#ifdef __linux__
+ return WaitForUnixSocketListeningWithoutConnect(gpu_device_socket_path,
+ /*timeoutSec=*/30);
+#else
+ return CF_ERR("Unhandled check if vhost user gpu ready.");
+#endif
+ });
main_crosvm_cmd->AddParameter(
"--vhost-user=gpu,pci-address=", gpu_pci_address,
",socket=", gpu_device_socket_path);