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 IORAP_SRC_INODE2FILENAME_INODE_RESOLVER_H_ 16 #define IORAP_SRC_INODE2FILENAME_INODE_RESOLVER_H_ 17 18 #include "common/expected.h" 19 #include "inode2filename/data_source.h" 20 #include "inode2filename/inode.h" 21 #include "inode2filename/system_call.h" 22 23 #include <rxcpp/rx.hpp> 24 25 #include <memory> 26 #include <optional> 27 #include <string> 28 #include <vector> 29 namespace iorap::inode2filename { 30 31 enum class ProcessMode { 32 // Test modes: 33 kInProcessDirect, // Execute the code directly. 34 kInProcessIpc, // Execute code via IPC layer using multiple threads. 35 // Shipping mode: 36 kOutOfProcessIpc, // Execute code via fork+exec with IPC. 37 38 // Note: in-process system-wide stat(2)/readdir/etc is blocked by selinux. 39 // Attempting to call the test modes will fail with -EPERM. 40 // 41 // Use fork+exec mode in shipping configurations, which spawns inode2filename 42 // as a separate command. 43 }; 44 45 enum class VerifyKind { 46 kNone, 47 kStat, 48 }; 49 50 std::vector<std::string> ToArgs(VerifyKind verify_kind); 51 52 struct InodeResolverDependencies : public DataSourceDependencies { 53 ProcessMode process_mode = ProcessMode::kInProcessDirect; 54 VerifyKind verify{VerifyKind::kStat}; // Filter out results that aren't up-to-date with stat(2) ? 55 }; 56 57 std::vector<std::string> ToArgs(const InodeResolverDependencies& deps); 58 59 // Create an rx-observable chain that allows searching for inode->filename mappings given 60 // a set of inode keys. 61 class InodeResolver : public std::enable_shared_from_this<InodeResolver> { 62 public: 63 static std::shared_ptr<InodeResolver> Create(InodeResolverDependencies dependencies, 64 std::shared_ptr<DataSource> data_source); // nonnull 65 66 // Convenience function for above: Uses DataSource::Create for the data-source. 67 static std::shared_ptr<InodeResolver> Create(InodeResolverDependencies dependencies); 68 69 // Search the associated data source to map each inode in 'inodes' to a file path. 70 // 71 // Observes DataSource::EmitInodes(), which is unsubscribed from early once all inodes are found. 72 // 73 // Notes: 74 // * Searching does not begin until all 'inodes' are observed to avoid rescanning. 75 // * If the observable is unsubscribed to prior to completion, searching will halt. 76 // 77 // Post-condition: All emitted results are in inodes, and all inodes are in emitted results. 78 rxcpp::observable<InodeResult> 79 FindFilenamesFromInodes(rxcpp::observable<Inode> inodes) const; 80 // TODO: feels like we could turn this into a general helper? 81 // Convenience function for above. 82 virtual rxcpp::observable<InodeResult> 83 FindFilenamesFromInodes(std::vector<Inode> inodes) const; 84 85 // Enumerate *all* inodes available from the data source, associating it with a filepath. 86 // 87 // Depending on the data source (e.g. diskscan), it can take a very long time for this observable 88 // to complete. The intended use-case is for development/debugging, not for production. 89 // 90 // Observes DataSource::EmitInodes() until it reaches #on_completed. 91 // 92 // Notes: 93 // * If the observable is unsubscribed to prior to completion, searching will halt. 94 virtual rxcpp::observable<InodeResult> 95 EmitAll() const; 96 97 // Notifies the DataSource to begin recording. 98 // Some DataSources may be continuously refreshing, but only if recording is enabled. 99 // To get the most up-to-date data, toggle recording before reading the inodes out. 100 void StartRecording(); // XX: feels like this should be BPF-specific. 101 102 // Notifies the DataSource to stop recording. 103 // Some DataSources may be continuously refreshing, but only if recording is enabled. 104 // The snapshot of data returned by e.g. #EmitAll would then not change outside of recording. 105 void StopRecording(); 106 107 virtual ~InodeResolver(); 108 private: 109 struct Impl; 110 Impl* impl_; 111 112 protected: 113 InodeResolver(InodeResolverDependencies dependencies); 114 InodeResolver(InodeResolverDependencies dependencies, std::shared_ptr<DataSource> data_source); 115 InodeResolverDependencies& GetDependencies(); 116 const InodeResolverDependencies& GetDependencies() const; 117 }; 118 119 } 120 121 #endif // IORAP_SRC_INODE2FILENAME_INODE_RESOLVER_H_ 122