LCOV - code coverage report
Current view: top level - atrace/utrace/recorder - trace_recorder.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.4 % 361 337
Test Date: 2026-08-31 10:07:06 Functions: 96.4 % 28 27

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

Generated by: LCOV version 2.0-1