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

Generated by: LCOV version 2.0-1