aboutsummaryrefslogtreecommitdiff
path: root/host/commands/run_cvd/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'host/commands/run_cvd/main.cc')
-rw-r--r--host/commands/run_cvd/main.cc384
1 files changed, 236 insertions, 148 deletions
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index f40226a3a..ad684e39a 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -14,51 +14,147 @@
* limitations under the License.
*/
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
#include <unistd.h>
-#include <fstream>
+
+#include <algorithm>
+#include <functional>
#include <iostream>
+#include <fstream>
+#include <iomanip>
#include <memory>
+#include <sstream>
#include <string>
-#include <utility>
+#include <thread>
#include <vector>
-#include <android-base/logging.h>
#include <android-base/strings.h>
#include <gflags/gflags.h>
+#include <android-base/logging.h>
#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/environment.h"
#include "common/libs/utils/files.h"
#include "common/libs/utils/network.h"
-#include "common/libs/utils/size_utils.h"
#include "common/libs/utils/subprocess.h"
+#include "common/libs/utils/size_utils.h"
+#include "host/commands/run_cvd/kernel_args.h"
#include "common/libs/utils/tee_logging.h"
-#include "host/commands/run_cvd/boot_state_machine.h"
#include "host/commands/run_cvd/launch.h"
-#include "host/commands/run_cvd/process_monitor.h"
#include "host/commands/run_cvd/runner_defs.h"
-#include "host/commands/run_cvd/server_loop.h"
+#include "host/commands/run_cvd/process_monitor.h"
#include "host/libs/config/cuttlefish_config.h"
-#include "host/libs/vm_manager/host_configuration.h"
+#include "host/commands/kernel_log_monitor/kernel_log_server.h"
+#include <host/libs/vm_manager/crosvm_manager.h>
#include "host/libs/vm_manager/vm_manager.h"
+#include "host/libs/vm_manager/qemu_manager.h"
-DEFINE_int32(reboot_notification_fd, -1,
- "A file descriptor to notify when boot completes.");
+using vsoc::ForCurrentInstance;
+using cvd::RunnerExitCodes;
-namespace cuttlefish {
+namespace {
-using vm_manager::GetVmManager;
-using vm_manager::ValidateHostConfiguration;
+cvd::OnSocketReadyCb GetOnSubprocessExitCallback(
+ const vsoc::CuttlefishConfig& config) {
+ if (config.restart_subprocesses()) {
+ return cvd::ProcessMonitor::RestartOnExitCb;
+ } else {
+ return cvd::ProcessMonitor::DoNotMonitorCb;
+ }
+}
-namespace {
+// Maintains the state of the boot process, once a final state is reached
+// (success or failure) it sends the appropriate exit code to the foreground
+// launcher process
+class CvdBootStateMachine {
+ public:
+ CvdBootStateMachine(cvd::SharedFD fg_launcher_pipe)
+ : fg_launcher_pipe_(fg_launcher_pipe), state_(kBootStarted) {}
+
+ // Returns true if the machine is left in a final state
+ bool OnBootEvtReceived(cvd::SharedFD boot_events_pipe) {
+ monitor::BootEvent evt;
+ auto bytes_read = boot_events_pipe->Read(&evt, sizeof(evt));
+ if (bytes_read != sizeof(evt)) {
+ LOG(ERROR) << "Fail to read a complete event, read " << bytes_read
+ << " bytes only instead of the expected " << sizeof(evt);
+ state_ |= kGuestBootFailed;
+ } else if (evt == monitor::BootEvent::BootCompleted) {
+ LOG(INFO) << "Virtual device booted successfully";
+ state_ |= kGuestBootCompleted;
+ } else if (evt == monitor::BootEvent::BootFailed) {
+ LOG(ERROR) << "Virtual device failed to boot";
+ state_ |= kGuestBootFailed;
+ } // Ignore the other signals
-constexpr char kGreenColor[] = "\033[1;32m";
-constexpr char kResetColor[] = "\033[0m";
+ return MaybeWriteToForegroundLauncher();
+ }
+
+ bool BootCompleted() const {
+ return state_ & kGuestBootCompleted;
+ }
+
+ bool BootFailed() const {
+ return state_ & kGuestBootFailed;
+ }
-bool WriteCuttlefishEnvironment(const CuttlefishConfig& config) {
- auto env = SharedFD::Open(config.cuttlefish_env_path().c_str(),
- O_CREAT | O_RDWR, 0755);
+ private:
+ void SendExitCode(cvd::RunnerExitCodes exit_code) {
+ fg_launcher_pipe_->Write(&exit_code, sizeof(exit_code));
+ // The foreground process will exit after receiving the exit code, if we try
+ // to write again we'll get a SIGPIPE
+ fg_launcher_pipe_->Close();
+ }
+ bool MaybeWriteToForegroundLauncher() {
+ if (fg_launcher_pipe_->IsOpen()) {
+ if (BootCompleted()) {
+ SendExitCode(cvd::RunnerExitCodes::kSuccess);
+ } else if (state_ & kGuestBootFailed) {
+ SendExitCode(cvd::RunnerExitCodes::kVirtualDeviceBootFailed);
+ } else {
+ // No final state was reached
+ return false;
+ }
+ }
+ // Either we sent the code before or just sent it, in any case the state is
+ // final
+ return true;
+ }
+
+ cvd::SharedFD fg_launcher_pipe_;
+ int state_;
+ static const int kBootStarted = 0;
+ static const int kGuestBootCompleted = 1 << 0;
+ static const int kGuestBootFailed = 1 << 1;
+};
+
+// Abuse the process monitor to make it call us back when boot events are ready
+void SetUpHandlingOfBootEvents(
+ cvd::ProcessMonitor* process_monitor, cvd::SharedFD boot_events_pipe,
+ std::shared_ptr<CvdBootStateMachine> state_machine) {
+ process_monitor->MonitorExistingSubprocess(
+ // A dummy command, so logs are desciptive
+ cvd::Command("boot_events_listener"),
+ // A dummy subprocess, with the boot events pipe as control socket
+ cvd::Subprocess(-1, boot_events_pipe),
+ [boot_events_pipe, state_machine](cvd::MonitorEntry*) {
+ auto sent_code = state_machine->OnBootEvtReceived(boot_events_pipe);
+ return !sent_code;
+ });
+}
+
+bool WriteCuttlefishEnvironment(const vsoc::CuttlefishConfig& config) {
+ auto env = cvd::SharedFD::Open(config.cuttlefish_env_path().c_str(),
+ O_CREAT | O_RDWR, 0755);
if (!env->IsOpen()) {
LOG(ERROR) << "Unable to create cuttlefish.env file";
return false;
@@ -73,12 +169,12 @@ bool WriteCuttlefishEnvironment(const CuttlefishConfig& config) {
// Forks and returns the write end of a pipe to the child process. The parent
// process waits for boot events to come through the pipe and exits accordingly.
-SharedFD DaemonizeLauncher(const CuttlefishConfig& config) {
+cvd::SharedFD DaemonizeLauncher(const vsoc::CuttlefishConfig& config) {
auto instance = config.ForDefaultInstance();
- SharedFD read_end, write_end;
- if (!SharedFD::Pipe(&read_end, &write_end)) {
+ cvd::SharedFD read_end, write_end;
+ if (!cvd::SharedFD::Pipe(&read_end, &write_end)) {
LOG(ERROR) << "Unable to create pipe";
- return {}; // a closed FD
+ return cvd::SharedFD(); // a closed FD
}
auto pid = fork();
if (pid) {
@@ -99,9 +195,9 @@ SharedFD DaemonizeLauncher(const CuttlefishConfig& config) {
LOG(ERROR) << "Unexpected exit code: " << exit_code;
}
if (exit_code == RunnerExitCodes::kSuccess) {
- LOG(INFO) << kBootCompletedMessage;
+ LOG(INFO) << vsoc::kBootCompletedMessage;
} else {
- LOG(INFO) << kBootFailedMessage;
+ LOG(INFO) << vsoc::kBootFailedMessage;
}
std::exit(exit_code);
} else {
@@ -112,15 +208,17 @@ SharedFD DaemonizeLauncher(const CuttlefishConfig& config) {
}
// Redirect standard I/O
auto log_path = instance.launcher_log_path();
- auto log = SharedFD::Open(log_path.c_str(), O_CREAT | O_WRONLY | O_APPEND,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ auto log =
+ cvd::SharedFD::Open(log_path.c_str(), O_CREAT | O_WRONLY | O_APPEND,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (!log->IsOpen()) {
LOG(ERROR) << "Failed to create launcher log file: " << log->StrError();
std::exit(RunnerExitCodes::kDaemonizationError);
}
- ::android::base::SetLogger(
- TeeLogger({{LogFileSeverity(), log, MetadataLevel::FULL}}));
- auto dev_null = SharedFD::Open("/dev/null", O_RDONLY);
+ ::android::base::SetLogger(cvd::TeeLogger({
+ {cvd::LogFileSeverity(), log},
+ }));
+ auto dev_null = cvd::SharedFD::Open("/dev/null", O_RDONLY);
if (!dev_null->IsOpen()) {
LOG(ERROR) << "Failed to open /dev/null: " << dev_null->StrError();
std::exit(RunnerExitCodes::kDaemonizationError);
@@ -143,29 +241,48 @@ SharedFD DaemonizeLauncher(const CuttlefishConfig& config) {
}
}
-std::string GetConfigFilePath(const CuttlefishConfig& config) {
- auto instance = config.ForDefaultInstance();
- return instance.PerInstancePath("cuttlefish_config.json");
+void ServerLoop(cvd::SharedFD server,
+ cvd::ProcessMonitor* process_monitor) {
+ while (true) {
+ // TODO: use select to handle simultaneous connections.
+ auto client = cvd::SharedFD::Accept(*server);
+ cvd::LauncherAction action;
+ while (client->IsOpen() && client->Read(&action, sizeof(action)) > 0) {
+ switch (action) {
+ case cvd::LauncherAction::kStop:
+ if (process_monitor->StopMonitoredProcesses()) {
+ auto response = cvd::LauncherResponse::kSuccess;
+ client->Write(&response, sizeof(response));
+ std::exit(0);
+ } else {
+ auto response = cvd::LauncherResponse::kError;
+ client->Write(&response, sizeof(response));
+ }
+ break;
+ case cvd::LauncherAction::kStatus: {
+ // TODO(schuffelen): Return more information on a side channel
+ auto response = cvd::LauncherResponse::kSuccess;
+ client->Write(&response, sizeof(response));
+ break;
+ }
+ default:
+ LOG(ERROR) << "Unrecognized launcher action: "
+ << static_cast<char>(action);
+ auto response = cvd::LauncherResponse::kError;
+ client->Write(&response, sizeof(response));
+ }
+ }
+ }
}
-void PrintStreamingInformation(const CuttlefishConfig& config) {
- if (config.ForDefaultInstance().start_webrtc_sig_server()) {
- // TODO (jemoreira): Change this when webrtc is moved to the debian package.
- LOG(INFO) << kGreenColor << "Point your browser to https://"
- << config.sig_server_address() << ":" << config.sig_server_port()
- << " to interact with the device." << kResetColor;
- } else if (config.enable_vnc_server()) {
- LOG(INFO) << kGreenColor << "VNC server started on port "
- << config.ForDefaultInstance().vnc_server_port() << kResetColor;
- }
- // When WebRTC is enabled but an operator other than the one launched by
- // run_cvd is used there is no way to know the url to which to point the
- // browser to.
+std::string GetConfigFilePath(const vsoc::CuttlefishConfig& config) {
+ auto instance = config.ForDefaultInstance();
+ return instance.PerInstancePath("cuttlefish_config.json");
}
} // namespace
-int RunCvdMain(int argc, char** argv) {
+int main(int argc, char** argv) {
setenv("ANDROID_LOG_TAGS", "*:v", /* overwrite */ 0);
::android::base::InitLogging(argv, android::base::StderrLogger);
google::ParseCommandLineFlags(&argc, &argv, false);
@@ -173,20 +290,20 @@ int RunCvdMain(int argc, char** argv) {
if (isatty(0)) {
LOG(FATAL) << "stdin was a tty, expected to be passed the output of a previous stage. "
<< "Did you mean to run launch_cvd?";
- return RunnerExitCodes::kInvalidHostConfiguration;
+ return cvd::RunnerExitCodes::kInvalidHostConfiguration;
} else {
int error_num = errno;
if (error_num == EBADF) {
LOG(FATAL) << "stdin was not a valid file descriptor, expected to be passed the output "
<< "of assemble_cvd. Did you mean to run launch_cvd?";
- return RunnerExitCodes::kInvalidHostConfiguration;
+ return cvd::RunnerExitCodes::kInvalidHostConfiguration;
}
}
std::string input_files_str;
{
- auto input_fd = SharedFD::Dup(0);
- auto bytes_read = ReadAll(input_fd, &input_files_str);
+ auto input_fd = cvd::SharedFD::Dup(0);
+ auto bytes_read = cvd::ReadAll(input_fd, &input_files_str);
if (bytes_read < 0) {
LOG(FATAL) << "Failed to read input files. Error was \"" << input_fd->StrError() << "\"";
}
@@ -196,28 +313,24 @@ int RunCvdMain(int argc, char** argv) {
for (const auto& file : input_files) {
if (file.find("cuttlefish_config.json") != std::string::npos) {
found_config = true;
- setenv(kCuttlefishConfigEnvVarName, file.c_str(), /* overwrite */ false);
+ setenv(vsoc::kCuttlefishConfigEnvVarName, file.c_str(), /* overwrite */ false);
}
}
if (!found_config) {
return RunnerExitCodes::kCuttlefishConfigurationInitError;
}
- auto config = CuttlefishConfig::Get();
+ auto config = vsoc::CuttlefishConfig::Get();
auto instance = config->ForDefaultInstance();
auto log_path = instance.launcher_log_path();
{
std::ofstream launcher_log_ofstream(log_path.c_str());
- auto assembly_path = config->AssemblyPath("assemble_cvd.log");
- std::ifstream assembly_log_ifstream(assembly_path);
- if (assembly_log_ifstream) {
- auto assemble_log = ReadFile(assembly_path);
- launcher_log_ofstream << assemble_log;
- }
+ auto assemble_log = cvd::ReadFile(config->AssemblyPath("assemble_cvd.log"));
+ launcher_log_ofstream << assemble_log;
}
- ::android::base::SetLogger(LogToStderrAndFiles({log_path}));
+ ::android::base::SetLogger(cvd::LogToStderrAndFiles({log_path}));
// Change working directory to the instance directory as early as possible to
// ensure all host processes have the same working dir. This helps stop_cvd
@@ -231,24 +344,20 @@ int RunCvdMain(int argc, char** argv) {
return RunnerExitCodes::kInstanceDirCreationError;
}
- auto used_tap_devices = TapInterfacesInUse();
+ auto used_tap_devices = cvd::TapInterfacesInUse();
if (used_tap_devices.count(instance.wifi_tap_name())) {
LOG(ERROR) << "Wifi TAP device already in use";
return RunnerExitCodes::kTapDeviceInUse;
} else if (used_tap_devices.count(instance.mobile_tap_name())) {
LOG(ERROR) << "Mobile TAP device already in use";
return RunnerExitCodes::kTapDeviceInUse;
- } else if (config->ethernet() &&
- used_tap_devices.count(instance.ethernet_tap_name())) {
- LOG(ERROR) << "Ethernet TAP device already in use";
}
- auto vm_manager = GetVmManager(config->vm_manager(), config->target_arch());
+ auto vm_manager = vm_manager::VmManager::Get(config->vm_manager(), config);
-#ifndef __ANDROID__
// Check host configuration
std::vector<std::string> config_commands;
- if (!ValidateHostConfiguration(&config_commands)) {
+ if (!vm_manager->ValidateHostConfiguration(&config_commands)) {
LOG(ERROR) << "Validation of user configuration failed";
std::cout << "Execute the following to correctly configure:" << std::endl;
for (auto& command : config_commands) {
@@ -258,51 +367,31 @@ int RunCvdMain(int argc, char** argv) {
<< std::endl;
return RunnerExitCodes::kInvalidHostConfiguration;
}
-#endif
if (!WriteCuttlefishEnvironment(*config)) {
LOG(ERROR) << "Unable to write cuttlefish environment file";
}
- PrintStreamingInformation(*config);
-
- if (config->console()) {
- LOG(INFO) << kGreenColor << "To access the console run: screen "
- << instance.console_path() << kResetColor;
- } else {
- LOG(INFO) << kGreenColor
- << "Serial console is disabled; use -console=true to enable it"
- << kResetColor;
+ LOG(INFO) << "The following files contain useful debugging information:";
+ if (config->run_as_daemon()) {
+ LOG(INFO) << " Launcher log: " << instance.launcher_log_path();
}
-
- LOG(INFO) << kGreenColor
- << "The following files contain useful debugging information:"
- << kResetColor;
- LOG(INFO) << kGreenColor
- << " Launcher log: " << instance.launcher_log_path()
- << kResetColor;
- LOG(INFO) << kGreenColor
- << " Android's logcat output: " << instance.logcat_path()
- << kResetColor;
- LOG(INFO) << kGreenColor
- << " Kernel log: " << instance.PerInstancePath("kernel.log")
- << kResetColor;
- LOG(INFO) << kGreenColor
- << " Instance configuration: " << GetConfigFilePath(*config)
- << kResetColor;
- LOG(INFO) << kGreenColor
- << " Instance environment: " << config->cuttlefish_env_path()
- << kResetColor;
+ LOG(INFO) << " Android's logcat output: " << instance.logcat_path();
+ LOG(INFO) << " Kernel log: " << instance.PerInstancePath("kernel.log");
+ LOG(INFO) << " Instance configuration: " << GetConfigFilePath(*config);
+ LOG(INFO) << " Instance environment: " << config->cuttlefish_env_path();
+ LOG(INFO) << "To access the console run: socat file:$(tty),raw,echo=0 "
+ << instance.console_path();
auto launcher_monitor_path = instance.launcher_monitor_socket_path();
- auto launcher_monitor_socket = SharedFD::SocketLocalServer(
+ auto launcher_monitor_socket = cvd::SharedFD::SocketLocalServer(
launcher_monitor_path.c_str(), false, SOCK_STREAM, 0666);
if (!launcher_monitor_socket->IsOpen()) {
LOG(ERROR) << "Error when opening launcher server: "
<< launcher_monitor_socket->StrError();
- return RunnerExitCodes::kMonitorCreationFailed;
+ return cvd::RunnerExitCodes::kMonitorCreationFailed;
}
- SharedFD foreground_launcher_pipe;
+ cvd::SharedFD foreground_launcher_pipe;
if (config->run_as_daemon()) {
foreground_launcher_pipe = DaemonizeLauncher(*config);
if (!foreground_launcher_pipe->IsOpen()) {
@@ -320,70 +409,69 @@ int RunCvdMain(int argc, char** argv) {
}
}
- SharedFD reboot_notification;
- if (FLAGS_reboot_notification_fd >= 0) {
- reboot_notification = SharedFD::Dup(FLAGS_reboot_notification_fd);
- close(FLAGS_reboot_notification_fd);
- }
+ auto boot_state_machine =
+ std::make_shared<CvdBootStateMachine>(foreground_launcher_pipe);
// Monitor and restart host processes supporting the CVD
- ProcessMonitor process_monitor(config->restart_subprocesses());
+ cvd::ProcessMonitor process_monitor;
- if (config->enable_metrics() == CuttlefishConfig::kYes) {
- process_monitor.AddCommands(LaunchMetrics());
- }
- process_monitor.AddCommands(LaunchModemSimulatorIfEnabled(*config));
-
- auto kernel_log_monitor = LaunchKernelLogMonitor(*config, 3);
- SharedFD boot_events_pipe = kernel_log_monitor.pipes[0];
- SharedFD adbd_events_pipe = kernel_log_monitor.pipes[1];
- SharedFD webrtc_events_pipe = kernel_log_monitor.pipes[2];
- kernel_log_monitor.pipes.clear();
- process_monitor.AddCommands(std::move(kernel_log_monitor.commands));
-
- CvdBootStateMachine boot_state_machine(foreground_launcher_pipe,
- reboot_notification, boot_events_pipe);
-
- process_monitor.AddCommands(LaunchRootCanal(*config));
- process_monitor.AddCommands(LaunchLogcatReceiver(*config));
- process_monitor.AddCommands(LaunchConfigServer(*config));
- process_monitor.AddCommands(LaunchTombstoneReceiver(*config));
- process_monitor.AddCommands(LaunchGnssGrpcProxyServerIfEnabled(*config));
- process_monitor.AddCommands(LaunchSecureEnvironment(*config));
- if (config->enable_host_bluetooth()) {
- process_monitor.AddCommands(LaunchBluetoothConnector(*config));
- }
- process_monitor.AddCommands(LaunchVehicleHalServerIfEnabled(*config));
- process_monitor.AddCommands(LaunchConsoleForwarderIfEnabled(*config));
+ auto event_pipes =
+ LaunchKernelLogMonitor(*config, &process_monitor, 2);
+ cvd::SharedFD boot_events_pipe = event_pipes[0];
+ cvd::SharedFD adbd_events_pipe = event_pipes[1];
+ event_pipes.clear();
+
+ std::set<std::string> extra_kernel_cmdline;
+
+ SetUpHandlingOfBootEvents(&process_monitor, boot_events_pipe,
+ boot_state_machine);
+
+ auto logcat_server = LaunchLogcatReceiverIfEnabled(*config, &process_monitor);
+ auto logcat_server_args = KernelCommandLineFromLogcatServer(logcat_server);
+
+ auto config_server = LaunchConfigServer(*config, &process_monitor);
+ auto config_server_args = KernelCommandLineFromConfigServer(config_server);
+
+ auto tombstone_server = LaunchTombstoneReceiverIfEnabled(*config, &process_monitor);
+ auto tombstone_kernel_args = KernelCommandLineFromTombstone(tombstone_server);
+
+ LaunchVerhicleHalServerIfEnabled(*config, &process_monitor);
// The streamer needs to launch before the VMM because it serves on several
// sockets (input devices, vsock frame server) when using crosvm.
+ StreamerLaunchResult streamer_config;
if (config->enable_vnc_server()) {
- process_monitor.AddCommands(LaunchVNCServer(*config));
+ streamer_config = LaunchVNCServer(
+ *config, &process_monitor, GetOnSubprocessExitCallback(*config));
}
if (config->enable_webrtc()) {
- process_monitor.AddCommands(LaunchWebRTC(*config, webrtc_events_pipe));
+ streamer_config = LaunchWebRTC(&process_monitor, *config);
}
+ auto streamer_kernel_args = KernelCommandLineFromStreamer(streamer_config);
+
+ auto kernel_args = KernelCommandLineFromConfig(*config);
+ kernel_args.insert(kernel_args.end(), streamer_kernel_args.begin(),
+ streamer_kernel_args.end());
+ kernel_args.insert(kernel_args.end(), tombstone_kernel_args.begin(),
+ tombstone_kernel_args.end());
+ kernel_args.insert(kernel_args.end(), config_server_args.begin(), config_server_args.end());
+ kernel_args.insert(kernel_args.end(), logcat_server_args.begin(), logcat_server_args.end());
+
// Start the guest VM
- process_monitor.AddCommands(vm_manager->StartCommands(*config));
+ vm_manager->WithFrontend(streamer_config.launched);
+ vm_manager->WithKernelCommandLine(android::base::Join(kernel_args, " "));
+ auto vmm_commands = vm_manager->StartCommands();
+ for (auto& vmm_cmd: vmm_commands) {
+ process_monitor.StartSubprocess(std::move(vmm_cmd),
+ GetOnSubprocessExitCallback(*config));
+ }
// Start other host processes
- process_monitor.AddCommands(
- LaunchSocketVsockProxyIfEnabled(*config, adbd_events_pipe));
- process_monitor.AddCommands(LaunchAdbConnectorIfEnabled(*config));
-
- CHECK(process_monitor.StartAndMonitorProcesses())
- << "Could not start subprocesses";
+ LaunchSocketVsockProxyIfEnabled(&process_monitor, *config);
+ LaunchAdbConnectorIfEnabled(&process_monitor, *config, adbd_events_pipe);
ServerLoop(launcher_monitor_socket, &process_monitor); // Should not return
LOG(ERROR) << "The server loop returned, it should never happen!!";
-
- return RunnerExitCodes::kServerError;
-}
-
-} // namespace cuttlefish
-
-int main(int argc, char** argv) {
- return cuttlefish::RunCvdMain(argc, argv);
+ return cvd::RunnerExitCodes::kServerError;
}