/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "host/libs/command_util/util.h" #include "sys/time.h" #include "sys/types.h" #include #include "common/libs/fs/shared_buf.h" #include "common/libs/fs/shared_fd.h" #include "common/libs/fs/shared_select.h" #include "common/libs/utils/result.h" #include "host/commands/run_cvd/runner_defs.h" #include "host/libs/config/cuttlefish_config.h" namespace cuttlefish { namespace { template Result ReadFromMonitor(const SharedFD& monitor_socket) { T response; ssize_t bytes_recv = ReadExactBinary(monitor_socket, &response); CF_EXPECT(bytes_recv != 0, "Launcher socket closed unexpectedly"); CF_EXPECT(bytes_recv > 0, "Error receiving response from launcher monitor: " << monitor_socket->StrError()); CF_EXPECT(bytes_recv == sizeof(response), "Launcher response not correct number of bytes"); return response; } } // namespace Result ReadLauncherResponse(const SharedFD& monitor_socket) { return ReadFromMonitor(monitor_socket); } Result ReadExitCode(const SharedFD& monitor_socket) { return ReadFromMonitor(monitor_socket); } Result GetLauncherMonitorFromInstance( const CuttlefishConfig::InstanceSpecific& instance_config, const int timeout_seconds) { std::string monitor_path = instance_config.launcher_monitor_socket_path(); CF_EXPECT(!monitor_path.empty(), "No path to launcher monitor found"); SharedFD monitor_socket = SharedFD::SocketLocalClient( monitor_path.c_str(), false, SOCK_STREAM, timeout_seconds); CF_EXPECT(monitor_socket->IsOpen(), "Unable to connect to launcher monitor at " << monitor_path << ":" << monitor_socket->StrError()); return monitor_socket; } Result GetLauncherMonitor(const CuttlefishConfig& config, const int instance_num, const int timeout_seconds) { auto instance_config = config.ForInstance(instance_num); return GetLauncherMonitorFromInstance(instance_config, timeout_seconds); } Result WriteLauncherAction(const SharedFD& monitor_socket, const LauncherAction request) { ssize_t bytes_sent = WriteAllBinary(monitor_socket, &request); CF_EXPECT(bytes_sent > 0, "Error sending launcher monitor the command: " << monitor_socket->StrError()); CF_EXPECT(bytes_sent == sizeof(request), "Launcher did not send correct number of bytes"); return {}; } Result WaitForRead(const SharedFD& monitor_socket, const int timeout_seconds) { // Perform a select with a timeout to guard against launcher hanging SharedFDSet read_set; read_set.Set(monitor_socket); struct timeval timeout = {timeout_seconds, 0}; int select_result = Select(&read_set, nullptr, nullptr, timeout_seconds <= 0 ? nullptr : &timeout); CF_EXPECT(select_result != 0, "Timeout expired waiting for launcher monitor to respond"); CF_EXPECT( select_result > 0, "Failed communication with the launcher monitor: " << strerror(errno)); return {}; } } // namespace cuttlefish