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 223 : File::File(const std::string &path, int32_t flag, mmMode_t mode, bool lazyOpen)
26 223 : : filePath_(path), fd_(INVALID_FILE_FD), flag_(flag), mode_(mode)
27 : {
28 223 : if (lazyOpen) {
29 72 : return;
30 : }
31 151 : if (Open(flag, mode) != ADUMP_SUCCESS) {
32 15 : fd_ = INVALID_FILE_FD;
33 : }
34 0 : }
35 :
36 21 : int32_t File::EnsureOpen()
37 : {
38 21 : if (fd_ != INVALID_FILE_FD) {
39 0 : return ADUMP_SUCCESS;
40 : }
41 21 : if (Open(flag_, mode_) != ADUMP_SUCCESS) {
42 0 : fd_ = INVALID_FILE_FD;
43 0 : return ADUMP_FAILED;
44 : }
45 21 : return ADUMP_SUCCESS;
46 : }
47 :
48 223 : File::~File()
49 : {
50 223 : (void)Close();
51 223 : }
52 :
53 172 : int32_t File::Open(int32_t flag, mmMode_t mode)
54 : {
55 172 : Path filePath(filePath_);
56 172 : std::string fileName = filePath.GetFileName();
57 172 : Path parentPath = filePath.ParentPath();
58 172 : if (!parentPath.Empty() && !parentPath.RealPath()) {
59 3 : IDE_LOGE("Real file path failed, file: %s", filePath_.c_str());
60 3 : return ADUMP_FAILED;
61 : }
62 :
63 169 : std::string realFilePath = parentPath.Concat(fileName).GetString();
64 169 : fd_ = mmOpen2(realFilePath.c_str(), flag, mode);
65 169 : if (fd_ >= 0) {
66 154 : return ADUMP_SUCCESS;
67 : }
68 15 : if (mmGetErrorCode() != ENAMETOOLONG) {
69 9 : IDE_LOGE("Open file failed. file: %s, fd: %d, message: %s", realFilePath.c_str(), fd_, strerror(errno));
70 9 : return ADUMP_FAILED;
71 : }
72 6 : parentPath = filePath.ParentPath();
73 6 : if (!parentPath.Empty() && !parentPath.RealPath()) {
74 0 : IDE_LOGE("Real long name file path failed, file: %s", filePath_.c_str());
75 0 : return ADUMP_FAILED;
76 : }
77 6 : std::string hashName = std::to_string(std::hash<std::string>{}(fileName));
78 6 : if (AddMapping(parentPath.GetString(), fileName, hashName) != ADUMP_SUCCESS) {
79 3 : IDE_LOGE("Add mapping item [ %s ] failed", hashName.c_str());
80 : }
81 6 : realFilePath = parentPath.Concat(hashName).GetString();
82 6 : IDE_LOGW("File name [ %s ] too long rename as [ %s ] and the mapping record in %s",
83 : fileName.c_str(), realFilePath.c_str(), MAPPING_FILE_NAME.c_str());
84 6 : fd_ = mmOpen2(realFilePath.c_str(), O_APPEND | M_RDWR | M_CREAT, M_IREAD | M_IWRITE);
85 6 : IDE_CTRL_VALUE_FAILED(fd_ >= 0, return ADUMP_FAILED, "Open hash file failed, fd: %d", fd_);
86 3 : return ADUMP_SUCCESS;
87 172 : }
88 :
89 0 : int32_t File::GetFileDiscriptor() const
90 : {
91 0 : return fd_;
92 : }
93 :
94 142 : int32_t File::IsFileOpen() const
95 : {
96 142 : if (fd_ == INVALID_FILE_FD) {
97 15 : return ADUMP_FAILED;
98 : }
99 127 : return ADUMP_SUCCESS;
100 : }
101 :
102 235 : int32_t File::Close()
103 : {
104 235 : if (fd_ == INVALID_FILE_FD) {
105 72 : return ADUMP_SUCCESS;
106 : }
107 :
108 163 : const int32_t ret = mmClose(fd_);
109 163 : if (ret != EN_OK) {
110 6 : IDE_LOGW("Can not close file handle, file: %s, ret: %d.", filePath_.c_str(), ret);
111 6 : return ADUMP_FAILED;
112 : }
113 157 : fd_ = INVALID_FILE_FD;
114 157 : return ADUMP_SUCCESS;
115 : }
116 :
117 278 : int64_t File::Write(const char *const buffer, int64_t length) const
118 : {
119 278 : mmSsize_t ret = 0;
120 278 : UINT32 reserve = static_cast<UINT32>(length);
121 : do {
122 284 : ret = mmWrite(fd_, const_cast<char *>(buffer) + (static_cast<UINT32>(length) - reserve), reserve);
123 284 : if ((ret == EN_ERROR) && (mmGetErrorCode() == EINTR)) {
124 0 : continue;
125 : }
126 284 : if (ret < 0 || static_cast<UINT32>(ret) > reserve) {
127 9 : IDE_LOGE("Write data failed, buff: %p, length: %ld, ret: %zd", buffer, length, ret);
128 9 : break;
129 : }
130 275 : reserve -= ret;
131 275 : if (reserve == 0) {
132 269 : break;
133 : }
134 : } while (true);
135 :
136 278 : return static_cast<int64_t>(ret);
137 : }
138 :
139 79 : int64_t File::Read(char *buffer, int64_t length) const
140 : {
141 : mmSsize_t ret;
142 : do {
143 79 : ret = mmRead(fd_, buffer, static_cast<UINT32>(length));
144 79 : } while (ret == EN_ERROR && mmGetErrorCode() == EINTR);
145 :
146 79 : if (ret == EN_ERROR) {
147 3 : IDE_LOGE("Read data failed, buff: %p, length: %ld bytes, ret: %zd", buffer, length, ret);
148 : }
149 79 : return static_cast<int64_t>(ret);
150 : }
151 :
152 29 : int32_t File::Copy(const std::string &srcPath, const std::string &dstPath)
153 : {
154 29 : IDE_LOGI("copy file from %s to %s", srcPath.c_str(), dstPath.c_str());
155 29 : File srcFile(srcPath, M_RDONLY);
156 29 : int32_t ret = srcFile.IsFileOpen();
157 29 : if (ret != ADUMP_SUCCESS) {
158 6 : IDE_LOGE("Open src file failed, file: %s", srcPath.c_str());
159 6 : return ret;
160 : }
161 :
162 23 : File dstFile(dstPath, M_CREAT | M_WRONLY | M_TRUNC, READ_WRITE_MODE);
163 23 : ret = dstFile.IsFileOpen();
164 23 : if (ret != ADUMP_SUCCESS) {
165 0 : IDE_LOGE("Open dst file failed, file: %s", dstPath.c_str());
166 0 : return ret;
167 : }
168 :
169 23 : char buffer[MAX_BUFFER_LENGTH] = { 0 };
170 23 : int64_t size = 0;
171 : do {
172 76 : size = srcFile.Read(buffer, MAX_BUFFER_LENGTH);
173 76 : if (size < 0) {
174 0 : IDE_LOGE("Read file failed, file: %s", srcPath.c_str());
175 0 : return ADUMP_FAILED;
176 : }
177 76 : IDE_LOGD("Read file size: %ld bytes", size);
178 76 : if (size > 0) {
179 59 : const auto writeSize = dstFile.Write(buffer, size);
180 59 : if (writeSize < 0) {
181 6 : IDE_LOGE("Write file failed, file: %s", dstPath.c_str());
182 6 : return ADUMP_FAILED;
183 : }
184 : }
185 70 : } while (size > 0);
186 17 : return ADUMP_SUCCESS;
187 29 : }
188 :
189 : /**
190 : * @brief : add map item into mapping.csv
191 : * @param [in] : filePath file path
192 : * @param [in] : hashName hash value of file name
193 : * @return : ADUMP_SUCCESS: success; ADUMP_FAILED: failed
194 : */
195 6 : int32_t File::AddMapping(const std::string &filePath, const std::string &fileName, const std::string &hashName)
196 : {
197 6 : IDE_CTRL_VALUE_FAILED(!filePath.empty(), return ADUMP_FAILED, "FilePath is empty");
198 6 : IDE_CTRL_VALUE_FAILED(!hashName.empty(), return ADUMP_FAILED, "HashName is empty");
199 :
200 6 : Path parentPath(filePath);
201 6 : std::string mappingFile = parentPath.Concat('/' + MAPPING_FILE_NAME).GetString();
202 6 : fd_ = mmOpen2(mappingFile.c_str(), O_APPEND | M_RDWR | M_CREAT, M_IRUSR | M_IWRITE);
203 6 : IDE_CTRL_VALUE_FAILED(fd_ >= 0, return ADUMP_FAILED, "Open mapping file failed, fd: %d", fd_);
204 :
205 3 : std::string mapping = hashName + ',' + fileName + '\n';
206 3 : uint32_t mappingLen = mapping.length();
207 3 : uint32_t residLen = mappingLen;
208 :
209 : do {
210 3 : mmSsize_t writeLen = mmWrite(fd_, const_cast<AdxStringBuffer>(mapping.c_str()) + (mappingLen - residLen),
211 : residLen);
212 3 : if (writeLen < 0) {
213 0 : IDE_LOGE("Write failed, info: %s, write length: %ld bytes", strerror(errno), writeLen);
214 0 : (void)Close();
215 0 : return ADUMP_FAILED;
216 : }
217 3 : if (residLen >= static_cast<uint32_t>(writeLen)) {
218 3 : residLen -= static_cast<uint32_t>(writeLen);
219 : } else {
220 0 : IDE_LOGE("Write failed, info: %s, write length larger than resid length", strerror(errno));
221 0 : (void)Close();
222 0 : return ADUMP_FAILED;
223 : }
224 3 : } while (residLen != 0);
225 :
226 3 : (void)Close();
227 3 : return ADUMP_SUCCESS;
228 6 : }
229 : } // namespace Adx
|