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