Merge "perfetto: enable traced on CTS running devices"
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 718e51f..77d1c02 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -163,8 +163,9 @@
id, source_config.target_buffer());
auto trace_writer = endpoint_->CreateTraceWriter(
static_cast<BufferID>(source_config.target_buffer()));
+ CreateDeviceToInodeMap("/system/", &system_inodes_);
auto file_map_source = std::unique_ptr<InodeFileMapDataSource>(
- new InodeFileMapDataSource(std::move(trace_writer)));
+ new InodeFileMapDataSource(&system_inodes_, std::move(trace_writer)));
file_map_sources_.emplace(id, std::move(file_map_source));
AddWatchdogsTimer(id, source_config);
}
@@ -200,6 +201,46 @@
trace_packet->Finalize();
}
+// static
+void ProbesProducer::CreateDeviceToInodeMap(
+ const std::string& root_directory,
+ std::map<uint64_t, InodeMap>* block_device_map) {
+ // Return immediately if we've already filled in the system map
+ if (!block_device_map->empty())
+ return;
+ std::queue<std::string> queue;
+ queue.push(root_directory);
+ while (!queue.empty()) {
+ struct dirent* entry;
+ std::string filepath = queue.front();
+ queue.pop();
+ DIR* dir = opendir(filepath.c_str());
+ filepath += "/";
+ if (dir == nullptr)
+ continue;
+ while ((entry = readdir(dir)) != nullptr) {
+ std::string filename = entry->d_name;
+ if (filename == "." || filename == "..")
+ continue;
+ uint64_t inode_number = entry->d_ino;
+ uint64_t block_device_id = 0;
+ InodeMap& inode_map = (*block_device_map)[block_device_id];
+ // Default
+ Type type = protos::pbzero::InodeFileMap_Entry_Type_UNKNOWN;
+ if (entry->d_type == DT_DIR) {
+ // Continue iterating through files if current entry is a directory
+ queue.push(filepath + filename);
+ type = protos::pbzero::InodeFileMap_Entry_Type_DIRECTORY;
+ } else if (entry->d_type == DT_REG) {
+ type = protos::pbzero::InodeFileMap_Entry_Type_FILE;
+ }
+ inode_map[inode_number].first = type;
+ inode_map[inode_number].second.emplace(filepath + filename);
+ }
+ closedir(dir);
+ }
+}
+
void ProbesProducer::TearDownDataSourceInstance(DataSourceInstanceID id) {
PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
PERFETTO_DCHECK(instances_.count(id));
@@ -278,8 +319,9 @@
}
ProbesProducer::InodeFileMapDataSource::InodeFileMapDataSource(
+ std::map<uint64_t, InodeMap>* file_system_inodes,
std::unique_ptr<TraceWriter> writer)
- : writer_(std::move(writer)) {}
+ : file_system_inodes_(file_system_inodes), writer_(std::move(writer)) {}
ProbesProducer::InodeFileMapDataSource::~InodeFileMapDataSource() = default;
@@ -287,12 +329,21 @@
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
+ // TODO(azappone): Get block_device_id and mount_points & add to the proto
+ uint64_t block_device_id = 0;
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
+ auto block_device_map = file_system_inodes_->find(block_device_id);
+ if (block_device_map != file_system_inodes_->end()) {
+ auto inode_map = block_device_map->second.find(inode);
+ if (inode_map != block_device_map->second.end()) {
+ entry->set_type(inode_map->second.first);
+ for (const auto& path : inode_map->second.second)
+ entry->add_paths(path.c_str());
+ }
+ }
}
trace_packet->Finalize();
}
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index bc1b91d..457975b 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -59,6 +59,10 @@
private:
using FtraceBundleHandle =
protozero::MessageHandle<protos::pbzero::FtraceEventBundle>;
+ using Type = protos::pbzero::InodeFileMap_Entry_Type;
+ using InodeMap = std::map<uint64_t,
+ std::pair<protos::pbzero::InodeFileMap_Entry_Type,
+ std::set<std::string>>>;
class SinkDelegate : public FtraceSink::Delegate {
public:
@@ -89,12 +93,15 @@
class InodeFileMapDataSource {
public:
- explicit InodeFileMapDataSource(std::unique_ptr<TraceWriter> writer);
+ explicit InodeFileMapDataSource(
+ std::map<uint64_t, InodeMap>* file_system_inodes,
+ std::unique_ptr<TraceWriter> writer);
~InodeFileMapDataSource();
void WriteInodes(const FtraceMetadata& metadata);
private:
+ std::map<uint64_t, InodeMap>* file_system_inodes_;
std::unique_ptr<TraceWriter> writer_;
};
@@ -110,6 +117,9 @@
void IncreaseConnectionBackoff();
void AddWatchdogsTimer(DataSourceInstanceID id,
const DataSourceConfig& source_config);
+ static void CreateDeviceToInodeMap(
+ const std::string& root_directory,
+ std::map<uint64_t, InodeMap>* block_device_map);
State state_ = kNotStarted;
base::TaskRunner* task_runner_;
@@ -124,6 +134,7 @@
std::map<DataSourceInstanceID, base::Watchdog::Timer> watchdogs_;
std::map<DataSourceInstanceID, std::unique_ptr<InodeFileMapDataSource>>
file_map_sources_;
+ std::map<uint64_t, InodeMap> system_inodes_;
};
} // namespace perfetto