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 "adx_dump_soc_helper.h"
12 : #include "adx_dump_record.h"
13 : #include "adx_datadump_callback.h"
14 : #include "memory_utils.h"
15 : #include "common_utils.h"
16 : #include "log/adx_log.h"
17 : #include "string_utils.h"
18 : #include "adx_datadump_server_soc.h"
19 : namespace Adx {
20 2 : AdxDumpSocHelper::AdxDumpSocHelper()
21 : {
22 2 : }
23 :
24 2 : AdxDumpSocHelper::~AdxDumpSocHelper()
25 : {
26 2 : UnInit();
27 2 : }
28 :
29 : /**
30 : * @brief parse connect info
31 : * @param [in] connectInfo: string of connect info
32 : *
33 : * @return
34 : * IDE_DAEMON_NONE_ERROR: parse connect info success
35 : * IDE_DAEMON_INVALID_PARAM_ERROR: parse connect info failed
36 : */
37 6 : IdeErrorT AdxDumpSocHelper::ParseConnectInfo(const std::string &connectInfo) const
38 : {
39 6 : std::string hostId;
40 6 : std::string hostPid;
41 6 : bool ret = StringUtils::ParseConnectInfo(connectInfo, hostId, hostPid);
42 6 : IDE_CTRL_VALUE_FAILED(ret == true, return IDE_DAEMON_INVALID_PARAM_ERROR, "ParseConnectInfo failed");
43 2 : return IDE_DAEMON_NONE_ERROR;
44 6 : }
45 :
46 2 : bool AdxDumpSocHelper::Init(const std::string &hostPid)
47 : {
48 4 : if (!init_.test_and_set()) {
49 2 : if (AdxSocDataDumpInit(hostPid) == IDE_DAEMON_ERROR) {
50 1 : init_.clear();
51 1 : return false;
52 : }
53 : }
54 1 : return true;
55 : }
56 :
57 2 : void AdxDumpSocHelper::UnInit()
58 : {
59 4 : if (init_.test_and_set()) {
60 1 : AdxSocDataDumpUnInit();
61 1 : init_.clear();
62 : }
63 2 : }
64 :
65 2 : IdeErrorT AdxDumpSocHelper::HandShake(const std::string &info, IDE_SESSION &session) const
66 : {
67 2 : IdeErrorT err = ParseConnectInfo(info);
68 2 : if (err == IDE_DAEMON_NONE_ERROR) {
69 1 : session = DEFAULT_SOC_SESSION;
70 : }
71 2 : IDE_LOGD("soc handshake success");
72 2 : return err;
73 : }
74 :
75 8 : IdeErrorT AdxDumpSocHelper::DataProcess(const IDE_SESSION &session, const IdeDumpChunk &dumpChunk) const
76 : {
77 : UNUSED(session);
78 8 : uint32_t dataLen = 0;
79 8 : IDE_CTRL_VALUE_FAILED(dumpChunk.fileName != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "fileName is null");
80 7 : IDE_CTRL_VALUE_FAILED(dumpChunk.dataBuf != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "dataBuf is null");
81 6 : IDE_CTRL_VALUE_FAILED(dumpChunk.bufLen > 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "bufLen is 0");
82 5 : IDE_RETURN_IF_CHECK_ASSIGN_32U_ADD(sizeof(DumpChunk),
83 : dumpChunk.bufLen, dataLen, return IDE_DAEMON_INTERGER_REVERSED_ERROR);
84 4 : DumpChunk* data = reinterpret_cast<DumpChunk*>(IdeXmalloc(dataLen));
85 4 : IDE_CTRL_VALUE_FAILED(data != nullptr, return IDE_DAEMON_MALLOC_ERROR, "malloc failed");
86 3 : std::unique_ptr<DumpChunk, decltype(&IdeXfree)> dataPtr(data, IdeXfree);
87 3 : IDE_CTRL_VALUE_FAILED(strnlen(dumpChunk.fileName, MAX_FILE_PATH_LENGTH) < MAX_FILE_PATH_LENGTH,
88 : return IDE_DAEMON_INVALID_PATH_ERROR,
89 : "fileName is too long or not null-terminated, max=%u", MAX_FILE_PATH_LENGTH);
90 2 : int32_t err = strcpy_s(data->fileName, MAX_FILE_PATH_LENGTH, dumpChunk.fileName);
91 2 : IDE_CTRL_VALUE_FAILED(err == EOK, return IDE_DAEMON_INVALID_PATH_ERROR,
92 : "copy file name failed, err=%d", err);
93 2 : data->bufLen = dumpChunk.bufLen;
94 2 : data->flag = dumpChunk.flag;
95 2 : data->isLastChunk = dumpChunk.isLastChunk;
96 2 : data->offset = dumpChunk.offset;
97 2 : IDE_LOGI("dataLen: %u, bufLen: %u, flag: %d, isLastChunk: %u, offset: %ld, fileName: %s",
98 : dataLen, data->bufLen, data->flag, data->isLastChunk, data->offset, data->fileName);
99 2 : err = memcpy_s(data->dataBuf, data->bufLen, dumpChunk.dataBuf, dumpChunk.bufLen);
100 2 : IDE_CTRL_VALUE_FAILED(err == EOK, return IDE_DAEMON_UNKNOW_ERROR, "memcpy_s data buffer failed");
101 2 : bool ret = AdxDumpRecord::Instance().RecordDumpDataToDisk(*data);
102 2 : IDE_CTRL_VALUE_FAILED(ret, return IDE_DAEMON_WRITE_ERROR, "record dump data to disk failed");
103 1 : IDE_LOGD("dump data process normal");
104 1 : return IDE_DAEMON_NONE_ERROR;
105 3 : }
106 :
107 2 : IdeErrorT AdxDumpSocHelper::Finish(IDE_SESSION &session) const
108 : {
109 2 : session = nullptr;
110 2 : return IDE_DAEMON_NONE_ERROR;
111 : }
112 :
113 : /**
114 : * @brief dump start api,create a HDC session for dump
115 : * @param [in] connectInfo: remote connect info
116 : *
117 : * @return
118 : * not NULL: Handle used by hdc
119 : * NULL: dump start failed
120 : */
121 4 : IDE_SESSION SocDumpStart(const char *connectInfo)
122 : {
123 4 : IDE_LOGI("Soc dump start, connectInfo: %s", connectInfo);
124 4 : std::string connectInfoStr = connectInfo;
125 4 : std::string::size_type idx = connectInfoStr.find_last_of(";");
126 4 : if (idx == std::string::npos) {
127 1 : IDE_LOGE("invalid info str: %s", connectInfoStr.c_str());
128 1 : return nullptr;
129 : }
130 3 : std::string hostPid = connectInfoStr.substr(idx + 1);
131 3 : if (!Adx::AdxDumpSocHelper::Instance().Init(hostPid)) {
132 1 : return nullptr;
133 : }
134 2 : IDE_SESSION session = nullptr;
135 4 : Adx::AdxDumpSocHelper::Instance().HandShake(std::string(connectInfo), session);
136 2 : return session;
137 4 : }
138 :
139 : /**
140 : * @brief dump data to remote server
141 : * @param [in] session: HDC session to dump data
142 : * @param [in] dumpChunk: Dump information
143 : * @return
144 : * IDE_DAEMON_INVALID_PARAM_ERROR: invalid parameter
145 : * IDE_DAEMON_UNKNOW_ERROR: write data failed
146 : * IDE_DAEMON_NONE_ERROR: write data succ
147 : * IDE_DAEMON_WRITE_ERROR: write file failed
148 : * IDE_DAEMON_MALLOC_ERROR: malloc memory failed
149 : * IDE_DAEMON_INVALID_PATH_ERROR: invalid dump path
150 : * IDE_DAEMON_INTERGER_REVERSED_ERROR: integer overflow
151 : */
152 11 : IdeErrorT SocDumpData(const IDE_SESSION session, const IdeDumpChunk *dumpChunk)
153 : {
154 11 : IDE_CTRL_VALUE_FAILED(session != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "session is nullptr");
155 10 : IDE_CTRL_VALUE_FAILED(dumpChunk != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "IdeDumpChunk is nullptr");
156 8 : IDE_LOGD("dump data process entry");
157 8 : IdeErrorT ret = Adx::AdxDumpSocHelper::Instance().DataProcess(session, *dumpChunk);
158 8 : IDE_LOGD("dump data process exit");
159 8 : return ret;
160 : }
161 :
162 : /**
163 : * @brief send dump end msg
164 : * @param [in] session: HDC session to dump data
165 : * @return
166 : * IDE_DAEMON_UNKNOW_ERROR: send dump end msg failed
167 : * IDE_DAEMON_NONE_ERROR: send dump end msg success
168 : */
169 2 : IdeErrorT SocDumpEnd(IDE_SESSION session)
170 : {
171 2 : IDE_CTRL_VALUE_FAILED(session != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "session is nullptr");
172 2 : IDE_LOGI("dump data finish");
173 2 : return Adx::AdxDumpSocHelper::Instance().Finish(session);
174 : }
175 : }
|