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