diff options
author | Jason Macnak <natsu@google.com> | 2024-04-24 19:47:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-04-24 19:47:33 +0000 |
commit | 53d315479d9ad006344a81f37149509b64ad741e (patch) | |
tree | 51a3372262bc2f440c21b5d4f63a057e798a2f0c | |
parent | 1294bb53b4ec148a21c258f03596343bdd030b1e (diff) | |
parent | 85841353f2fe9a6b71e03edc72c94522426d8df7 (diff) | |
download | cuttlefish-53d315479d9ad006344a81f37149509b64ad741e.tar.gz |
Merge "Make main crosvm wait for vhost user gpu device socket available" into main
-rw-r--r-- | common/libs/utils/files.cpp | 52 | ||||
-rw-r--r-- | common/libs/utils/files.h | 2 | ||||
-rw-r--r-- | host/libs/vm_manager/crosvm_manager.cpp | 15 |
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); |