• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
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 HIEBPF_DATA_FILE_H
17 #define HIEBPF_DATA_FILE_H
18 #include <sys/mman.h>
19 #include <cerrno>
20 #include <memory>
21 #include <string>
22 #include <mutex>
23 
24 #include <fcntl.h>
25 #include <unistd.h>
26 
27 #include "type_headers.h"
28 #include "ringbuffer.h"
29 #include "hhlog.h"
30 
31 
32 struct DataFileHeader {
33     enum HeaderConsts:std::size_t {
34         MAGIC_LEN = 8,
35         TOTAL_HEAD_SIZE = 1024,
36         FIXED_HEAD_SIZE = 24
37     };
38     char magic[MAGIC_LEN] = {'E', 'B', 'P', 'F', 'F', 'I', 'L', 'E'};
39     __u32 headSize_ {TOTAL_HEAD_SIZE};
40     __u32 version_ {0};
41     __u32 clock_ {1};
42     __u32 cmdLen_ {0};
43     char cmd_[TOTAL_HEAD_SIZE - FIXED_HEAD_SIZE] {};
44 };
45 
46 class HiebpfDataFile {
47 public:
~HiebpfDataFile()48     ~HiebpfDataFile()
49     {
50         if (mapAddr_) {
51             munmap(mapAddr_, length_);
52             mapAddr_ = nullptr;
53         }
54         if (fd_ != -1) {
55             std::size_t curPos = mapPos_ + offset_;
56             ftruncate(fd_, curPos);
57             close(fd_);
58             fd_ = -1;
59         }
60     }
61 
62     static std::shared_ptr<HiebpfDataFile> MakeShared(
63         const std::string& cmd,
64         const std::string& filename,
65         const std::size_t pages = DEFAULT_MMAP_PAGES);
66     void* Reserve(const std::size_t size);
67     void Discard(void *data);
68     void Submit(void *data);
69     void WriteKernelSymbol();
70 
71     enum Constants:std::size_t {
72         DEFAULT_MMAP_PAGES = (1 << 8),
73         DEFAULT_MMAP_LENGTH = (1 << 20),
74         DEFAULT_PAGE_SIZE = (1 << 12),
75     };
76 
77 private:
78     int MapFile();
79     int RemapFile(const std::size_t size);
80     HiebpfDataFile(
81         const std::string& cmd,
82         const std::string& filename,
83         const std::size_t pages = DEFAULT_MMAP_PAGES)
84         : hiebpfCmd_ {cmd},
85           filename_ {filename}
86     {
87         long pageSize = sysconf(_SC_PAGE_SIZE);
88         HHLOGI(true, "page size of the current OS: %u bytes", pageSize);
89         if (pageSize > 0) {
90             pageSize_ = static_cast<size_t>(pageSize);
91             length_ = static_cast<size_t>(pageSize * pages);
92         }
93         HHLOGI(true, "mmap length = %u", length_);
94     }
95 
OpenFile()96     inline int OpenFile()
97     {
98         constexpr int FILE_MODE = 0644;
99         fd_ = open(filename_.c_str(), O_RDWR | O_CREAT, FILE_MODE);
100         return (fd_ < 0) ? -1 : 0;
101     }
102 
ExtendFile(const std::size_t mapPos,const std::size_t mapLength)103     inline int ExtendFile(const std::size_t mapPos, const std::size_t mapLength)
104     {
105         if (ftruncate(fd_, mapPos + mapLength) != 0) {
106             HHLOGE(true, "failed to extend data file");
107             return -1;
108         }
109         return 0;
110     }
111 
WriteFileHeader()112     int WriteFileHeader()
113     {
114         struct DataFileHeader header {};
115         header.cmdLen_ = hiebpfCmd_.length() + 1;
116         if (strncpy_s(header.cmd_, header.TOTAL_HEAD_SIZE - header.FIXED_HEAD_SIZE,
117                       hiebpfCmd_.c_str(), hiebpfCmd_.length() + 1) != EOK) {
118             HHLOGE(true, "failed to copy string");
119             return -1;
120         }
121         if (memcpy_s(mapAddr_, length_, &header, sizeof(header)) != EOK) {
122             HHLOGE(true, "failed to memcpy_s");
123             return -1;
124         }
125         offset_ += sizeof(header);
126         return 0;
127     }
128 
129     const std::string hiebpfCmd_ {};
130     const std::string filename_ {"/data/local/tmp/hiebpf.data"};
131     std::size_t length_ {DEFAULT_MMAP_LENGTH};
132     std::size_t pageSize_ {};
133 
134     int fd_ {-1};
135     void *mapAddr_ {MAP_FAILED};
136     std::size_t mapPos_ {0};
137     std::size_t offset_ {0};
138     std::mutex mtx_ {};
139 };
140 
141 #endif