1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "fault_logger_pipe.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <algorithm> 19800b99b8Sopenharmony_ci#include <cerrno> 20800b99b8Sopenharmony_ci#include <cstdio> 21800b99b8Sopenharmony_ci#include <cstdlib> 22800b99b8Sopenharmony_ci#include <cstring> 23800b99b8Sopenharmony_ci#include <ctime> 24800b99b8Sopenharmony_ci#include <fcntl.h> 25800b99b8Sopenharmony_ci#include <securec.h> 26800b99b8Sopenharmony_ci#include <string> 27800b99b8Sopenharmony_ci#include <sys/socket.h> 28800b99b8Sopenharmony_ci#include <sys/stat.h> 29800b99b8Sopenharmony_ci#include <sys/syscall.h> 30800b99b8Sopenharmony_ci#include <sys/types.h> 31800b99b8Sopenharmony_ci#include <sys/un.h> 32800b99b8Sopenharmony_ci#include <unistd.h> 33800b99b8Sopenharmony_ci#include <vector> 34800b99b8Sopenharmony_ci#include "dfx_define.h" 35800b99b8Sopenharmony_ci#include "dfx_log.h" 36800b99b8Sopenharmony_ci 37800b99b8Sopenharmony_cinamespace OHOS { 38800b99b8Sopenharmony_cinamespace HiviewDFX { 39800b99b8Sopenharmony_cinamespace { 40800b99b8Sopenharmony_ciconst std::string FAULTLOGGER_PIPE_TAG = "FaultLoggerPipe"; 41800b99b8Sopenharmony_ciconst int PIPE_TIMEOUT = 10000; // 10 seconds 42800b99b8Sopenharmony_ci} 43800b99b8Sopenharmony_ci 44800b99b8Sopenharmony_ciFaultLoggerPipe::FaultLoggerPipe() 45800b99b8Sopenharmony_ci{ 46800b99b8Sopenharmony_ci init_ = false; 47800b99b8Sopenharmony_ci write_ = false; 48800b99b8Sopenharmony_ci Init(); 49800b99b8Sopenharmony_ci} 50800b99b8Sopenharmony_ci 51800b99b8Sopenharmony_ciFaultLoggerPipe::~FaultLoggerPipe() 52800b99b8Sopenharmony_ci{ 53800b99b8Sopenharmony_ci Destroy(); 54800b99b8Sopenharmony_ci} 55800b99b8Sopenharmony_ci 56800b99b8Sopenharmony_ciint FaultLoggerPipe::GetReadFd(void) 57800b99b8Sopenharmony_ci{ 58800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: pipe read fd: %{public}d", __func__, fds_[PIPE_READ]); 59800b99b8Sopenharmony_ci return fds_[PIPE_READ]; 60800b99b8Sopenharmony_ci} 61800b99b8Sopenharmony_ci 62800b99b8Sopenharmony_ciint FaultLoggerPipe::GetWriteFd(void) 63800b99b8Sopenharmony_ci{ 64800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: pipe write fd: %{public}d", __func__, fds_[PIPE_WRITE]); 65800b99b8Sopenharmony_ci if (!write_) { 66800b99b8Sopenharmony_ci write_ = true; 67800b99b8Sopenharmony_ci return fds_[PIPE_WRITE]; 68800b99b8Sopenharmony_ci } 69800b99b8Sopenharmony_ci return -1; 70800b99b8Sopenharmony_ci} 71800b99b8Sopenharmony_ci 72800b99b8Sopenharmony_cibool FaultLoggerPipe::Init(void) 73800b99b8Sopenharmony_ci{ 74800b99b8Sopenharmony_ci if (!init_) { 75800b99b8Sopenharmony_ci if (pipe2(fds_, O_NONBLOCK) != 0) { 76800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to create pipe.", __func__); 77800b99b8Sopenharmony_ci return false; 78800b99b8Sopenharmony_ci } 79800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: create pipe.", __func__); 80800b99b8Sopenharmony_ci } 81800b99b8Sopenharmony_ci init_ = true; 82800b99b8Sopenharmony_ci if (!SetSize(MAX_PIPE_SIZE)) { 83800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to set pipe size.", __func__); 84800b99b8Sopenharmony_ci } 85800b99b8Sopenharmony_ci return true; 86800b99b8Sopenharmony_ci} 87800b99b8Sopenharmony_ci 88800b99b8Sopenharmony_cibool FaultLoggerPipe::SetSize(long sz) 89800b99b8Sopenharmony_ci{ 90800b99b8Sopenharmony_ci if (!init_) { 91800b99b8Sopenharmony_ci return false; 92800b99b8Sopenharmony_ci } 93800b99b8Sopenharmony_ci if (fcntl(fds_[PIPE_READ], F_SETPIPE_SZ, sz) < 0) { 94800b99b8Sopenharmony_ci return false; 95800b99b8Sopenharmony_ci } 96800b99b8Sopenharmony_ci if (fcntl(fds_[PIPE_WRITE], F_SETPIPE_SZ, sz) < 0) { 97800b99b8Sopenharmony_ci return false; 98800b99b8Sopenharmony_ci } 99800b99b8Sopenharmony_ci return true; 100800b99b8Sopenharmony_ci} 101800b99b8Sopenharmony_ci 102800b99b8Sopenharmony_civoid FaultLoggerPipe::Destroy(void) 103800b99b8Sopenharmony_ci{ 104800b99b8Sopenharmony_ci if (init_) { 105800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: close pipe.", __func__); 106800b99b8Sopenharmony_ci Close(fds_[PIPE_READ]); 107800b99b8Sopenharmony_ci Close(fds_[PIPE_WRITE]); 108800b99b8Sopenharmony_ci } 109800b99b8Sopenharmony_ci init_ = false; 110800b99b8Sopenharmony_ci} 111800b99b8Sopenharmony_ci 112800b99b8Sopenharmony_civoid FaultLoggerPipe::Close(int fd) const 113800b99b8Sopenharmony_ci{ 114800b99b8Sopenharmony_ci if (fd > 0) { 115800b99b8Sopenharmony_ci syscall(SYS_close, fd); 116800b99b8Sopenharmony_ci } 117800b99b8Sopenharmony_ci} 118800b99b8Sopenharmony_ci 119800b99b8Sopenharmony_ciFaultLoggerPipe2::FaultLoggerPipe2(uint64_t time, bool isJson) 120800b99b8Sopenharmony_ci{ 121800b99b8Sopenharmony_ci if (isJson) { 122800b99b8Sopenharmony_ci faultLoggerJsonPipeBuf_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe()); 123800b99b8Sopenharmony_ci faultLoggerJsonPipeRes_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe()); 124800b99b8Sopenharmony_ci } else { 125800b99b8Sopenharmony_ci faultLoggerPipeBuf_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe()); 126800b99b8Sopenharmony_ci faultLoggerPipeRes_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe()); 127800b99b8Sopenharmony_ci } 128800b99b8Sopenharmony_ci time_ = time; 129800b99b8Sopenharmony_ci} 130800b99b8Sopenharmony_ci 131800b99b8Sopenharmony_ciFaultLoggerPipe2::~FaultLoggerPipe2() 132800b99b8Sopenharmony_ci{ 133800b99b8Sopenharmony_ci faultLoggerPipeBuf_.reset(); 134800b99b8Sopenharmony_ci faultLoggerPipeRes_.reset(); 135800b99b8Sopenharmony_ci faultLoggerJsonPipeBuf_.reset(); 136800b99b8Sopenharmony_ci faultLoggerJsonPipeRes_.reset(); 137800b99b8Sopenharmony_ci time_ = 0; 138800b99b8Sopenharmony_ci} 139800b99b8Sopenharmony_ci 140800b99b8Sopenharmony_ciFaultLoggerPipeMap::FaultLoggerPipeMap() 141800b99b8Sopenharmony_ci{ 142800b99b8Sopenharmony_ci std::lock_guard<std::mutex> lck(pipeMapsMutex_); 143800b99b8Sopenharmony_ci faultLoggerPipes_.clear(); 144800b99b8Sopenharmony_ci} 145800b99b8Sopenharmony_ci 146800b99b8Sopenharmony_ciFaultLoggerPipeMap::~FaultLoggerPipeMap() 147800b99b8Sopenharmony_ci{ 148800b99b8Sopenharmony_ci std::lock_guard<std::mutex> lck(pipeMapsMutex_); 149800b99b8Sopenharmony_ci std::map<int, std::unique_ptr<FaultLoggerPipe2> >::iterator iter = faultLoggerPipes_.begin(); 150800b99b8Sopenharmony_ci while (iter != faultLoggerPipes_.end()) { 151800b99b8Sopenharmony_ci faultLoggerPipes_.erase(iter++); 152800b99b8Sopenharmony_ci } 153800b99b8Sopenharmony_ci} 154800b99b8Sopenharmony_ci 155800b99b8Sopenharmony_civoid FaultLoggerPipeMap::Set(int pid, uint64_t time, bool isJson) 156800b99b8Sopenharmony_ci{ 157800b99b8Sopenharmony_ci std::lock_guard<std::mutex> lck(pipeMapsMutex_); 158800b99b8Sopenharmony_ci if (!Find(pid)) { 159800b99b8Sopenharmony_ci std::unique_ptr<FaultLoggerPipe2> ptr = std::unique_ptr<FaultLoggerPipe2>(new FaultLoggerPipe2(time, isJson)); 160800b99b8Sopenharmony_ci faultLoggerPipes_.emplace(pid, std::move(ptr)); 161800b99b8Sopenharmony_ci } 162800b99b8Sopenharmony_ci} 163800b99b8Sopenharmony_ci 164800b99b8Sopenharmony_cibool FaultLoggerPipeMap::Check(int pid, uint64_t time) 165800b99b8Sopenharmony_ci{ 166800b99b8Sopenharmony_ci std::lock_guard<std::mutex> lck(pipeMapsMutex_); 167800b99b8Sopenharmony_ci std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid); 168800b99b8Sopenharmony_ci if (iter != faultLoggerPipes_.end()) { 169800b99b8Sopenharmony_ci if ((time > faultLoggerPipes_[pid]->time_) && (time - faultLoggerPipes_[pid]->time_) > PIPE_TIMEOUT) { 170800b99b8Sopenharmony_ci faultLoggerPipes_.erase(iter); 171800b99b8Sopenharmony_ci return false; 172800b99b8Sopenharmony_ci } 173800b99b8Sopenharmony_ci return true; 174800b99b8Sopenharmony_ci } 175800b99b8Sopenharmony_ci return false; 176800b99b8Sopenharmony_ci} 177800b99b8Sopenharmony_ci 178800b99b8Sopenharmony_ciFaultLoggerPipe2* FaultLoggerPipeMap::Get(int pid) 179800b99b8Sopenharmony_ci{ 180800b99b8Sopenharmony_ci std::lock_guard<std::mutex> lck(pipeMapsMutex_); 181800b99b8Sopenharmony_ci if (!Find(pid)) { 182800b99b8Sopenharmony_ci return nullptr; 183800b99b8Sopenharmony_ci } 184800b99b8Sopenharmony_ci return faultLoggerPipes_[pid].get(); 185800b99b8Sopenharmony_ci} 186800b99b8Sopenharmony_ci 187800b99b8Sopenharmony_civoid FaultLoggerPipeMap::Del(int pid) 188800b99b8Sopenharmony_ci{ 189800b99b8Sopenharmony_ci std::lock_guard<std::mutex> lck(pipeMapsMutex_); 190800b99b8Sopenharmony_ci std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid); 191800b99b8Sopenharmony_ci if (iter != faultLoggerPipes_.end()) { 192800b99b8Sopenharmony_ci faultLoggerPipes_.erase(iter); 193800b99b8Sopenharmony_ci } 194800b99b8Sopenharmony_ci} 195800b99b8Sopenharmony_ci 196800b99b8Sopenharmony_cibool FaultLoggerPipeMap::Find(int pid) const 197800b99b8Sopenharmony_ci{ 198800b99b8Sopenharmony_ci std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid); 199800b99b8Sopenharmony_ci if (iter != faultLoggerPipes_.end()) { 200800b99b8Sopenharmony_ci return true; 201800b99b8Sopenharmony_ci } 202800b99b8Sopenharmony_ci return false; 203800b99b8Sopenharmony_ci} 204800b99b8Sopenharmony_ci} // namespace HiviewDfx 205800b99b8Sopenharmony_ci} // namespace OHOS 206