Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "file.h"
12 : #include "path.h"
13 : #include "adump_pub.h"
14 : #include "log/adx_log.h"
15 : #include "extra_config.h"
16 :
17 : namespace Adx {
18 : namespace {
19 : constexpr int32_t INVALID_FILE_FD = -1;
20 : constexpr mmMode_t READ_WRITE_MODE = M_IRUSR | M_IWUSR;
21 : constexpr int64_t MAX_BUFFER_LENGTH = 512;
22 : static const std::string MAPPING_FILE_NAME = "mapping.csv";
23 : } // namespace
24 :
25 217 : File::File(const std::string& path, int32_t flag, mmMode_t mode, bool lazyOpen)
26 217 : : filePath_(path), fd_(INVALID_FILE_FD), flag_(flag), mode_(mode)
27 : {
28 217 : if (lazyOpen) {
29 88 : return;
30 : }
31 129 : if (Open(flag, mode) != ADUMP_SUCCESS) {
32 19 : fd_ = INVALID_FILE_FD;
33 : }
34 0 : }
35 :
36 22 : int32_t File::EnsureOpen()
37 : {
38 22 : if (fd_ != INVALID_FILE_FD) {
39 0 : return ADUMP_SUCCESS;
40 : }
41 22 : if (Open(flag_, mode_) != ADUMP_SUCCESS) {
42 0 : fd_ = INVALID_FILE_FD;
43 0 : return ADUMP_FAILED;
44 : }
45 22 : return ADUMP_SUCCESS;
46 : }
47 :
48 217 : File::~File() { (void)Close(); }
49 :
50 151 : int32_t File::Open(int32_t flag, mmMode_t mode)
51 : {
52 151 : Path filePath(filePath_);
53 151 : std::string fileName = filePath.GetFileName();
54 151 : Path parentPath = filePath.ParentPath();
55 151 : if (!parentPath.Empty() && !parentPath.RealPath()) {
56 7 : IDE_LOGE("Real file path failed, file: %s", filePath_.c_str());
57 7 : return ADUMP_FAILED;
58 : }
59 :
60 144 : std::string realFilePath = parentPath.Concat(fileName).GetString();
61 144 : fd_ = mmOpen2(realFilePath.c_str(), flag, mode);
62 144 : if (fd_ >= 0) {
63 129 : return ADUMP_SUCCESS;
64 : }
65 15 : if (mmGetErrorCode() != ENAMETOOLONG) {
66 9 : IDE_LOGE("Open file failed. file: %s, fd: %d, message: %s", realFilePath.c_str(), fd_, strerror(errno));
67 9 : return ADUMP_FAILED;
68 : }
69 6 : parentPath = filePath.ParentPath();
70 6 : if (!parentPath.Empty() && !parentPath.RealPath()) {
71 0 : IDE_LOGE("Real long name file path failed, file: %s", filePath_.c_str());
72 0 : return ADUMP_FAILED;
73 : }
74 6 : std::string hashName = std::to_string(std::hash<std::string>{}(fileName));
75 6 : if (AddMapping(parentPath.GetString(), fileName, hashName) != ADUMP_SUCCESS) {
76 3 : IDE_LOGE("Add mapping item [ %s ] failed", hashName.c_str());
77 : }
78 6 : realFilePath = parentPath.Concat(hashName).GetString();
79 6 : IDE_LOGW(
80 : "File name [ %s ] too long rename as [ %s ] and the mapping record in %s", fileName.c_str(),
81 : realFilePath.c_str(), MAPPING_FILE_NAME.c_str());
82 6 : fd_ = mmOpen2(realFilePath.c_str(), O_APPEND | M_RDWR | M_CREAT, M_IREAD | M_IWRITE);
83 6 : IDE_CTRL_VALUE_FAILED(fd_ >= 0, return ADUMP_FAILED, "Open hash file failed, fd: %d", fd_);
84 3 : return ADUMP_SUCCESS;
85 151 : }
86 :
87 0 : int32_t File::GetFileDiscriptor() const { return fd_; }
88 :
89 120 : int32_t File::IsFileOpen() const
90 : {
91 120 : if (fd_ == INVALID_FILE_FD) {
92 19 : return ADUMP_FAILED;
93 : }
94 101 : return ADUMP_SUCCESS;
95 : }
96 :
97 232 : int32_t File::Close()
98 : {
99 232 : if (fd_ == INVALID_FILE_FD) {
100 91 : return ADUMP_SUCCESS;
101 : }
102 :
103 141 : const int32_t ret = mmClose(fd_);
104 141 : if (ret != EN_OK) {
105 6 : IDE_LOGW("Can not close file handle, file: %s, ret: %d.", filePath_.c_str(), ret);
106 6 : return ADUMP_FAILED;
107 : }
108 135 : fd_ = INVALID_FILE_FD;
109 135 : return ADUMP_SUCCESS;
110 : }
111 :
112 241 : int64_t File::Write(const char* const buffer, int64_t length) const
113 : {
114 241 : mmSsize_t ret = 0;
115 241 : UINT32 reserve = static_cast<UINT32>(length);
116 : do {
117 244 : ret = mmWrite(fd_, const_cast<char*>(buffer) + (static_cast<UINT32>(length) - reserve), reserve);
118 244 : if ((ret == EN_ERROR) && (mmGetErrorCode() == EINTR)) {
119 0 : continue;
120 : }
121 244 : if (ret < 0 || static_cast<UINT32>(ret) > reserve) {
122 9 : IDE_LOGE("Write data failed, buff: %p, length: %ld, ret: %zd", buffer, length, ret);
123 9 : break;
124 : }
125 235 : reserve -= ret;
126 235 : if (reserve == 0) {
127 232 : break;
128 : }
129 : } while (true);
130 :
131 241 : return static_cast<int64_t>(ret);
132 : }
133 :
134 57 : int64_t File::Read(char* buffer, int64_t length) const
135 : {
136 : mmSsize_t ret;
137 : do {
138 57 : ret = mmRead(fd_, buffer, static_cast<UINT32>(length));
139 57 : } while (ret == EN_ERROR && mmGetErrorCode() == EINTR);
140 :
141 57 : if (ret == EN_ERROR) {
142 3 : IDE_LOGE("Read data failed, buff: %p, length: %ld bytes, ret: %zd", buffer, length, ret);
143 : }
144 57 : return static_cast<int64_t>(ret);
145 : }
146 :
147 29 : int32_t File::Copy(const std::string& srcPath, const std::string& dstPath)
148 : {
149 29 : IDE_LOGI("copy file from %s to %s", srcPath.c_str(), dstPath.c_str());
150 29 : File srcFile(srcPath, M_RDONLY);
151 29 : int32_t ret = srcFile.IsFileOpen();
152 29 : if (ret != ADUMP_SUCCESS) {
153 6 : IDE_LOGE("Open src file failed, file: %s", srcPath.c_str());
154 6 : return ret;
155 : }
156 :
157 23 : File dstFile(dstPath, M_CREAT | M_WRONLY | M_TRUNC, READ_WRITE_MODE);
158 23 : ret = dstFile.IsFileOpen();
159 23 : if (ret != ADUMP_SUCCESS) {
160 4 : IDE_LOGE("Open dst file failed, file: %s", dstPath.c_str());
161 4 : return ret;
162 : }
163 :
164 19 : char buffer[MAX_BUFFER_LENGTH] = {0};
165 19 : int64_t size = 0;
166 : do {
167 54 : size = srcFile.Read(buffer, MAX_BUFFER_LENGTH);
168 54 : if (size < 0) {
169 0 : IDE_LOGE("Read file failed, file: %s", srcPath.c_str());
170 0 : return ADUMP_FAILED;
171 : }
172 54 : IDE_LOGD("Read file size: %ld bytes", size);
173 54 : if (size > 0) {
174 41 : const auto writeSize = dstFile.Write(buffer, size);
175 41 : if (writeSize < 0) {
176 6 : IDE_LOGE("Write file failed, file: %s", dstPath.c_str());
177 6 : return ADUMP_FAILED;
178 : }
179 : }
180 48 : } while (size > 0);
181 13 : return ADUMP_SUCCESS;
182 29 : }
183 :
184 : /**
185 : * @brief : add map item into mapping.csv
186 : * @param [in] : filePath file path
187 : * @param [in] : hashName hash value of file name
188 : * @return : ADUMP_SUCCESS: success; ADUMP_FAILED: failed
189 : */
190 9 : int32_t File::AddMapping(const std::string& filePath, const std::string& fileName, const std::string& hashName)
191 : {
192 9 : IDE_CTRL_VALUE_FAILED(!filePath.empty(), return ADUMP_FAILED, "FilePath is empty");
193 9 : IDE_CTRL_VALUE_FAILED(!hashName.empty(), return ADUMP_FAILED, "HashName is empty");
194 :
195 9 : Path parentPath(filePath);
196 9 : std::string mappingFile = parentPath.Concat('/' + MAPPING_FILE_NAME).GetString();
197 9 : fd_ = mmOpen2(mappingFile.c_str(), O_APPEND | M_RDWR | M_CREAT, M_IRUSR | M_IWRITE);
198 9 : IDE_CTRL_VALUE_FAILED(fd_ >= 0, return ADUMP_FAILED, "Open mapping file failed, fd: %d", fd_);
199 :
200 6 : std::string mapping = hashName + ',' + fileName + '\n';
201 6 : uint32_t mappingLen = mapping.length();
202 6 : uint32_t residLen = mappingLen;
203 :
204 : do {
205 : mmSsize_t writeLen =
206 6 : mmWrite(fd_, const_cast<AdxStringBuffer>(mapping.c_str()) + (mappingLen - residLen), residLen);
207 6 : if (writeLen < 0) {
208 0 : IDE_LOGE("Write failed, info: %s, write length: %ld bytes", strerror(errno), writeLen);
209 0 : (void)Close();
210 0 : return ADUMP_FAILED;
211 : }
212 6 : if (residLen >= static_cast<uint32_t>(writeLen)) {
213 3 : residLen -= static_cast<uint32_t>(writeLen);
214 : } else {
215 3 : IDE_LOGE("Write failed, info: %s, write length larger than remaining length", strerror(errno));
216 3 : (void)Close();
217 3 : return ADUMP_FAILED;
218 : }
219 3 : } while (residLen != 0);
220 :
221 3 : (void)Close();
222 3 : return ADUMP_SUCCESS;
223 9 : }
224 : } // namespace Adx
|