1 // Copyright (C) 2019 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef PREFETCHER_DAEMON_H_ 16 #define PREFETCHER_DAEMON_H_ 17 18 #include "prefetcher/session_manager.h" 19 20 #include <memory> 21 #include <optional> 22 #include <ostream> 23 24 namespace iorap { 25 namespace prefetcher { 26 27 struct PrefetcherForkParameters { 28 int input_fd; 29 int output_fd; 30 bool use_sockets; // use the socket path instead of simpler read/write path. 31 bool format_text; // true=>text, false=>binary 32 }; 33 34 inline std::ostream& operator<<(std::ostream& os, const PrefetcherForkParameters& p) { 35 os << "PrefetcherForkParameters{"; 36 os << "input_fd=" << p.input_fd << ","; 37 os << "output_fd=" << p.output_fd << ","; 38 os << "format_text=" << p.format_text << ","; 39 os << "use_sockets=" << p.use_sockets << ","; 40 os << "}"; 41 return os; 42 } 43 44 45 #ifndef READ_AHEAD_KIND 46 enum class ReadAheadKind : uint32_t { 47 kFadvise = 0, 48 kMmapLocked = 1, 49 kMlock = 2, 50 }; 51 #define READ_AHEAD_KIND 1 52 #endif 53 54 std::ostream& operator<<(std::ostream& os, ReadAheadKind k); 55 56 enum class CommandChoice : uint32_t { 57 kRegisterFilePath, // kRegisterFilePath <sid:uint32> <id:uint32> <path:c-string> 58 kUnregisterFilePath, // kUnregisterFilePath <sid:uint32> <id:uint32> 59 kReadAhead, // kReadAhead <sid:uint32> <id:uint32> <kind:uint32_t> <length:uint64> <offset:uint64> 60 kExit, // kExit 61 kCreateSession, // kCreateSession <sid:uint32> <description:c-string> 62 kDestroySession, // kDestroySession <sid:uint32> 63 kDumpSession, // kDumpSession <sid:uint32> 64 kDumpEverything, // kDumpEverything 65 kCreateFdSession, // kCreateFdSession $CMSG{<fd:int>} <sid:uint32> <description:c-string> 66 }; 67 68 struct Command { 69 CommandChoice choice; 70 uint32_t session_id; 71 uint32_t id; // file_path_id 72 std::optional<std::string> file_path; // required for choice=kRegisterFilePath. 73 // also serves as the description for choice=kCreateSession 74 75 // choice=kReadAhead 76 ReadAheadKind read_ahead_kind; 77 uint64_t length; 78 uint64_t offset; 79 80 std::optional<int> fd; // only valid in kCreateFdSession. 81 82 // Deserialize from a char buffer. 83 // This can only fail if buf_size is too small. 84 static std::optional<Command> Read(char* buf, size_t buf_size, /*out*/size_t* consumed_bytes); 85 // Serialize to a char buffer. 86 // This can only fail if the buf_size is too small. 87 bool Write(char* buf, size_t buf_size, /*out*/size_t* produced_bytes) const; 88 RequiresFdCommand89 bool RequiresFd() const { 90 return choice == CommandChoice::kCreateFdSession; 91 } 92 }; 93 94 std::ostream& operator<<(std::ostream& os, const Command& command); 95 96 class PrefetcherDaemon { 97 public: 98 PrefetcherDaemon(); 99 ~PrefetcherDaemon(); 100 101 // Asynchronously launch a new fork. 102 // 103 // The destructor will waitpid automatically on the child process. 104 bool StartViaFork(PrefetcherForkParameters params); 105 106 // Launch a new fork , returning the pipes as input/output fds. 107 std::optional<PrefetcherForkParameters> StartPipesViaFork(); 108 109 // Launch a new fork , returning the socket pair as input/output fds. 110 std::optional<PrefetcherForkParameters> StartSocketViaFork(); 111 112 // Execute the main code in-process. 113 // 114 // Intended as the execve target. 115 bool Main(PrefetcherForkParameters params); 116 117 // Send a command via IPC. 118 // The caller must be the parent process after using StartViaFork. 119 bool SendCommand(const Command& command); 120 121 private: 122 class Impl; 123 std::unique_ptr<PrefetcherDaemon::Impl> impl_; 124 }; 125 126 } // namespace prefetcher 127 } // namespace iorap 128 129 #endif 130 131