1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef BPF_CONTROLLER_H 17 #define BPF_CONTROLLER_H 18 19 #include <iostream> 20 21 #include <memory> 22 #include <string> 23 #include <functional> 24 #include <vector> 25 #include <functional> 26 #include <set> 27 28 #include "type_headers.h" 29 #include "libbpf.h" 30 #include "bpf_log_reader.h" 31 #include "hhlog.h" 32 #include "hiebpf.skel.h" 33 #include "bpf_event_receiver.h" 34 #include "hiebpf_data_file.h" 35 36 enum HiebpfEventGroup:uint32_t { 37 // file system events start from 0x000 38 FS_GROUP_BASE = 0, 39 FS_GROUP_ALL = FS_GROUP_BASE, 40 FS_GROUP_OPEN, 41 FS_GROUP_READ, 42 FS_GROUP_WRITE, 43 FS_GROUP_CLOSE, 44 // memory events start from 0x100 45 MEM_GROUP_BASE = 0x100, 46 MEM_GROUP_ALL = MEM_GROUP_BASE, 47 // BIO events start from 0x200 48 BIO_GROUP_BASE = 0x200, 49 BIO_GROUP_ALL = BIO_GROUP_BASE, 50 }; 51 52 struct BPFConfig { 53 bool excludeTracer_ {true}; 54 bool unwindStack_ {true}; 55 __u32 dumpEvents_ {0}; 56 __u32 traceDuration_ {0}; 57 __u32 maxStackDepth_ {MAX_STACK_LIMIT}; 58 __u32 epollTimeout_ {100}; 59 __u32 pipelines_ {1}; // Numbers of pipeline channels that process data in user mode 60 std::string cmd_; 61 std::vector<pid_t> targetPids_ {}; 62 std::set<HiebpfEventGroup> selectEventGroups_ {}; 63 std::string outputFile_ {"/data/local/tmp/hiebpf.data"}; 64 // loggers configs 65 __u32 BPFLogLevel_ {BPF_LOG_DEBUG}; 66 int LIBBPFLogLevel_ {LIBBPF_DEBUG}; 67 std::string BPFLogFile_ {"stdout"}; 68 std::string LIBBPFLogFile_ {"stdout"}; 69 }; 70 71 class BPFController { 72 public: 73 ~BPFController(); 74 static std::unique_ptr<BPFController> MakeUnique(const struct BPFConfig& config); 75 int Start(); 76 void Stop(); 77 78 static int HandleEvent(void *ctx, void *data, size_t dataSize); 79 static int DumpEvent(void *ctx, void *data, size_t dataSize); 80 81 enum ConfigurationLimit:__u32 { 82 DUMP_EVENTS_LIMIT = 10000, 83 TRACE_DURATION_LIMIT = 3600, 84 MIN_PIPELINES_LIMIT = 1, 85 }; 86 87 private: BPFController(const struct BPFConfig & config)88 BPFController(const struct BPFConfig& config):config_ {config} {} 89 int VerifySelectEventGroups(const std::set<HiebpfEventGroup> &selectEventGroups); 90 int VerifyConfigurations(); 91 int SetUpBPF(); 92 int FilterProgByEvents(); 93 void FilterFsGroup(); 94 int ConfigureBPF(); 95 int InitBPFVariables() const; 96 int FillTargetPidMap() const; 97 int ConfigBPFLogger(); 98 int ConfigLIBBPFLogger() const; 99 int ConfigReceivers(); 100 int32_t ConfigDlopenBPFProg(); 101 uint64_t GetSymOffset(const std::string &path, const std::string &symbol); 102 std::weak_ptr<BPFEventReceiver> NextActiveReceiver(); 103 BPFEventLoopOnce()104 int BPFEventLoopOnce() const 105 { 106 int err = ring_buffer__poll(rb_, config_.epollTimeout_); 107 if (err < 0) { 108 HHLOGE(true, "failed to poll BPF ring buffer: %s", strerror(-err)); 109 return err; 110 } 111 return 0; 112 } 113 StartBPFLogReader()114 inline int StartBPFLogReader() 115 { 116 if (bpfLogReader_) { 117 return bpfLogReader_->Start(); 118 } 119 return 0; 120 } 121 StartReceivers()122 inline int StartReceivers() 123 { 124 if (receivers_.empty()) { 125 return 0; 126 } 127 for (__u32 k = 0; k < receivers_.size(); ++k) { 128 if (receivers_[k]->Start() != 0) { 129 return -1; 130 } 131 } 132 return 0; 133 } 134 135 static int LIBBPFPrintFunc(enum libbpf_print_level level, const char *format, va_list args); 136 static int DumpFSTraceEvent(BPFController *bpfctlr, void *data, size_t dataSize); 137 static int DumpPFTraceEvent(BPFController *bpfctlr, void *data, size_t dataSize); 138 static int DumpBIOTraceEvent(BPFController *bpfctlr, void *data, size_t dataSize); 139 static int DumpSTRTraceEvent(void *data, size_t dataSize); 140 141 bool loopStop_ {false}; 142 struct hiebpf_bpf* skel_ {nullptr}; 143 std::unique_ptr<BPFLogReader> bpfLogReader_ {nullptr}; 144 struct BPFConfig config_; 145 std::set<HiebpfEventGroup> selectEventGroups_ {}; 146 struct ring_buffer* rb_ {nullptr}; 147 std::shared_ptr<HiebpfDataFile> dataFile_ {nullptr}; 148 std::vector<std::shared_ptr<BPFEventReceiver>> receivers_ {}; 149 __u32 last_ {0}; 150 __u64 *ips_ {nullptr}; 151 }; 152 153 #endif