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