probes_producer: Add initial code to put inodes into their own trace packet
Bug: 73625480
Change-Id: I6fa2e9b7dc4d378a0f57bf049af7a8c6d7833a82
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 7a36f32..718e51f 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -17,6 +17,7 @@
#include "src/traced/probes/probes_producer.h"
#include <stdio.h>
+#include <queue>
#include <string>
#include "perfetto/base/logging.h"
@@ -30,6 +31,7 @@
#include "src/process_stats/file_utils.h"
#include "src/process_stats/procfs_utils.h"
+#include "perfetto/trace/filesystem/inode_file_map.pbzero.h"
#include "perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "perfetto/trace/ps/process_tree.pbzero.h"
#include "perfetto/trace/trace_packet.pbzero.h"
@@ -41,6 +43,7 @@
uint64_t kMaxConnectionBackoffMs = 30 * 1000;
const char* kFtraceSourceName = "com.google.perfetto.ftrace";
const char* kProcessStatsSourceName = "com.google.perfetto.process_stats";
+const char* kInodeFileMapSourceName = "com.google.perfetto.inode_file_map";
} // namespace.
@@ -69,6 +72,11 @@
process_stats_descriptor.set_name(kProcessStatsSourceName);
endpoint_->RegisterDataSource(process_stats_descriptor,
[](DataSourceInstanceID) {});
+
+ DataSourceDescriptor inode_map_descriptor;
+ inode_map_descriptor.set_name(kInodeFileMapSourceName);
+ endpoint_->RegisterDataSource(inode_map_descriptor,
+ [](DataSourceInstanceID) {});
}
void ProbesProducer::OnDisconnect() {
@@ -90,12 +98,21 @@
CreateFtraceDataSourceInstance(id, source_config);
} else if (source_config.name() == kProcessStatsSourceName) {
CreateProcessStatsDataSourceInstance(source_config);
+ } else if (source_config.name() == kInodeFileMapSourceName) {
+ CreateInodeFileMapDataSourceInstance(id, source_config);
} else {
PERFETTO_ELOG("Data source name: %s not recognised.",
source_config.name().c_str());
}
}
+void ProbesProducer::AddWatchdogsTimer(DataSourceInstanceID id,
+ const DataSourceConfig& source_config) {
+ if (source_config.trace_duration_ms() != 0)
+ watchdogs_.emplace(id, base::Watchdog::GetInstance()->CreateFatalTimer(
+ 5000 + 2 * source_config.trace_duration_ms()));
+}
+
void ProbesProducer::CreateFtraceDataSourceInstance(
DataSourceInstanceID id,
const DataSourceConfig& source_config) {
@@ -136,9 +153,20 @@
}
delegate->sink(std::move(sink));
delegates_.emplace(id, std::move(delegate));
- if (source_config.trace_duration_ms() != 0)
- watchdogs_.emplace(id, base::Watchdog::GetInstance()->CreateFatalTimer(
- 5000 + 2 * source_config.trace_duration_ms()));
+ AddWatchdogsTimer(id, source_config);
+}
+
+void ProbesProducer::CreateInodeFileMapDataSourceInstance(
+ DataSourceInstanceID id,
+ const DataSourceConfig& source_config) {
+ PERFETTO_LOG("Inode file map start (id=%" PRIu64 ", target_buf=%" PRIu32 ")",
+ id, source_config.target_buffer());
+ auto trace_writer = endpoint_->CreateTraceWriter(
+ static_cast<BufferID>(source_config.target_buffer()));
+ auto file_map_source = std::unique_ptr<InodeFileMapDataSource>(
+ new InodeFileMapDataSource(std::move(trace_writer)));
+ file_map_sources_.emplace(id, std::move(file_map_source));
+ AddWatchdogsTimer(id, source_config);
}
void ProbesProducer::CreateProcessStatsDataSourceInstance(
@@ -180,6 +208,10 @@
PERFETTO_DCHECK(removed == 1);
// Might return 0 if trace_duration_ms == 0.
watchdogs_.erase(id);
+ } else if (instances_[id] == kInodeFileMapSourceName) {
+ size_t removed = file_map_sources_.erase(id);
+ PERFETTO_DCHECK(removed == 1);
+ watchdogs_.erase(id);
}
}
@@ -233,7 +265,6 @@
if (!metadata.inodes.empty()) {
auto weak_this = weak_factory_.GetWeakPtr();
auto inodes = metadata.inodes;
- // TODO(hjd): This call back should be one in total, not one per CPU.
task_runner_->PostTask([weak_this, inodes] {
if (weak_this)
weak_this->OnInodes(inodes);
@@ -246,4 +277,24 @@
PERFETTO_DLOG("Saw FtraceBundle with %zu inodes.", inodes.size());
}
+ProbesProducer::InodeFileMapDataSource::InodeFileMapDataSource(
+ std::unique_ptr<TraceWriter> writer)
+ : writer_(std::move(writer)) {}
+
+ProbesProducer::InodeFileMapDataSource::~InodeFileMapDataSource() = default;
+
+void ProbesProducer::InodeFileMapDataSource::WriteInodes(
+ const FtraceMetadata& metadata) {
+ auto trace_packet = writer_->NewTracePacket();
+ auto inode_file_map = trace_packet->set_inode_file_map();
+ // TODO(azappone): Add block_device_id and mount_points
+ auto inodes = metadata.inodes;
+ for (const auto& inode : inodes) {
+ auto* entry = inode_file_map->add_entries();
+ entry->set_inode_number(inode);
+ // TODO(azappone): Add resolving filepaths and type
+ }
+ trace_packet->Finalize();
+}
+
} // namespace perfetto