1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SRC_TRACED_PROBES_PROBES_PRODUCER_H_ 18 #define SRC_TRACED_PROBES_PROBES_PRODUCER_H_ 19 20 #include <map> 21 #include <memory> 22 #include <utility> 23 24 #include "perfetto/base/task_runner.h" 25 #include "perfetto/base/watchdog.h" 26 #include "perfetto/ftrace_reader/ftrace_controller.h" 27 #include "perfetto/tracing/core/producer.h" 28 #include "perfetto/tracing/core/trace_writer.h" 29 #include "perfetto/tracing/ipc/producer_ipc_client.h" 30 #include "src/traced/probes/filesystem/inode_file_data_source.h" 31 #include "src/traced/probes/process_stats_data_source.h" 32 33 #include "perfetto/trace/filesystem/inode_file_map.pbzero.h" 34 35 namespace perfetto { 36 37 const uint64_t kLRUInodeCacheSize = 1000; 38 39 class ProbesProducer : public Producer { 40 public: 41 ProbesProducer(); 42 ~ProbesProducer() override; 43 44 // Producer Impl: 45 void OnConnect() override; 46 void OnDisconnect() override; 47 void CreateDataSourceInstance(DataSourceInstanceID, 48 const DataSourceConfig&) override; 49 void TearDownDataSourceInstance(DataSourceInstanceID) override; 50 void OnTracingSetup() override; 51 void Flush(FlushRequestID, 52 const DataSourceInstanceID* data_source_ids, 53 size_t num_data_sources) override; 54 55 // Our Impl 56 void ConnectWithRetries(const char* socket_name, 57 base::TaskRunner* task_runner); 58 bool CreateFtraceDataSourceInstance(TracingSessionID session_id, 59 DataSourceInstanceID id, 60 const DataSourceConfig& config); 61 void CreateProcessStatsDataSourceInstance(TracingSessionID session_id, 62 DataSourceInstanceID id, 63 const DataSourceConfig& config); 64 void CreateInodeFileDataSourceInstance(TracingSessionID session_id, 65 DataSourceInstanceID id, 66 DataSourceConfig config); 67 68 void OnMetadata(const FtraceMetadata& metadata); 69 70 private: 71 using FtraceBundleHandle = 72 protozero::MessageHandle<protos::pbzero::FtraceEventBundle>; 73 using FtraceStatsHandle = 74 protozero::MessageHandle<protos::pbzero::FtraceStats>; 75 76 class SinkDelegate : public FtraceSink::Delegate { 77 public: 78 SinkDelegate(TracingSessionID, 79 base::TaskRunner*, 80 std::unique_ptr<TraceWriter>); 81 ~SinkDelegate() override; 82 session_id()83 TracingSessionID session_id() const { return session_id_; } 84 85 void Flush(); 86 87 // FtraceDelegateImpl 88 FtraceBundleHandle GetBundleForCpu(size_t cpu) override; 89 void OnBundleComplete(size_t cpu, 90 FtraceBundleHandle bundle, 91 const FtraceMetadata& metadata) override; 92 void OnCreate(FtraceSink*) override; 93 94 void WriteStats(); 95 set_sink(std::unique_ptr<FtraceSink> sink)96 void set_sink(std::unique_ptr<FtraceSink> sink) { sink_ = std::move(sink); } 97 set_ps_source(base::WeakPtr<ProcessStatsDataSource> ptr)98 void set_ps_source(base::WeakPtr<ProcessStatsDataSource> ptr) { 99 ps_source_ = std::move(ptr); 100 } ps_source()101 const base::WeakPtr<ProcessStatsDataSource>& ps_source() const { 102 return ps_source_; 103 } 104 set_file_source(base::WeakPtr<InodeFileDataSource> ptr)105 void set_file_source(base::WeakPtr<InodeFileDataSource> ptr) { 106 file_source_ = std::move(ptr); 107 } file_source()108 const base::WeakPtr<InodeFileDataSource>& file_source() const { 109 return file_source_; 110 } 111 112 private: 113 const TracingSessionID session_id_; 114 base::TaskRunner* task_runner_; 115 std::unique_ptr<FtraceSink> sink_ = nullptr; 116 std::unique_ptr<TraceWriter> writer_; 117 FtraceStats stats_before_ = {}; 118 119 base::WeakPtr<ProcessStatsDataSource> ps_source_; 120 base::WeakPtr<InodeFileDataSource> file_source_; 121 122 // Keep this after the TraceWriter because TracePackets must not outlive 123 // their originating writer. 124 TraceWriter::TracePacketHandle trace_packet_; 125 126 // Keep this last. 127 base::WeakPtrFactory<SinkDelegate> weak_factory_; 128 }; 129 130 enum State { 131 kNotStarted = 0, 132 kNotConnected, 133 kConnecting, 134 kConnected, 135 }; 136 137 ProbesProducer(const ProbesProducer&) = delete; 138 ProbesProducer& operator=(const ProbesProducer&) = delete; 139 140 void Connect(); 141 void Restart(); 142 void ResetConnectionBackoff(); 143 void IncreaseConnectionBackoff(); 144 void AddWatchdogsTimer(DataSourceInstanceID id, 145 const DataSourceConfig& source_config); 146 147 State state_ = kNotStarted; 148 base::TaskRunner* task_runner_ = nullptr; 149 std::unique_ptr<Service::ProducerEndpoint> endpoint_ = nullptr; 150 std::unique_ptr<FtraceController> ftrace_ = nullptr; 151 bool ftrace_creation_failed_ = false; 152 uint32_t connection_backoff_ms_ = 0; 153 const char* socket_name_ = nullptr; 154 std::set<DataSourceInstanceID> failed_sources_; 155 std::map<DataSourceInstanceID, std::unique_ptr<ProcessStatsDataSource>> 156 process_stats_sources_; 157 std::map<DataSourceInstanceID, std::unique_ptr<SinkDelegate>> delegates_; 158 std::map<DataSourceInstanceID, base::Watchdog::Timer> watchdogs_; 159 std::map<DataSourceInstanceID, std::unique_ptr<InodeFileDataSource>> 160 file_map_sources_; 161 LRUInodeCache cache_{kLRUInodeCacheSize}; 162 std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>> 163 system_inodes_; 164 }; 165 166 } // namespace perfetto 167 168 #endif // SRC_TRACED_PROBES_PROBES_PRODUCER_H_ 169