LCOV - code coverage report
Current view: top level - atrace/utrace/recorder - trace_recorder.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.6 % 337 312
Test Date: 2026-07-28 10:53:44 Functions: 95.5 % 22 21

            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              : }
        

Generated by: LCOV version 2.0-1