LCOV - code coverage report
Current view: top level - atrace/utrace/utrace_client - utrace_socket.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.8 % 92 90
Test Date: 2026-08-31 10:07:06 Functions: 100.0 % 9 9

            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 "utrace_socket.h"
      12              : #include "adiag_lock.h"
      13              : #include "adiag_utils.h"
      14              : #include "adiag_print.h"
      15              : #include "trace_recorder.h"
      16              : #include "trace_system_api.h"
      17              : 
      18              : STATIC int32_t g_clientSockFd = -1;
      19              : STATIC AdiagLock g_clientSockLock = TRACE_MUTEX_INITIALIZER;
      20              : 
      21           44 : void UtraceSetSocketFd(int32_t fd)
      22              : {
      23           44 :     (void)AdiagLockGet(&g_clientSockLock);
      24           44 :     g_clientSockFd = fd;
      25           44 :     (void)AdiagLockRelease(&g_clientSockLock);
      26           44 : }
      27              : 
      28            2 : int32_t UtraceGetSocketFd(void)
      29              : {
      30            2 :     (void)AdiagLockGet(&g_clientSockLock);
      31            2 :     int32_t fd = g_clientSockFd;
      32            2 :     (void)AdiagLockRelease(&g_clientSockLock);
      33            2 :     return fd;
      34              : }
      35              : 
      36            6 : bool UtraceIsSocketFdValid(void)
      37              : {
      38            6 :     (void)AdiagLockGet(&g_clientSockLock);
      39            6 :     bool isValid = (g_clientSockFd >= 0);
      40            6 :     (void)AdiagLockRelease(&g_clientSockLock);
      41            6 :     return isValid;
      42              : }
      43              : 
      44            2 : STATIC TraStatus TraceGetSocketPathByVfid(uint32_t vfid, char* socketPath, uint32_t pathLen)
      45              : {
      46            2 :     int32_t ret = snprintf_s(socketPath, pathLen, pathLen - 1, "%s%s_%u", SOCKET_FILE_DIR, SOCKET_FILE, vfid);
      47            2 :     if (ret == -1) {
      48            1 :         ADIAG_ERR("snprintf_s failed, strerr=%s, pid=%d, vfid=%u.", strerror(AdiagGetErrorCode()), getpid(), vfid);
      49            1 :         return TRACE_FAILURE;
      50              :     }
      51            1 :     return TRACE_SUCCESS;
      52              : }
      53              : 
      54           13 : STATIC TraStatus TraceGetSocketPathByPfid(char* socketPath, uint32_t pathLen)
      55              : {
      56           13 :     int32_t ret = snprintf_s(socketPath, pathLen, pathLen - 1, "%s%s", SOCKET_FILE_DIR, SOCKET_FILE);
      57           13 :     if (ret == -1) {
      58            1 :         ADIAG_ERR("snprintf_s failed, strerr=%s, pid=%d.", strerror(AdiagGetErrorCode()), getpid());
      59            1 :         return TRACE_FAILURE;
      60              :     }
      61           12 :     return TRACE_SUCCESS;
      62              : }
      63              : 
      64              : /**
      65              :  * @brief           : get socket path when trace server create socket
      66              :  * @param [in]      : devId             device id
      67              :  * @param [out]     : socketPath        socket path
      68              :  * @param [in]      : pathLen           path length
      69              :  * @return          : !=0 failure; ==0 success
      70              :  */
      71           16 : STATIC TraStatus UtraceGetTraceSocketPath(uint32_t devId, char* socketPath, uint32_t pathLen)
      72              : {
      73           16 :     if ((devId >= MIN_VFID_NUM) && (devId <= MAX_VFID_NUM)) {
      74              :         // devId(32~63) is vfid, strcat socket path with "socket_trace_vfid"
      75            2 :         return TraceGetSocketPathByVfid(devId, socketPath, pathLen);
      76           14 :     } else if (devId < MIN_VFID_NUM) {
      77              :         // devId(0~31) is pfid, strcat socket path with "socket_trace"
      78           13 :         return TraceGetSocketPathByPfid(socketPath, pathLen);
      79              :     } else {
      80            1 :         return TRACE_FAILURE;
      81              :     }
      82              : }
      83              : 
      84           17 : int32_t UtraceCreateSocket(uint32_t devId)
      85              : {
      86              :     struct sockaddr_un addr;
      87           17 :     int32_t pid = (int32_t)getpid();
      88           17 :     int32_t sockFd = TraceSocket(AF_UNIX, (uint32_t)SOCK_DGRAM | (uint32_t)SOCK_NONBLOCK, 0);
      89           17 :     ADIAG_CHK_EXPR_ACTION(
      90              :         sockFd == TRACE_FAILURE, return TRACE_FAILURE, "create socket failed, strerr=%s, pid=%d",
      91              :         strerror(AdiagGetErrorCode()), pid);
      92              : 
      93           17 :     const int32_t nSendBuf = 2097152; // 2MB
      94              :     int32_t ret;
      95              :     do {
      96           17 :         ret = setsockopt(sockFd, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
      97           17 :         if (ret < 0) {
      98            1 :             ADIAG_ERR("set socket option failed, strerr=%s, pid=%d.", strerror(AdiagGetErrorCode()), pid);
      99            1 :             break;
     100              :         }
     101              : 
     102           16 :         (void)memset_s(&addr, sizeof(addr), 0, sizeof(addr));
     103              : 
     104           16 :         addr.sun_family = AF_UNIX;
     105           16 :         char socketPath[SOCKET_PATH_MAX_LENGTH + 1U] = {0};
     106           16 :         ret = UtraceGetTraceSocketPath(devId, socketPath, SOCKET_PATH_MAX_LENGTH);
     107           16 :         if (ret != TRACE_SUCCESS) {
     108            3 :             ADIAG_ERR("get socket path failed, ret=%d, pid=%d, devId=%u.", ret, pid, devId);
     109            3 :             break;
     110              :         }
     111              : 
     112           13 :         ret = strcpy_s(addr.sun_path, sizeof(addr.sun_path), socketPath);
     113           13 :         if (ret != EOK) {
     114            0 :             ADIAG_ERR("strcpy failed, ret=%d, pid=%d, devId=%u.", ret, pid, devId);
     115            0 :             break;
     116              :         }
     117              : 
     118           13 :         ret = TraceConnect(sockFd, (struct sockaddr*)&addr, sizeof(addr));
     119           13 :         if (ret != TRACE_SUCCESS) {
     120            3 :             ADIAG_ERR("connect to trace server failed, path %s, ret=%d, pid=%d.", addr.sun_path, ret, pid);
     121            3 :             break;
     122              :         }
     123           10 :         ADIAG_INF("create socket succeed, socket path: %s, fd %d.", addr.sun_path, sockFd);
     124           10 :         return sockFd;
     125              :     } while (0);
     126              : 
     127            7 :     ret = TraceCloseSocket(sockFd);
     128            7 :     if (ret != TRACE_SUCCESS) {
     129            2 :         ADIAG_ERR("close socket failed, strerr=%s, pid=%d.", strerror(AdiagGetErrorCode()), pid);
     130              :     }
     131            7 :     return TRACE_FAILURE;
     132              : }
     133              : 
     134           14 : void UtraceCloseSocket(void)
     135              : {
     136           14 :     int32_t fd = -1;
     137           14 :     (void)AdiagLockGet(&g_clientSockLock);
     138           14 :     if (g_clientSockFd >= 0) {
     139            8 :         fd = g_clientSockFd;
     140            8 :         g_clientSockFd = -1;
     141              :     }
     142           14 :     (void)AdiagLockRelease(&g_clientSockLock);
     143           14 :     if (fd >= 0) {
     144            8 :         (void)TraceCloseSocket(fd);
     145              :     }
     146           14 : }
     147              : 
     148           22 : TraStatus UtraceWriteSocket(uint32_t devId, const char* buffer, uint32_t len)
     149              : {
     150           22 :     if ((buffer == NULL) || (len == 0U)) {
     151            2 :         return TRACE_FAILURE;
     152              :     }
     153              : 
     154           20 :     int32_t fd = -1;
     155           20 :     (void)AdiagLockGet(&g_clientSockLock);
     156           20 :     if (g_clientSockFd < 0) {
     157           10 :         fd = UtraceCreateSocket(devId);
     158           10 :         if (fd == TRACE_FAILURE) {
     159            3 :             (void)AdiagLockRelease(&g_clientSockLock);
     160            3 :             return TRACE_FAILURE;
     161              :         }
     162            7 :         g_clientSockFd = fd;
     163              :     }
     164           17 :     fd = g_clientSockFd;
     165           17 :     TraStatus ret = TraceRecorderWrite(fd, buffer, len);
     166           17 :     if (ret != TRACE_SUCCESS) {
     167            2 :         g_clientSockFd = -1;
     168              :     }
     169           17 :     (void)AdiagLockRelease(&g_clientSockLock);
     170           17 :     if ((ret != TRACE_SUCCESS) && (fd >= 0)) {
     171            2 :         (void)TraceCloseSocket(fd);
     172              :     }
     173           17 :     return ret;
     174              : }
        

Generated by: LCOV version 2.0-1