• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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