unplugged-system/device/google/cuttlefish/host/libs/command_util/util.cc

104 lines
3.8 KiB
C++

/*
* 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/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) {
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<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