blob: f87b06fcbdc2f18c4f6d48441de842d05fd67ae0 [file] [log] [blame]
/*
* 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 <string>
#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/command_util/launcher_message.h"
#include "host/libs/config/cuttlefish_config.h"
namespace cuttlefish {
namespace {
template <typename T>
Result<T> 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<LauncherResponse> ReadLauncherResponse(const SharedFD& monitor_socket) {
return ReadFromMonitor<LauncherResponse>(monitor_socket);
}
Result<RunnerExitCodes> ReadExitCode(const SharedFD& monitor_socket) {
return ReadFromMonitor<RunnerExitCodes>(monitor_socket);
}
Result<SharedFD> 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<SharedFD> 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<void> WriteLauncherAction(const SharedFD& monitor_socket,
const LauncherAction request) {
CF_EXPECT(WriteLauncherActionWithData(monitor_socket, request,
ExtendedActionType::kUnused, ""));
return {};
}
Result<void> WriteLauncherActionWithData(const SharedFD& monitor_socket,
const LauncherAction request,
const ExtendedActionType type,
std::string serialized_data) {
using run_cvd_msg_impl::LauncherActionMessage;
auto message = CF_EXPECT(
LauncherActionMessage::Create(request, type, std::move(serialized_data)));
CF_EXPECT(message.WriteToFd(monitor_socket));
return {};
}
Result<LauncherActionInfo> ReadLauncherActionFromFd(
const SharedFD& monitor_socket) {
using run_cvd_msg_impl::LauncherActionMessage;
auto message = CF_EXPECT(LauncherActionMessage::ReadFromFd(monitor_socket));
return LauncherActionInfo{
.action = message.Action(),
.type = message.Type(),
.serialized_data = message.SerializedData(),
};
}
Result<void> 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