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