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 "trace_recorder.h"
12 : #include "adiag_print.h"
13 : #include "trace_system_api.h"
14 : #include "trace_attr.h"
15 : #include "trace_types.h"
16 :
17 : #define TRACE_FILE_ASCEND_PATH "ascend"
18 : #define TRACE_FILE_SUB_PATH "atrace"
19 : #define TRACE_DIR_HEAD "trace"
20 : #define TRACE_DIR_MODE 0750U
21 : #define TRACE_FILE_MODE 0640U
22 : #define FILE_SEPARATOR "/"
23 :
24 : #define TRACE_DIR_NUM_DEFAULT 10
25 : #define TRACE_DIR_NUM_MIN 10
26 : #define TRACE_DIR_NUM_MAX 1000
27 :
28 : STATIC TraceRecorderMgr *g_recorderMgr = NULL;
29 :
30 : #ifndef ATRACE_ROOT_PATH
31 1670 : STATIC TraStatus TraceGetHomeDir(char *const homedir, uint32_t len)
32 : {
33 1670 : ADIAG_CHK_NULL_PTR(homedir, return TRACE_FAILURE);
34 :
35 : int32_t ret;
36 1670 : const struct passwd *userInfo = getpwuid(getuid());
37 1670 : if (userInfo != NULL) {
38 1670 : ret = strcpy_s(homedir, len, userInfo->pw_dir);
39 : } else {
40 0 : ret = strcpy_s(homedir, len, "");
41 : }
42 1670 : ADIAG_CHK_EXPR_ACTION(ret != EOK, return TRACE_FAILURE,
43 : "strcpy_s home directory failed, result=%d, strerr=%s.", ret, strerror(AdiagGetErrorCode()));
44 :
45 1670 : ADIAG_INF("home_directory=%s.", homedir);
46 1670 : return TRACE_SUCCESS;
47 : }
48 :
49 200 : STATIC TraStatus TraceMkdirRecur(const char *dirPath)
50 : {
51 200 : TraStatus err = TRACE_SUCCESS;
52 200 : char *newDir = strdup(dirPath);
53 200 : if (newDir == NULL) {
54 20 : ADIAG_ERR("strdup failed, strerr=%s.", strerror(AdiagGetErrorCode()));
55 20 : return TRACE_FAILURE;
56 : }
57 180 : char *path = (char *)AdiagMalloc(MAX_FILEDIR_LEN + 1U);
58 180 : ADIAG_CHK_EXPR_ACTION(path == NULL, return TRACE_FAILURE,
59 : "malloc path failed, strerr=%s", strerror(AdiagGetErrorCode()));
60 :
61 180 : char *tmpNewDir = newDir;
62 180 : char *tmpPath = path;
63 180 : char *token = strsep(&newDir, FILE_SEPARATOR);
64 1060 : while (token != NULL) {
65 960 : if (strcmp(token, "") == 0) {
66 220 : token = strsep(&newDir, FILE_SEPARATOR);
67 220 : continue;
68 : }
69 740 : char nextDir[MAX_FILEDIR_LEN + 1U] = { 0 };
70 740 : int32_t ret = snprintf_s(nextDir, MAX_FILEDIR_LEN + 1U, MAX_FILEDIR_LEN, "/%s", token);
71 740 : if (ret == -1) {
72 20 : ADIAG_ERR("copy data failed, strerr=%s.", strerror(AdiagGetErrorCode()));
73 20 : err = TRACE_FAILURE;
74 80 : break;
75 : }
76 720 : ret = strncat_s(path, MAX_FILEDIR_LEN + 1U, nextDir, strlen(nextDir));
77 720 : if (ret != 0) {
78 20 : ADIAG_ERR("strncat_s failed, strerr=%s.", strerror(AdiagGetErrorCode()));
79 20 : err = TRACE_FAILURE;
80 20 : break;
81 : }
82 700 : err = TraceMkdir((const char *)path, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
83 700 : if (err != TRACE_SUCCESS) {
84 40 : ADIAG_ERR("mkdir failed, strerr=%s.", strerror(AdiagGetErrorCode()));
85 40 : break;
86 : }
87 660 : token = strsep(&newDir, FILE_SEPARATOR);
88 : }
89 180 : ADIAG_SAFE_FREE(tmpPath);
90 180 : ADIAG_SAFE_FREE(tmpNewDir);
91 180 : return err;
92 : }
93 :
94 460 : STATIC TraStatus TraceNormalizeEnvPath(char *envDir, uint32_t len)
95 : {
96 460 : if ((envDir == NULL) || (len == 0U) || (envDir[0] == '\0')) {
97 20 : ADIAG_WAR("ASCEND_WORK_PATH is invalid.");
98 20 : return TRACE_FAILURE;
99 : }
100 440 : if (envDir[0] == '/') {
101 320 : return TRACE_SUCCESS;
102 : }
103 :
104 120 : char cwd[MAX_FILEDIR_LEN + 1U] = { 0 };
105 120 : if (getcwd(cwd, sizeof(cwd)) == NULL) {
106 20 : ADIAG_WAR("get current directory failed, strerr=%s.", strerror(AdiagGetErrorCode()));
107 20 : return TRACE_FAILURE;
108 : }
109 :
110 100 : char absPath[MAX_FILEDIR_LEN + 1U] = { 0 };
111 100 : int32_t ret = snprintf_s(absPath, sizeof(absPath), sizeof(absPath) - 1U, "%s/%s", cwd, envDir);
112 100 : if (ret == -1) {
113 20 : ADIAG_WAR("build ASCEND_WORK_PATH absolute path failed, path may exceed %u bytes, cwd=%s, env=%s.",
114 : MAX_FILEDIR_LEN, cwd, envDir);
115 20 : return TRACE_FAILURE;
116 : }
117 80 : ret = strcpy_s(envDir, len, absPath);
118 80 : if (ret != EOK) {
119 20 : ADIAG_WAR("copy ASCEND_WORK_PATH absolute path failed, ret=%d.", ret);
120 20 : return TRACE_FAILURE;
121 : }
122 60 : return TRACE_SUCCESS;
123 : }
124 :
125 460 : STATIC TraStatus TraceGetValidPath(char *envDir, uint32_t len)
126 : {
127 460 : if (TraceNormalizeEnvPath(envDir, len) != TRACE_SUCCESS) {
128 80 : return TRACE_FAILURE;
129 : }
130 380 : if ((TraceAccess(envDir, F_OK) != EN_OK) && (TraceMkdirRecur(envDir) != EN_OK)) {
131 100 : ADIAG_WAR("path %s doesn't exist.", envDir);
132 100 : return TRACE_FAILURE;
133 : }
134 280 : if (TraceAccess(envDir, W_OK) != EN_OK) {
135 20 : ADIAG_WAR("path %s doesn't have write permission.", envDir);
136 20 : return TRACE_FAILURE;
137 : }
138 :
139 260 : char *realPath = (char *)AdiagMalloc(TRACE_MAX_PATH);
140 260 : ADIAG_CHK_EXPR_ACTION(realPath == NULL, return TRACE_FAILURE,
141 : "malloc real path failed, strerr=%s", strerror(AdiagGetErrorCode()));
142 :
143 260 : if ((TraceRealPath(envDir, realPath, TRACE_MAX_PATH) != EN_OK) && (AdiagGetErrorCode() != ENOENT)) {
144 20 : ADIAG_WAR("can not get realpath, path=%s, strerr=%s.", envDir, strerror(AdiagGetErrorCode()));
145 20 : ADIAG_SAFE_FREE(realPath);
146 20 : return TRACE_FAILURE;
147 : }
148 240 : int32_t res = snprintf_truncated_s(envDir, len, "%s", realPath);
149 240 : if (res < 0) {
150 0 : ADIAG_ERR("get path failed, ret=%d.", res);
151 0 : ADIAG_SAFE_FREE(realPath);
152 0 : return TRACE_FAILURE;
153 : }
154 240 : ADIAG_SAFE_FREE(realPath);
155 240 : return TRACE_SUCCESS;
156 : }
157 :
158 1910 : STATIC TraStatus TraceGetEnvPath(char *envDir, uint32_t len)
159 : {
160 1910 : const char *env = NULL;
161 1910 : MM_SYS_GET_ENV(MM_ENV_ASCEND_WORK_PATH, (env));
162 1910 : TraStatus ret = TraceHandleEnvString(env, envDir, len);
163 1910 : if (ret != TRACE_SUCCESS) {
164 1450 : return TRACE_FAILURE;
165 : }
166 460 : ADIAG_RUN_INF("get path by env ASCEND_WORK_PATH: %s", envDir);
167 :
168 460 : ret = TraceGetValidPath(envDir, len);
169 460 : if (ret != TRACE_SUCCESS) {
170 220 : ADIAG_RUN_INF("can not use ASCEND_WORK_PATH, please check the warning logs.");
171 220 : return TRACE_FAILURE;
172 : }
173 240 : return TRACE_SUCCESS;
174 : }
175 : #endif
176 :
177 : /**
178 : * @brief get dir num by env
179 : * @param [in] mgr: recorder manager
180 : * @return void
181 : */
182 1910 : STATIC void TraceInitDirNum(TraceRecorderMgr *mgr)
183 : {
184 1910 : mgr->maxDirNum = TRACE_DIR_NUM_DEFAULT;
185 1910 : const char *env = NULL;
186 1910 : MM_SYS_GET_ENV(MM_ENV_ASCEND_TRACE_RECORD_NUM, (env));
187 1910 : if (env == NULL) {
188 1810 : ADIAG_INF("doesn't set env ASCEND_TRACE_RECORD_NUM, use default dir num=%d.", mgr->maxDirNum);
189 1810 : return;
190 : }
191 :
192 100 : ADIAG_RUN_INF("get dir num by env ASCEND_TRACE_RECORD_NUM: %s", env);
193 100 : int32_t value = -1;
194 100 : if ((AdiagStrToInt(env, &value) == TRACE_SUCCESS) && (value <= TRACE_DIR_NUM_MAX) && (value >= TRACE_DIR_NUM_MIN)) {
195 100 : ADIAG_INF("set dir num=%d by env ASCEND_TRACE_RECORD_NUM.", value);
196 100 : mgr->maxDirNum = value;
197 : } else {
198 0 : ADIAG_WAR("invalid value [%s] for ASCEND_TRACE_RECORD_NUM, expected range: [10, 1000]. Use default dir num=%d.", env, mgr->maxDirNum);
199 : }
200 : }
201 :
202 : /**
203 : * @brief get root path
204 : * @param [in] mgr: recorder manager
205 : * @return TraStatus
206 : */
207 1910 : STATIC TraStatus TraceInitRootPath(TraceRecorderMgr *mgr)
208 : {
209 1910 : ADIAG_CHK_NULL_PTR(mgr, return TRACE_FAILURE);
210 : int32_t res;
211 :
212 : #ifdef ATRACE_ROOT_PATH
213 : res = snprintf_truncated_s(mgr->rootPath, MAX_FILEDIR_LEN + 1U, "%s", ATRACE_ROOT_PATH);
214 : if (res < 0) {
215 : ADIAG_ERR("snprintf_truncated_s failed, ret=%d.", res);
216 : return TRACE_FAILURE;
217 : }
218 : #else
219 1910 : char *path = (char *)AdiagMalloc(MAX_FILEDIR_LEN + 1U);
220 1910 : ADIAG_CHK_EXPR_ACTION(path == NULL, return TRACE_FAILURE,
221 : "malloc root path failed, strerr=%s", strerror(AdiagGetErrorCode()));
222 :
223 1910 : TraStatus ret = TraceGetEnvPath(path, MAX_FILEDIR_LEN + 1U);
224 1910 : if (ret == TRACE_SUCCESS) {
225 240 : res = snprintf_truncated_s(mgr->rootPath, MAX_FILEDIR_LEN + 1U, "%s", path);
226 : } else {
227 : // get process user home path
228 1670 : ret = TraceGetHomeDir(path, MAX_FILEDIR_LEN + 1U);
229 1670 : if (ret != TRACE_SUCCESS) {
230 0 : ADIAG_SAFE_FREE(path);
231 0 : ADIAG_ERR("get home directory failed, ret=%d.", ret);
232 0 : return TRACE_FAILURE;
233 : }
234 1670 : res = snprintf_truncated_s(mgr->rootPath, MAX_FILEDIR_LEN + 1U, "%s/%s",
235 : path, TRACE_FILE_ASCEND_PATH);
236 : }
237 :
238 1910 : if (res < 0) {
239 0 : ADIAG_SAFE_FREE(path);
240 0 : ADIAG_ERR("snprintf_truncated_s failed, ret=%d.", res);
241 0 : return TRACE_FAILURE;
242 : }
243 1910 : ADIAG_SAFE_FREE(path);
244 : #endif
245 1910 : ADIAG_INF("use root path: %s", mgr->rootPath);
246 1910 : return TRACE_SUCCESS;
247 : }
248 :
249 3808 : STATIC void TraceRecorderClearList(TraceDirList *list)
250 : {
251 3808 : TraceDirNode *curNode = list->head;
252 3808 : TraceDirNode *next = NULL;
253 4989 : while (curNode != NULL) {
254 1181 : next = curNode->next;
255 1181 : ADIAG_SAFE_FREE(curNode);
256 1181 : curNode = next;
257 : }
258 3808 : list->count = 0;
259 3808 : }
260 :
261 1910 : TraStatus TraceRecorderInit(void)
262 : {
263 1910 : g_recorderMgr = (TraceRecorderMgr *)AdiagMalloc(sizeof(TraceRecorderMgr));
264 1910 : ADIAG_CHK_EXPR_ACTION(g_recorderMgr == NULL, return TRACE_FAILURE, "init recorder mgr failed.");
265 :
266 1910 : TraStatus ret = TraceInitRootPath(g_recorderMgr);
267 1910 : if (ret != TRACE_SUCCESS) {
268 0 : ADIAG_SAFE_FREE(g_recorderMgr);
269 0 : ADIAG_ERR("init file root path failed, ret=%d.", ret);
270 0 : return TRACE_FAILURE;
271 : }
272 :
273 1910 : TraceInitDirNum(g_recorderMgr);
274 :
275 1910 : return TRACE_SUCCESS;
276 : }
277 :
278 1980 : void TraceRecorderExit(void)
279 : {
280 1980 : if (g_recorderMgr == NULL) {
281 76 : ADIAG_WAR("file list is null.");
282 76 : return;
283 : }
284 :
285 1904 : TraceRecorderClearList(&g_recorderMgr->hostDirList);
286 1904 : TraceRecorderClearList(&g_recorderMgr->deviceDirList);
287 1904 : if (g_recorderMgr->exitDir != NULL) {
288 41 : ADIAG_SAFE_FREE(g_recorderMgr->exitDir);
289 : }
290 1904 : ADIAG_SAFE_FREE(g_recorderMgr);
291 : }
292 :
293 1860 : STATIC TraceDirNode *TraceRecorderListPopHead(TraceDirList *dirList)
294 : {
295 1860 : (void)AdiagLockGet(&dirList->lock);
296 1860 : TraceDirNode *dirNode = dirList->head;
297 1860 : dirList->head = dirNode->next;
298 1860 : if (dirList->head != NULL) {
299 1860 : dirList->head->prev = NULL;
300 : } else {
301 0 : dirList->tail = NULL;
302 : }
303 1860 : dirNode->next = NULL;
304 1860 : dirNode->prev = NULL;
305 1860 : dirList->count--;
306 1860 : (void)AdiagLockRelease(&dirList->lock);
307 1860 : return dirNode;
308 : }
309 :
310 3042 : STATIC void TraceRecorderListAppend(TraceDirList *dirList, TraceDirNode *newNode)
311 : {
312 3042 : (void)AdiagLockGet(&dirList->lock);
313 3042 : newNode->prev = dirList->tail;
314 3042 : newNode->next = NULL;
315 3042 : if (dirList->tail != NULL) {
316 2740 : dirList->tail->next = newNode;
317 : } else {
318 302 : dirList->head = newNode;
319 : }
320 3042 : dirList->tail = newNode;
321 3042 : dirList->count++;
322 3042 : (void)AdiagLockRelease(&dirList->lock);
323 3042 : }
324 :
325 3282 : STATIC TraceDirNode *TraceRecorderListFind(TraceDirList *dirList, const char *dirPath)
326 : {
327 3282 : (void)AdiagLockGet(&dirList->lock);
328 3282 : TraceDirNode *curNode = dirList->head;
329 26062 : while (curNode != NULL) {
330 23020 : if (strcmp(curNode->dirPath, dirPath) == 0) {
331 240 : (void)AdiagLockRelease(&dirList->lock);
332 240 : return curNode;
333 : }
334 22780 : curNode = curNode->next;
335 : }
336 3042 : (void)AdiagLockRelease(&dirList->lock);
337 3042 : return NULL;
338 : }
339 :
340 3104 : STATIC void TraceRecorderSaveNode(const TraceDirInfo *dirInfo, TraceDirNode *dirNew)
341 : {
342 : // if exit_event, no need to aging
343 3104 : if (strncmp(dirInfo->eventName, TRACER_EVENT_EXIT, strlen(TRACER_EVENT_EXIT)) == 0) {
344 62 : if (g_recorderMgr->exitDir != NULL) {
345 21 : ADIAG_SAFE_FREE(g_recorderMgr->exitDir);
346 : }
347 62 : g_recorderMgr->exitDir = dirNew;
348 62 : return;
349 : }
350 :
351 3042 : TraceDirList *dirList = (dirInfo->isDevice) ? &g_recorderMgr->deviceDirList : &g_recorderMgr->hostDirList;
352 : // delete node and age the dir
353 3042 : if (dirList->count >= g_recorderMgr->maxDirNum) {
354 1860 : TraceDirNode *deleteNode = TraceRecorderListPopHead(dirList);
355 1860 : TraStatus ret = TraceRmdir(deleteNode->dirPath);
356 1860 : if (ret != 0) {
357 0 : ADIAG_WAR("can not remove dir %s, ret=%d, strerr=%s.", deleteNode->dirPath, ret, strerror(AdiagGetErrorCode()));
358 : } else {
359 1860 : ADIAG_INF("remove dir %s successfully.", deleteNode->dirPath);
360 : }
361 1860 : ADIAG_SAFE_FREE(deleteNode);
362 : }
363 : // append new node
364 3042 : TraceRecorderListAppend(dirList, dirNew);
365 : }
366 :
367 10152 : STATIC TraStatus TraceRecorderCreateDirWithCheck(const char *path)
368 : {
369 10152 : TraStatus ret = TraceMkdir(path, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
370 10152 : if (ret != TRACE_SUCCESS) {
371 60 : ADIAG_ERR("mkdir %s failed, strerr=%s.", path, strerror(AdiagGetErrorCode()));
372 60 : return TRACE_FAILURE;
373 : }
374 10092 : return ret;
375 : }
376 :
377 3424 : const TraceDirNode *TraceRecorderGetDirPath(const TraceDirInfo *dirInfo)
378 : {
379 : // ~/ascend
380 3424 : int32_t ret = TraceMkdir(g_recorderMgr->rootPath, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
381 3424 : if (ret != TRACE_SUCCESS) {
382 20 : ADIAG_ERR("mkdir %s failed, strerr=%s.", g_recorderMgr->rootPath, strerror(AdiagGetErrorCode()));
383 20 : return NULL;
384 : }
385 :
386 3404 : TraceDirNode *dirNew = (TraceDirNode *)AdiagMalloc(sizeof(TraceDirNode));
387 3404 : ADIAG_CHK_EXPR_ACTION(dirNew == NULL, return NULL, "create dir failed.");
388 :
389 : // ~/ascend/atrace
390 3404 : ret = snprintf_s(dirNew->dirPath, MAX_FILEPATH_LEN + 1U, MAX_FILEPATH_LEN, "%s/%s",
391 3404 : g_recorderMgr->rootPath, TRACE_FILE_SUB_PATH);
392 3404 : if ((ret == -1) || (TraceRecorderCreateDirWithCheck(dirNew->dirPath) != TRACE_SUCCESS)) {
393 20 : ADIAG_ERR("failed at atrace directory, strerr=%s.", strerror(AdiagGetErrorCode()));
394 20 : ADIAG_SAFE_FREE(dirNew);
395 20 : return NULL;
396 : }
397 :
398 : // ~/ascend/atrace/trace_{attr_group_id}_{attr_pid}_{attr_time}
399 3384 : ret = snprintf_s(dirNew->dirPath, MAX_FILEPATH_LEN + 1U, MAX_FILEPATH_LEN, "%s/%s/%s_%d_%d_%s",
400 3384 : g_recorderMgr->rootPath, TRACE_FILE_SUB_PATH,
401 : TRACE_DIR_HEAD, TraceAttrGetPgid(), TraceAttrGetPid(), TraceAttrGetTime());
402 3384 : if ((ret == -1) || (TraceRecorderCreateDirWithCheck(dirNew->dirPath) != TRACE_SUCCESS)) {
403 20 : ADIAG_ERR("failed at first directory, strerr=%s.", strerror(AdiagGetErrorCode()));
404 20 : ADIAG_SAFE_FREE(dirNew);
405 20 : return NULL;
406 : }
407 :
408 : // ~/ascend/atrace/trace_{attr_group_id}_{attr_pid}_{attr_time}/{tracer_name}_event_{pid}_time
409 3364 : ret = snprintf_s(dirNew->dirPath, MAX_FILEPATH_LEN + 1U, MAX_FILEPATH_LEN, "%s/%s/%s_%d_%d_%s/%s_event_%d_%s",
410 3364 : g_recorderMgr->rootPath, TRACE_FILE_SUB_PATH,
411 : TRACE_DIR_HEAD, TraceAttrGetPgid(), TraceAttrGetPid(), TraceAttrGetTime(),
412 3364 : dirInfo->eventName,dirInfo->pid, dirInfo->dirTime);
413 3364 : if ((ret == -1) || (TraceRecorderCreateDirWithCheck(dirNew->dirPath) != TRACE_SUCCESS)) {
414 20 : ADIAG_ERR("failed at second directory, strerr=%s.", strerror(AdiagGetErrorCode()));
415 20 : ADIAG_SAFE_FREE(dirNew);
416 20 : return NULL;
417 : }
418 :
419 3344 : if (strncmp(dirInfo->eventName, TRACER_EVENT_EXIT, strlen(TRACER_EVENT_EXIT)) != 0) {
420 3282 : TraceDirList *dirList = (dirInfo->isDevice) ? &g_recorderMgr->deviceDirList : &g_recorderMgr->hostDirList;
421 3282 : TraceDirNode *existNode = TraceRecorderListFind(dirList, dirNew->dirPath);
422 3282 : if (existNode != NULL) {
423 240 : ADIAG_SAFE_FREE(dirNew);
424 240 : return existNode;
425 : }
426 : }
427 :
428 3104 : TraceRecorderSaveNode(dirInfo, dirNew);
429 3104 : return dirNew;
430 : }
431 :
432 3364 : TraStatus TraceRecorderGetFd(const TraceDirInfo *dirInfo, const TraceFileInfo *fileInfo, int32_t *fd)
433 : {
434 3364 : ADIAG_CHK_NULL_PTR(fileInfo, return TRACE_FAILURE);
435 3364 : ADIAG_CHK_NULL_PTR(dirInfo, return TRACE_FAILURE);
436 3364 : (void)AdiagLockGet(&g_recorderMgr->lock);
437 3364 : const TraceDirNode *dir = TraceRecorderGetDirPath(dirInfo);
438 3364 : if (dir == NULL) {
439 20 : ADIAG_ERR("get dir failed.");
440 20 : (void)AdiagLockRelease(&g_recorderMgr->lock);
441 20 : return TRACE_FAILURE;
442 : }
443 :
444 3344 : char filePath[MAX_FULLPATH_LEN + 1U] = { 0 };
445 3344 : int32_t ret = snprintf_s(filePath, MAX_FULLPATH_LEN + 1U, MAX_FULLPATH_LEN,
446 3344 : "%s/%s_tracer_%s%s", dir->dirPath, fileInfo->tracerName, fileInfo->objName, fileInfo->suffix);
447 3344 : if (ret == -1) {
448 0 : int32_t errCode = AdiagGetErrorCode();
449 0 : (void)AdiagLockRelease(&g_recorderMgr->lock);
450 0 : ADIAG_ERR("snprintf_s file path failed, ret=%d, strerr=%s.", ret, strerror(errCode));
451 0 : return TRACE_FAILURE;
452 : }
453 3344 : int32_t fileFd = TraceOpen(filePath, (uint32_t)O_CREAT | (uint32_t)O_WRONLY | (uint32_t)O_APPEND,
454 : TRACE_FILE_MODE);
455 3344 : int32_t errCode = (fileFd < 0) ? AdiagGetErrorCode() : 0;
456 3344 : (void)AdiagLockRelease(&g_recorderMgr->lock);
457 3344 : ADIAG_CHK_EXPR_ACTION(fileFd < 0, return TRACE_FAILURE,
458 : "open file failed, file=%s, strerr=%s.", filePath, strerror(errCode));
459 :
460 3322 : *fd = fileFd;
461 3322 : return TRACE_SUCCESS;
462 : }
463 :
464 66963 : TraStatus TraceRecorderWrite(int32_t fd, const char *msg, uint32_t len)
465 : {
466 66963 : int32_t ret = (int32_t)write(fd, msg, len);
467 66963 : if ((ret < 0) || ((uint32_t)ret != len)) {
468 1 : return TRACE_FAILURE;
469 : }
470 66962 : return TRACE_SUCCESS;
471 : }
472 :
473 567 : TraStatus TraceRecorderSafeMkdirPath(const TraceDirInfo *dirInfo)
474 : {
475 567 : int32_t ret = TraceMkdir(g_recorderMgr->rootPath, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
476 567 : if (ret != TRACE_SUCCESS) {
477 40 : return TRACE_FAILURE;
478 : }
479 :
480 527 : char path[MAX_FULLPATH_LEN + 1U] = { 0 };
481 527 : ret = snprintf_s(path, MAX_FULLPATH_LEN + 1U, MAX_FULLPATH_LEN, "%s/%s",
482 527 : g_recorderMgr->rootPath, TRACE_FILE_SUB_PATH);
483 527 : if (ret == -1) {
484 20 : return TRACE_FAILURE;
485 : }
486 507 : ret = TraceMkdir(path, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
487 507 : if (ret != TRACE_SUCCESS) {
488 40 : return TRACE_FAILURE;
489 : }
490 :
491 467 : ret = snprintf_s(path, MAX_FULLPATH_LEN + 1U, MAX_FULLPATH_LEN, "%s/%s/%s_%d_%d_%s",
492 467 : g_recorderMgr->rootPath, TRACE_FILE_SUB_PATH,
493 : TRACE_DIR_HEAD, TraceAttrGetPgid(), TraceAttrGetPid(), TraceAttrGetTime());
494 467 : if (ret == -1) {
495 20 : return TRACE_FAILURE;
496 : }
497 447 : ret = TraceMkdir(path, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
498 447 : if (ret != TRACE_SUCCESS) {
499 20 : return TRACE_FAILURE;
500 : }
501 :
502 427 : ret = TraceRecorderSafeGetDirPath(dirInfo, path, MAX_FULLPATH_LEN + 1U);
503 427 : if (ret != TRACE_SUCCESS) {
504 20 : return TRACE_FAILURE;
505 : }
506 407 : ret = TraceMkdir(path, TRACE_DIR_MODE, TraceAttrGetUid(), TraceAttrGetGid());
507 407 : if (ret != TRACE_SUCCESS) {
508 20 : return ret;
509 : }
510 387 : return TRACE_SUCCESS;
511 : }
512 :
513 1003 : TraStatus TraceRecorderSafeGetDirPath(const TraceDirInfo *dirInfo, char *path, size_t len)
514 : {
515 1003 : if ((dirInfo == NULL) || (path == NULL) || (len == 0)) {
516 60 : return TRACE_INVALID_PARAM;
517 : }
518 943 : int32_t ret = snprintf_s(path, len, len - 1U, "%s/%s/%s_%d_%d_%s/%s_event_%d_%s",
519 943 : g_recorderMgr->rootPath, TRACE_FILE_SUB_PATH,
520 : TRACE_DIR_HEAD, TraceAttrGetPgid(), TraceAttrGetPid(), TraceAttrGetTime(),
521 943 : dirInfo->eventName, dirInfo->pid, dirInfo->dirTime);
522 943 : if (ret == -1) {
523 40 : return TRACE_FAILURE;
524 : }
525 903 : return TRACE_SUCCESS;
526 : }
527 :
528 : /**
529 : * @brief get file fd to write
530 : use for signal_callback_func, only call reentrant function
531 : * @param [in] dirInfo: dir info, for dir name
532 : * @param [in] fileInfo: file info, for file name
533 : * @param [out] fd: file handle
534 : * @return TraStatus
535 : */
536 336 : TraStatus TraceRecorderSafeGetFd(const TraceDirInfo *dirInfo, const TraceFileInfo *fileInfo, int32_t *fd)
537 : {
538 336 : if ((dirInfo == NULL) || (fileInfo == NULL) || (fd == NULL)) {
539 20 : return TRACE_INVALID_PARAM;
540 : }
541 :
542 316 : char path[MAX_FULLPATH_LEN + 1U] = { 0 };
543 316 : TraStatus ret = TraceRecorderSafeGetDirPath(dirInfo, path, MAX_FULLPATH_LEN + 1U);
544 316 : if (ret != TRACE_SUCCESS) {
545 0 : return ret;
546 : }
547 :
548 316 : ret = TraceRecorderSafeMkdirPath(dirInfo);
549 316 : if (ret != TRACE_SUCCESS) {
550 40 : return ret;
551 : }
552 :
553 276 : char tmp[MAX_FILEDIR_LEN] = { 0 };
554 276 : ret = snprintf_s(tmp, MAX_FILEDIR_LEN, MAX_FULLPATH_LEN - 1U, "/%s_tracer_%s%s",
555 276 : fileInfo->tracerName, fileInfo->objName, fileInfo->suffix);
556 276 : if (ret == -1) {
557 0 : return TRACE_FAILURE;
558 : }
559 276 : errno_t err = strncat_s(path, MAX_FULLPATH_LEN + 1U, tmp, strlen(tmp));
560 276 : if (err != EOK) {
561 20 : return TRACE_FAILURE;
562 : }
563 :
564 256 : err = strncpy_s(g_recorderMgr->corePath, MAX_FULLPATH_LEN + 1U, path, strlen(path));
565 256 : if (err != EOK) {
566 0 : return TRACE_FAILURE;
567 : }
568 :
569 256 : int32_t fileFd = TraceOpen(path, (uint32_t)O_CREAT | (uint32_t)O_WRONLY | (uint32_t)O_APPEND, TRACE_FILE_MODE);
570 256 : if (fileFd < 0) {
571 20 : return TRACE_FAILURE;
572 : }
573 :
574 236 : *fd = fileFd;
575 236 : return TRACE_SUCCESS;
576 : }
577 :
578 0 : const char* TraceRecorderSafeGetFilePath(void)
579 : {
580 0 : return g_recorderMgr->corePath;
581 : }
|