blob: 1f4197f0680fbe8184ccd2a3c903857296eb763b [file] [log] [blame]
Anna Zappone2a6f9042018-03-14 13:26:07 +00001/*
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_FILESYSTEM_INODE_FILE_DATA_SOURCE_H_
18#define SRC_TRACED_PROBES_FILESYSTEM_INODE_FILE_DATA_SOURCE_H_
19
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <map>
Primiano Tucci569ad312018-03-14 22:28:31 +000023#include <memory>
Anna Zappone2a6f9042018-03-14 13:26:07 +000024#include <set>
25#include <string>
Anna Zappone9ab79602018-03-27 11:57:44 +010026#include <unordered_map>
Anna Zappone2a6f9042018-03-14 13:26:07 +000027
Florian Mayer112376e2018-03-28 16:20:41 +010028#include "perfetto/base/task_runner.h"
Hector Dearman0ff07c72018-03-15 09:54:46 +000029#include "perfetto/base/weak_ptr.h"
Hector Dearmancd3b6d32018-03-20 11:35:20 +000030#include "perfetto/traced/data_source_types.h"
Anna Zappone2a6f9042018-03-14 13:26:07 +000031#include "perfetto/tracing/core/basic_types.h"
Primiano Tuccidae35652018-03-29 18:32:02 +010032#include "perfetto/tracing/core/data_source_config.h"
Anna Zappone2a6f9042018-03-14 13:26:07 +000033#include "perfetto/tracing/core/trace_writer.h"
Florian Mayer20c9ac72018-03-29 12:20:48 +010034#include "src/traced/probes/filesystem/file_scanner.h"
Anna Zappone2a6f9042018-03-14 13:26:07 +000035#include "src/traced/probes/filesystem/fs_mount.h"
Anna Zappone3be7b672018-03-23 17:26:10 +000036#include "src/traced/probes/filesystem/lru_inode_cache.h"
Anna Zappone2a6f9042018-03-14 13:26:07 +000037
38#include "perfetto/trace/filesystem/inode_file_map.pbzero.h"
39
40namespace perfetto {
41
Anna Zappone2a6f9042018-03-14 13:26:07 +000042using InodeFileMap = protos::pbzero::InodeFileMap;
Primiano Tucci569ad312018-03-14 22:28:31 +000043class TraceWriter;
Anna Zappone2a6f9042018-03-14 13:26:07 +000044
Florian Mayer7ca14bf2018-03-20 14:13:02 +000045void ScanFilesDFS(
46 const std::string& root_directory,
Florian Mayerfe28afd2018-03-22 16:24:10 +000047 const std::function<bool(BlockDeviceID block_device_id,
Florian Mayer7ca14bf2018-03-20 14:13:02 +000048 Inode inode_number,
49 const std::string& path,
50 protos::pbzero::InodeFileMap_Entry_Type type)>&);
51
Anna Zappone3be7b672018-03-23 17:26:10 +000052// Creates block_device_map for /system partition
53void CreateStaticDeviceToInodeMap(
Anna Zappone2a6f9042018-03-14 13:26:07 +000054 const std::string& root_directory,
Anna Zappone9ab79602018-03-27 11:57:44 +010055 std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
56 static_file_map);
Anna Zappone3be7b672018-03-23 17:26:10 +000057
58void FillInodeEntry(InodeFileMap* destination,
59 Inode inode_number,
60 const InodeMapValue& inode_map_value);
Anna Zappone2a6f9042018-03-14 13:26:07 +000061
Florian Mayer20c9ac72018-03-29 12:20:48 +010062class InodeFileDataSource : public FileScanner::Delegate {
Anna Zappone2a6f9042018-03-14 13:26:07 +000063 public:
Anna Zappone3be7b672018-03-23 17:26:10 +000064 InodeFileDataSource(
Primiano Tuccidae35652018-03-29 18:32:02 +010065 DataSourceConfig,
Florian Mayer112376e2018-03-28 16:20:41 +010066 base::TaskRunner*,
Anna Zappone3be7b672018-03-23 17:26:10 +000067 TracingSessionID,
Anna Zappone9ab79602018-03-27 11:57:44 +010068 std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
69 static_file_map,
Anna Zappone3be7b672018-03-23 17:26:10 +000070 LRUInodeCache* cache,
71 std::unique_ptr<TraceWriter> writer);
Hector Dearman0ff07c72018-03-15 09:54:46 +000072
73 TracingSessionID session_id() const { return session_id_; }
74 base::WeakPtr<InodeFileDataSource> GetWeakPtr() const;
Anna Zappone2a6f9042018-03-14 13:26:07 +000075
Anna Zappone3be7b672018-03-23 17:26:10 +000076 // Called when Inodes are seen in the FtraceEventBundle
Anna Zappone80e098e2018-03-16 14:50:28 +000077 void OnInodes(const std::vector<std::pair<Inode, BlockDeviceID>>& inodes);
78
Anna Zappone3be7b672018-03-23 17:26:10 +000079 // Search in /system partition and add inodes to InodeFileMap proto if found
80 void AddInodesFromStaticMap(BlockDeviceID block_device_id,
Florian Mayer20c9ac72018-03-29 12:20:48 +010081 std::set<Inode>* inode_numbers);
Anna Zappone3be7b672018-03-23 17:26:10 +000082
83 // Search in LRUInodeCache and add inodes to InodeFileMap if found
84 void AddInodesFromLRUCache(BlockDeviceID block_device_id,
Florian Mayer20c9ac72018-03-29 12:20:48 +010085 std::set<Inode>* inode_numbers);
86
87 virtual ~InodeFileDataSource() {}
Anna Zappone2a6f9042018-03-14 13:26:07 +000088
89 private:
Florian Mayer20c9ac72018-03-29 12:20:48 +010090 InodeFileMap* AddToCurrentTracePacket(BlockDeviceID block_device_id);
Florian Mayer112376e2018-03-28 16:20:41 +010091 void FindMissingInodes();
Florian Mayer20c9ac72018-03-29 12:20:48 +010092 bool OnInodeFound(BlockDeviceID block_device_id,
93 Inode inode_number,
94 const std::string& path,
95 protos::pbzero::InodeFileMap_Entry_Type type);
96 void OnInodeScanDone();
97 void AddRootsForBlockDevice(BlockDeviceID block_device_id,
98 std::vector<std::string>* roots);
Florian Mayer112376e2018-03-28 16:20:41 +010099
Primiano Tuccidae35652018-03-29 18:32:02 +0100100 uint64_t GetScanIntervalMs();
101 uint64_t GetScanDelayMs();
102 uint64_t GetScanBatchSize();
103
104 const DataSourceConfig source_config_;
Florian Mayer18614fe2018-03-29 17:51:20 +0100105 std::set<std::string> scan_mount_points_;
106 std::map<std::string, std::vector<std::string>> mount_point_mapping_;
107
Florian Mayer112376e2018-03-28 16:20:41 +0100108 base::TaskRunner* task_runner_;
Hector Dearman0ff07c72018-03-15 09:54:46 +0000109 const TracingSessionID session_id_;
Anna Zappone9ab79602018-03-27 11:57:44 +0100110 std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
111 static_file_map_;
Anna Zappone3be7b672018-03-23 17:26:10 +0000112 LRUInodeCache* cache_;
Anna Zappone2a6f9042018-03-14 13:26:07 +0000113 std::multimap<BlockDeviceID, std::string> mount_points_;
114 std::unique_ptr<TraceWriter> writer_;
Florian Mayer112376e2018-03-28 16:20:41 +0100115 std::map<BlockDeviceID, std::set<Inode>> missing_inodes_;
Florian Mayer20c9ac72018-03-29 12:20:48 +0100116 std::map<BlockDeviceID, std::set<Inode>> next_missing_inodes_;
117 BlockDeviceID current_block_device_id_;
118 TraceWriter::TracePacketHandle current_trace_packet_;
119 InodeFileMap* current_file_map_;
120 bool has_current_trace_packet_ = false;
121 bool scan_running_ = false;
122 std::unique_ptr<FileScanner> file_scanner_;
Hector Dearman0ff07c72018-03-15 09:54:46 +0000123 base::WeakPtrFactory<InodeFileDataSource> weak_factory_; // Keep last.
Anna Zappone2a6f9042018-03-14 13:26:07 +0000124};
125
126} // namespace perfetto
127
128#endif // SRC_TRACED_PROBES_FILESYSTEM_INODE_FILE_DATA_SOURCE_H_