/* * 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. */ #pragma once #include #include #include #include #include #include #include #include "cvd_server.pb.h" #include "common/libs/fs/epoll.h" #include "common/libs/fs/shared_fd.h" #include "common/libs/utils/subprocess.h" #include "common/libs/utils/unix_sockets.h" #include "host/commands/cvd/epoll_loop.h" #include "host/commands/cvd/instance_manager.h" #include "host/commands/cvd/logger.h" // including "server_command/subcmd.h" causes cyclic dependency #include "host/commands/cvd/server_command/host_tool_target_manager.h" #include "host/commands/cvd/server_command/server_handler.h" #include "host/libs/config/inject.h" #include "host/libs/web/build_api.h" namespace cuttlefish { struct ServerMainParam { SharedFD internal_server_fd; SharedFD carryover_client_fd; std::optional memory_carryover_fd; std::unique_ptr server_logger; /* scoped logger that carries the stderr of the carried-over * client. The client may have called "cvd restart-server." * * The scoped_logger should expire just after AcceptCarryoverClient() */ std::unique_ptr scoped_logger; }; Result CvdServerMain(ServerMainParam&& fds); class CvdServer { // for server_logger_. // server_logger_ shouldn't be exposed to anything but CvdServerMain() friend Result CvdServerMain(ServerMainParam&& fds); public: INJECT(CvdServer(BuildApi&, EpollPool&, InstanceManager&, HostToolTargetManager&, ServerLogger&)); ~CvdServer(); Result StartServer(SharedFD server); struct ExecParam { SharedFD new_exe; SharedFD carryover_client_fd; // the client that called cvd restart-server std::optional in_memory_data_fd; // fd to carry over in-memory data SharedFD client_stderr_fd; bool verbose; }; Result Exec(const ExecParam&); Result AcceptCarryoverClient( SharedFD client, std::unique_ptr scoped_logger); void Stop(); void Join(); Result InstanceDbFromJson(const std::string& json_string); private: struct OngoingRequest { CvdServerHandler* handler; std::mutex mutex; std::thread::id thread_id; }; /* this has to be static due to the way fruit includes components */ static fruit::Component<> RequestComponent(CvdServer*); Result AcceptClient(EpollEvent); Result HandleMessage(EpollEvent); Result HandleRequest(RequestWithStdio, SharedFD client); Result BestEffortWakeup(); SharedFD server_fd_; BuildApi& build_api_; EpollPool& epoll_pool_; InstanceManager& instance_manager_; HostToolTargetManager& host_tool_target_manager_; ServerLogger& server_logger_; std::atomic_bool running_ = true; std::mutex ongoing_requests_mutex_; std::set> ongoing_requests_; // TODO(schuffelen): Move this thread pool to another class. std::mutex threads_mutex_; std::vector threads_; // translator optout std::atomic optout_; }; Result RequestHandler( const RequestWithStdio& request, const std::vector& handlers); // Read all contents from the file Result ReadAllFromMemFd(const SharedFD& mem_fd); } // namespace cuttlefish