/* * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef HIEBPF_DATA_FILE_H #define HIEBPF_DATA_FILE_H #include #include #include #include #include #include #include #include "type_headers.h" #include "ringbuffer.h" #include "hhlog.h" struct DataFileHeader { enum HeaderConsts:std::size_t { MAGIC_LEN = 8, TOTAL_HEAD_SIZE = 1024, FIXED_HEAD_SIZE = 24 }; char magic[MAGIC_LEN] = {'E', 'B', 'P', 'F', 'F', 'I', 'L', 'E'}; __u32 headSize_ {TOTAL_HEAD_SIZE}; __u32 version_ {0}; __u32 clock_ {1}; __u32 cmdLen_ {0}; char cmd_[TOTAL_HEAD_SIZE - FIXED_HEAD_SIZE] {}; }; class HiebpfDataFile { public: ~HiebpfDataFile() { if (mapAddr_) { munmap(mapAddr_, length_); mapAddr_ = nullptr; } if (fd_ != -1) { std::size_t curPos = mapPos_ + offset_; ftruncate(fd_, curPos); close(fd_); fd_ = -1; } } static std::shared_ptr MakeShared( const std::string& cmd, const std::string& filename, const std::size_t pages = DEFAULT_MMAP_PAGES); void* Reserve(const std::size_t size); void Discard(void *data); void Submit(void *data); void WriteKernelSymbol(); enum Constants:std::size_t { DEFAULT_MMAP_PAGES = (1 << 8), DEFAULT_MMAP_LENGTH = (1 << 20), DEFAULT_PAGE_SIZE = (1 << 12), }; private: int MapFile(); int RemapFile(const std::size_t size); HiebpfDataFile( const std::string& cmd, const std::string& filename, const std::size_t pages = DEFAULT_MMAP_PAGES) : hiebpfCmd_ {cmd}, filename_ {filename} { long pageSize = sysconf(_SC_PAGE_SIZE); HHLOGI(true, "page size of the current OS: %u bytes", pageSize); if (pageSize > 0) { pageSize_ = static_cast(pageSize); length_ = static_cast(pageSize * pages); } HHLOGI(true, "mmap length = %u", length_); } inline int OpenFile() { constexpr int FILE_MODE = 0644; fd_ = open(filename_.c_str(), O_RDWR | O_CREAT, FILE_MODE); return (fd_ < 0) ? -1 : 0; } inline int ExtendFile(const std::size_t mapPos, const std::size_t mapLength) { if (ftruncate(fd_, mapPos + mapLength) != 0) { HHLOGE(true, "failed to extend data file"); return -1; } return 0; } int WriteFileHeader() { struct DataFileHeader header {}; header.cmdLen_ = hiebpfCmd_.length() + 1; if (strncpy_s(header.cmd_, header.TOTAL_HEAD_SIZE - header.FIXED_HEAD_SIZE, hiebpfCmd_.c_str(), hiebpfCmd_.length() + 1) != EOK) { HHLOGE(true, "failed to copy string"); return -1; } if (memcpy_s(mapAddr_, length_, &header, sizeof(header)) != EOK) { HHLOGE(true, "failed to memcpy_s"); return -1; } offset_ += sizeof(header); return 0; } const std::string hiebpfCmd_ {}; const std::string filename_ {"/data/local/tmp/hiebpf.data"}; std::size_t length_ {DEFAULT_MMAP_LENGTH}; std::size_t pageSize_ {}; int fd_ {-1}; void *mapAddr_ {MAP_FAILED}; std::size_t mapPos_ {0}; std::size_t offset_ {0}; std::mutex mtx_ {}; }; #endif