// Copyright (C) 2019 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. #ifndef PREFETCHER_DAEMON_H_ #define PREFETCHER_DAEMON_H_ #include "prefetcher/session_manager.h" #include #include #include namespace iorap { namespace prefetcher { struct PrefetcherForkParameters { int input_fd; int output_fd; bool use_sockets; // use the socket path instead of simpler read/write path. bool format_text; // true=>text, false=>binary }; inline std::ostream& operator<<(std::ostream& os, const PrefetcherForkParameters& p) { os << "PrefetcherForkParameters{"; os << "input_fd=" << p.input_fd << ","; os << "output_fd=" << p.output_fd << ","; os << "format_text=" << p.format_text << ","; os << "use_sockets=" << p.use_sockets << ","; os << "}"; return os; } #ifndef READ_AHEAD_KIND enum class ReadAheadKind : uint32_t { kFadvise = 0, kMmapLocked = 1, kMlock = 2, }; #define READ_AHEAD_KIND 1 #endif std::ostream& operator<<(std::ostream& os, ReadAheadKind k); enum class CommandChoice : uint32_t { kRegisterFilePath, // kRegisterFilePath kUnregisterFilePath, // kUnregisterFilePath kReadAhead, // kReadAhead kExit, // kExit kCreateSession, // kCreateSession kDestroySession, // kDestroySession kDumpSession, // kDumpSession kDumpEverything, // kDumpEverything kCreateFdSession, // kCreateFdSession $CMSG{} }; struct Command { CommandChoice choice; uint32_t session_id; uint32_t id; // file_path_id std::optional file_path; // required for choice=kRegisterFilePath. // also serves as the description for choice=kCreateSession // choice=kReadAhead ReadAheadKind read_ahead_kind; uint64_t length; uint64_t offset; std::optional fd; // only valid in kCreateFdSession. // Deserialize from a char buffer. // This can only fail if buf_size is too small. static std::optional Read(char* buf, size_t buf_size, /*out*/size_t* consumed_bytes); // Serialize to a char buffer. // This can only fail if the buf_size is too small. bool Write(char* buf, size_t buf_size, /*out*/size_t* produced_bytes) const; bool RequiresFd() const { return choice == CommandChoice::kCreateFdSession; } }; std::ostream& operator<<(std::ostream& os, const Command& command); class PrefetcherDaemon { public: PrefetcherDaemon(); ~PrefetcherDaemon(); // Asynchronously launch a new fork. // // The destructor will waitpid automatically on the child process. bool StartViaFork(PrefetcherForkParameters params); // Launch a new fork , returning the pipes as input/output fds. std::optional StartPipesViaFork(); // Launch a new fork , returning the socket pair as input/output fds. std::optional StartSocketViaFork(); // Execute the main code in-process. // // Intended as the execve target. bool Main(PrefetcherForkParameters params); // Send a command via IPC. // The caller must be the parent process after using StartViaFork. bool SendCommand(const Command& command); private: class Impl; std::unique_ptr impl_; }; } // namespace prefetcher } // namespace iorap #endif