• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "log_ioctl.h"
17 
18 namespace OHOS {
19 namespace HiviewDFX {
20 using namespace std;
21 
GetSocketName(IoctlCmd cmd)22 static string GetSocketName(IoctlCmd cmd)
23 {
24     if (cmd == IoctlCmd::OUTPUT_RQST) {
25         return OUTPUT_SOCKET_NAME;
26     } else {
27         return CONTROL_SOCKET_NAME;
28     }
29 }
30 
LogIoctl(IoctlCmd rqst,IoctlCmd rsp)31 LogIoctl::LogIoctl(IoctlCmd rqst, IoctlCmd rsp) : socket(GetSocketName(rqst), 0)
32 {
33     socketInit = socket.Init();
34     if (socketInit != SeqPacketSocketResult::CREATE_AND_CONNECTED) {
35         PrintErrorno(errno);
36     }
37     rqstCmd = rqst;
38     rspCmd = rsp;
39 }
40 
SendMsgHeader(IoctlCmd cmd,size_t len)41 int LogIoctl::SendMsgHeader(IoctlCmd cmd, size_t len)
42 {
43     MsgHeader header = {MSG_VER, static_cast<uint8_t>(cmd), 0, static_cast<uint16_t>(len)};
44     if (socketInit != SeqPacketSocketResult::CREATE_AND_CONNECTED) {
45         return ERR_SOCKET_CLIENT_INIT_FAIL;
46     }
47     int ret = socket.WriteAll(reinterpret_cast<char*>(&header), sizeof(MsgHeader));
48     if (ret < 0) {
49         PrintErrorno(errno);
50         return ERR_SOCKET_WRITE_MSG_HEADER_FAIL;
51     }
52     return RET_SUCCESS;
53 }
54 
ReceiveMsgHeaer(MsgHeader & hdr)55 int LogIoctl::ReceiveMsgHeaer(MsgHeader& hdr)
56 {
57     int ret = socket.RecvMsg(reinterpret_cast<char *>(&hdr), sizeof(hdr));
58     if (ret <= 0) {
59         return ERR_SOCKET_RECEIVE_RSP;
60     }
61     return RET_SUCCESS;
62 }
63 
GetRsp(char * rsp,int len)64 int LogIoctl::GetRsp(char* rsp, int len)
65 {
66     int ret = socket.RecvMsg(rsp, len);
67     if (ret <= 0) {
68         return ERR_SOCKET_RECEIVE_RSP;
69     }
70     return RET_SUCCESS;
71 }
72 
ReceiveProcTagStats(StatsQueryRsp & rsp)73 int LogIoctl::ReceiveProcTagStats(StatsQueryRsp &rsp)
74 {
75     int i = 0;
76     for (i = 0; i < rsp.procNum; i++) {
77         ProcStatsRsp &pStats = rsp.pStats[i];
78         int msgSize = pStats.tagNum * sizeof(TagStatsRsp);
79         if (msgSize == 0) {
80             pStats.tStats = nullptr;
81             continue;
82         }
83         char* tmp = new (std::nothrow) char[msgSize];
84         if (tmp == nullptr) {
85             pStats.tStats = nullptr;
86             return RET_FAIL;
87         }
88         if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
89             delete []tmp;
90             tmp = nullptr;
91             return RET_FAIL;
92         }
93         if (GetRsp(tmp, msgSize) != RET_SUCCESS) {
94             pStats.tStats = nullptr;
95             delete []tmp;
96             tmp = nullptr;
97             return RET_FAIL;
98         }
99         pStats.tStats = reinterpret_cast<TagStatsRsp*>(tmp);
100     }
101     return RET_SUCCESS;
102 }
103 
ReceiveProcLogTypeStats(StatsQueryRsp & rsp)104 int LogIoctl::ReceiveProcLogTypeStats(StatsQueryRsp &rsp)
105 {
106     int i = 0;
107     for (i = 0; i < rsp.procNum; i++) {
108         ProcStatsRsp &pStats = rsp.pStats[i];
109         int msgSize = pStats.typeNum * sizeof(LogTypeStatsRsp);
110         if (msgSize == 0) {
111             continue;
112         }
113         char* tmp = new (std::nothrow) char[msgSize];
114         if (tmp == nullptr) {
115             pStats.lStats = nullptr;
116             return RET_FAIL;
117         }
118         if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
119             delete []tmp;
120             tmp = nullptr;
121             return RET_FAIL;
122         }
123         if (GetRsp(tmp, msgSize) != RET_SUCCESS) {
124             pStats.lStats = nullptr;
125             delete []tmp;
126             tmp = nullptr;
127             return RET_FAIL;
128         }
129         pStats.lStats = reinterpret_cast<LogTypeStatsRsp*>(tmp);
130     }
131     return RET_SUCCESS;
132 }
133 
ReceiveProcStats(StatsQueryRsp & rsp)134 int LogIoctl::ReceiveProcStats(StatsQueryRsp &rsp)
135 {
136     if (rsp.procNum == 0) {
137         return RET_FAIL;
138     }
139     int msgSize = rsp.procNum * sizeof(ProcStatsRsp);
140     if (msgSize == 0) {
141         return RET_SUCCESS;
142     }
143     char* tmp = new (std::nothrow) char[msgSize];
144     if (tmp == nullptr) {
145         rsp.pStats = nullptr;
146         return RET_FAIL;
147     }
148     if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
149         delete []tmp;
150         tmp = nullptr;
151         return RET_FAIL;
152     }
153     if (GetRsp(tmp, msgSize) != RET_SUCCESS) {
154         rsp.pStats = nullptr;
155         delete []tmp;
156         tmp = nullptr;
157         return RET_FAIL;
158     }
159     rsp.pStats = reinterpret_cast<ProcStatsRsp*>(tmp);
160     return RET_SUCCESS;
161 }
162 
ReceiveDomainTagStats(StatsQueryRsp & rsp)163 int LogIoctl::ReceiveDomainTagStats(StatsQueryRsp &rsp)
164 {
165     int i = 0;
166     for (i = 0; i < rsp.typeNum; i++) {
167         LogTypeDomainStatsRsp &ldStats = rsp.ldStats[i];
168         int j = 0;
169         for (j = 0; j < ldStats.domainNum; j++) {
170             DomainStatsRsp &dStats = ldStats.dStats[j];
171             int msgSize = dStats.tagNum * sizeof(TagStatsRsp);
172             if (msgSize == 0) {
173                 dStats.tStats = nullptr;
174                 continue;
175             }
176             char* tmp = new (std::nothrow) char[msgSize];
177             if (tmp == nullptr) {
178                 dStats.tStats = nullptr;
179                 return RET_FAIL;
180             }
181             if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
182                 delete []tmp;
183                 tmp = nullptr;
184                 return RET_FAIL;
185             }
186             if (GetRsp(tmp, msgSize) != RET_SUCCESS) {
187                 dStats.tStats = nullptr;
188                 delete []tmp;
189                 tmp = nullptr;
190                 return RET_FAIL;
191             }
192             dStats.tStats = reinterpret_cast<TagStatsRsp*>(tmp);
193         }
194     }
195     return RET_SUCCESS;
196 }
197 
ReceiveDomainStats(StatsQueryRsp & rsp)198 int LogIoctl::ReceiveDomainStats(StatsQueryRsp &rsp)
199 {
200     int i = 0;
201     for (i = 0; i < rsp.typeNum; i++) {
202         LogTypeDomainStatsRsp &ldStats = rsp.ldStats[i];
203         int msgSize = ldStats.domainNum * sizeof(DomainStatsRsp);
204         if (msgSize == 0) {
205             continue;
206         }
207         char* tmp = new (std::nothrow) char[msgSize];
208         if (tmp == nullptr) {
209             ldStats.dStats = nullptr;
210             return RET_FAIL;
211         }
212         if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
213             delete []tmp;
214             tmp = nullptr;
215             return RET_FAIL;
216         }
217         if (GetRsp(tmp, msgSize) != RET_SUCCESS) {
218             ldStats.dStats = nullptr;
219             delete []tmp;
220             tmp = nullptr;
221             return RET_FAIL;
222         }
223         ldStats.dStats = reinterpret_cast<DomainStatsRsp*>(tmp);
224     }
225     return RET_SUCCESS;
226 }
227 
ReceiveLogTypeDomainStats(StatsQueryRsp & rsp)228 int LogIoctl::ReceiveLogTypeDomainStats(StatsQueryRsp &rsp)
229 {
230     if (rsp.typeNum == 0) {
231         return RET_FAIL;
232     }
233     int msgSize = rsp.typeNum * sizeof(LogTypeDomainStatsRsp);
234     if (msgSize == 0) {
235         return RET_SUCCESS;
236     }
237     char* tmp = new (std::nothrow) char[msgSize];
238     if (tmp == nullptr) {
239         rsp.ldStats = nullptr;
240         return RET_FAIL;
241     }
242     if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
243         delete []tmp;
244         tmp = nullptr;
245         return RET_FAIL;
246     }
247     if (GetRsp(tmp, msgSize) != RET_SUCCESS) {
248         rsp.ldStats = nullptr;
249         delete []tmp;
250         tmp = nullptr;
251         return RET_FAIL;
252     }
253     rsp.ldStats = reinterpret_cast<LogTypeDomainStatsRsp*>(tmp);
254     return RET_SUCCESS;
255 }
256 
DeleteLogStatsInfo(StatsQueryRsp & rsp)257 void LogIoctl::DeleteLogStatsInfo(StatsQueryRsp &rsp)
258 {
259     if (rsp.ldStats == nullptr) {
260         return;
261     }
262     int i = 0;
263     for (i = 0; i < rsp.typeNum; i++) {
264         LogTypeDomainStatsRsp &ldStats = rsp.ldStats[i];
265         if (ldStats.dStats == nullptr) {
266             break;
267         }
268         int j = 0;
269         for (j = 0; j < ldStats.domainNum; j++) {
270             DomainStatsRsp &dStats = ldStats.dStats[j];
271             if (dStats.tStats == nullptr) {
272                 break;
273             }
274             delete []dStats.tStats;
275             dStats.tStats = nullptr;
276         }
277         delete []ldStats.dStats;
278         ldStats.dStats = nullptr;
279     }
280     delete []rsp.ldStats;
281     rsp.ldStats = nullptr;
282 
283     if (rsp.pStats == nullptr) {
284         return;
285     }
286     for (i = 0; i < rsp.procNum; i++) {
287         ProcStatsRsp &pStats = rsp.pStats[i];
288         if (pStats.lStats == nullptr) {
289             return;
290         }
291         delete []pStats.lStats;
292         pStats.lStats = nullptr;
293         if (pStats.tStats == nullptr) {
294             return;
295         }
296         delete []pStats.tStats;
297         pStats.tStats = nullptr;
298     }
299 }
300 
RequestOutput(const OutputRqst & rqst,std::function<int (const OutputRsp & rsp)> handle)301 int LogIoctl::RequestOutput(const OutputRqst& rqst, std::function<int(const OutputRsp& rsp)> handle)
302 {
303     // 0. Send reqeust message and process the response header
304     int ret = RequestMsgHead<OutputRqst, OutputRsp>(rqst);
305     if (ret != RET_SUCCESS) {
306         return ret;
307     }
308     // 1. process the response message
309     return ReceiveAndProcessOutputRsp(handle);
310 }
311 
ReceiveAndProcessOutputRsp(std::function<int (const OutputRsp & rsp)> handle)312 int LogIoctl::ReceiveAndProcessOutputRsp(std::function<int(const OutputRsp& rsp)> handle)
313 {
314     vector<char> buffer(DEFAULT_RECV_BUF_LEN, 0);
315     OutputRsp *rsp = reinterpret_cast<OutputRsp *>(buffer.data());
316     while (true) {
317         int ret = GetRsp(reinterpret_cast<char*>(rsp), DEFAULT_RECV_BUF_LEN);
318         if (ret != RET_SUCCESS) {
319             return ret;
320         }
321         ret = handle(*rsp);
322         if (likely(ret == static_cast<int>(SUCCESS_CONTINUE))) {
323             continue;
324         }
325         return ret;
326     }
327 }
328 
RequestStatsQuery(const StatsQueryRqst & rqst,std::function<int (const StatsQueryRsp & rsp)> handle)329 int LogIoctl::RequestStatsQuery(const StatsQueryRqst& rqst, std::function<int(const StatsQueryRsp& rsp)> handle)
330 {
331     // 0. Send reqeust message and process the response header
332     int ret = RequestMsgHead<StatsQueryRqst, StatsQueryRsp>(rqst);
333     if (ret != RET_SUCCESS) {
334         return ret;
335     }
336     // 1. process the response message
337     return ReceiveAndProcessStatsQueryRsp(handle);
338 }
339 
ReceiveAndProcessStatsQueryRsp(std::function<int (const StatsQueryRsp & rsp)> handle)340 int LogIoctl::ReceiveAndProcessStatsQueryRsp(std::function<int(const StatsQueryRsp& rsp)> handle)
341 {
342     int ret;
343     StatsQueryRsp rsp = { 0 };
344     do {
345         ret = GetRsp(reinterpret_cast<char*>(&rsp), sizeof(rsp));
346         if (RET_SUCCESS != ret) {
347             break;
348         }
349         rsp.ldStats = nullptr;
350         rsp.pStats = nullptr;
351         ret = ReceiveLogTypeDomainStats(rsp);
352         if (RET_SUCCESS != ret) {
353             break;
354         }
355         ret = ReceiveDomainStats(rsp);
356         if (RET_SUCCESS != ret) {
357             break;
358         }
359         ret = ReceiveDomainTagStats(rsp);
360         if (RET_SUCCESS != ret) {
361             break;
362         }
363         ret = ReceiveProcStats(rsp);
364         if (RET_SUCCESS != ret) {
365             break;
366         }
367         ret = ReceiveProcLogTypeStats(rsp);
368         if (RET_SUCCESS != ret) {
369             break;
370         }
371         ret = ReceiveProcTagStats(rsp);
372         if (RET_SUCCESS != ret) {
373             break;
374         }
375     } while (0);
376     if (ret ==  RET_SUCCESS) {
377         ret = handle(rsp);
378     }
379     DeleteLogStatsInfo(rsp);
380     return ret;
381 }
382 } // namespace HiviewDFX
383 } // namespace OHOS