• 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 <errno.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 
21 #include "control_fd.h"
22 #include "init_service.h"
23 #include "init_service_manager.h"
24 #include "init_modulemgr.h"
25 #include "init_utils.h"
26 #include "init_log.h"
27 #include "init_group_manager.h"
28 #include "init_param.h"
29 #include "hookmgr.h"
30 #include "bootstage.h"
31 
DumpServiceArgs(const char * info,const ServiceArgs * args)32 static void DumpServiceArgs(const char *info, const ServiceArgs *args)
33 {
34     printf("\tservice %s count %d \n", info, args->count);
35     for (int j = 0; j < args->count; j++) {
36         if (args->argv[j] != NULL) {
37             printf("\t\tinfo [%d] %s \n", j, args->argv[j]);
38         }
39     }
40 }
41 
DumpServiceJobs(const Service * service)42 static void DumpServiceJobs(const Service *service)
43 {
44     printf("\tservice job info \n");
45     if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) {
46         printf("\t\tservice boot job %s \n", service->serviceJobs.jobsName[JOB_ON_BOOT]);
47     }
48     if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
49         printf("\t\tservice start job %s \n", service->serviceJobs.jobsName[JOB_ON_START]);
50     }
51     if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
52         printf("\t\tservice stop job %s \n", service->serviceJobs.jobsName[JOB_ON_STOP]);
53     }
54     if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
55         printf("\t\tservice restart job %s \n", service->serviceJobs.jobsName[JOB_ON_RESTART]);
56     }
57 }
58 
DumpServiceSocket(const Service * service)59 static void DumpServiceSocket(const Service *service)
60 {
61     printf("\tservice socket info \n");
62     ServiceSocket *sockopt = service->socketCfg;
63     while (sockopt != NULL) {
64         printf("\t\tsocket fd: %d \n", sockopt->sockFd);
65         printf("\t\tsocket name: %s \n", sockopt->name);
66         printf("\t\tsocket type: %u \n", sockopt->type);
67         printf("\t\tsocket uid: %u \n", sockopt->uid);
68         printf("\t\tsocket gid: %u \n", sockopt->gid);
69         sockopt = sockopt->next;
70     }
71 }
72 
DumpServiceHookExecute(const char * name,const char * info)73 void DumpServiceHookExecute(const char *name, const char *info)
74 {
75     SERVICE_INFO_CTX context;
76     context.serviceName = name;
77     context.reserved = info;
78     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&context), NULL);
79 }
80 
DumpOneService(const Service * service)81 static void DumpOneService(const Service *service)
82 {
83     static const struct InitErrMap initErrMaps[] = {
84         {INIT_OK, ""},
85 #define XX(code, info) {INIT_ ## code, info},
86         INIT_ERRNO_MAP(XX)
87 #undef XX
88         {INIT_OK, ""}
89     };
90 
91     const InitArgInfo startModeMap[] = {
92         {"condition", START_MODE_CONDITION},
93         {"boot", START_MODE_BOOT},
94         {"normal", START_MODE_NORMAL}
95     };
96 
97     const static char *serviceStatusMap[] = {
98         "created", "starting", "running", "ready",
99         "stopping", "stopped", "suspended", "freezed", "disabled", "critical"
100     };
101 
102     printf("\tservice name: [%s] \n", service->name);
103     printf("\tservice pid: [%d] \n", service->pid);
104     int tmpCount = sizeof(initErrMaps) / sizeof(initErrMaps[0]);
105     if (service->lastErrno < tmpCount) {
106         printf("\tservice last error: %s(%d) \n", initErrMaps[service->lastErrno].info, service->lastErrno);
107     } else {
108         printf("\tservice last error: %d \n", service->lastErrno);
109     }
110     printf("\tservice context : [%s] \n", (service->context.type == INIT_CONTEXT_CHIPSET) ? "chipset" : "system");
111     printf("\tservice crashCnt: [%d] \n", service->crashCnt);
112     printf("\tservice attribute: [%u] \n", service->attribute);
113     printf("\tservice importance: [%d] \n", service->importance);
114     printf("\tservice startMode: [%s] \n", startModeMap[service->startMode].name);
115     printf("\tservice status: [%s] \n", serviceStatusMap[service->status]);
116     printf("\tservice perms uID [%u] \n", service->servPerm.uID);
117     DumpServiceArgs("path arg", &service->pathArgs);
118     DumpServiceArgs("writepid file", &service->writePidArgs);
119     DumpServiceJobs(service);
120     DumpServiceSocket(service);
121 
122     printf("\tservice perms groupId %d \n", service->servPerm.gIDCnt);
123     for (int i = 0; i < service->servPerm.gIDCnt; i++) {
124         printf("\t\tservice perms groupId %u \n", service->servPerm.gIDArray[i]);
125     }
126     printf("\tservice perms capability %u \n", service->servPerm.capsCnt);
127     for (int i = 0; i < (int)service->servPerm.capsCnt; i++) {
128         printf("\t\tservice perms capability %u \n", service->servPerm.caps[i]);
129     }
130 
131     DumpServiceHookExecute(service->name, NULL);
132 }
133 
PrintBootEventHead(const char * cmd)134 static void PrintBootEventHead(const char *cmd)
135 {
136     if (strcmp(cmd, "bootevent") == 0) {
137         printf("\t%-20.20s\t%-50s\t%-20.20s\t%-20.20s\n",
138             "service-name", "bootevent-name", "fork", "ready");
139     }
140     return;
141 }
142 
DumpAllExtData(const char * cmd)143 static void DumpAllExtData(const char *cmd)
144 {
145     PrintBootEventHead(cmd);
146     InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
147     while (node != NULL) {
148         if (node->data.service == NULL) {
149             node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
150             continue;
151         }
152         DumpServiceHookExecute(node->name, cmd);
153         node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
154     }
155 }
156 
DumpAllServices(void)157 static void DumpAllServices(void)
158 {
159     printf("Ready to dump all services: \n");
160     InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
161     while (node != NULL) {
162         if (node->data.service == NULL) {
163             node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
164             continue;
165         }
166         Service *service = node->data.service;
167         DumpOneService(service);
168         node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
169     }
170     printf("Dump all services finished \n");
171 }
172 
ProcessSandboxControlFd(uint16_t type,const char * serviceCmd)173 static void ProcessSandboxControlFd(uint16_t type, const char *serviceCmd)
174 {
175     if ((type != ACTION_SANDBOX) || (serviceCmd == NULL)) {
176         INIT_LOGE("Invalid parameter");
177         return;
178     }
179     Service *service  = GetServiceByName(serviceCmd);
180     if (service == NULL) {
181         INIT_LOGE("Failed get service %s", serviceCmd);
182         return;
183     }
184     EnterServiceSandbox(service);
185     return;
186 }
187 
ProcessDumpServiceControlFd(uint16_t type,const char * serviceCmd)188 static void ProcessDumpServiceControlFd(uint16_t type, const char *serviceCmd)
189 {
190     if ((type != ACTION_DUMP) || (serviceCmd == NULL)) {
191         return;
192     }
193     char *cmd = strrchr(serviceCmd, '#');
194     if (cmd != NULL) {
195         cmd[0] = '\0';
196         cmd++;
197     }
198 
199     if (strcmp(serviceCmd, "all") == 0) {
200         if (cmd != NULL) {
201             DumpAllExtData(cmd);
202         } else {
203             DumpAllServices();
204         }
205         return;
206     }
207     if (strcmp(serviceCmd, "parameter_service") == 0) {
208         if (cmd != NULL && strcmp(cmd, "trigger") == 0) {
209             SystemDumpTriggers(0, printf);
210         } else {
211             SystemDumpParameters(0, 0, printf);
212         }
213         return;
214     }
215     Service *service  = GetServiceByName(serviceCmd);
216     if (service != NULL) {
217         if (cmd != NULL) {
218             PrintBootEventHead(cmd);
219             DumpServiceHookExecute(serviceCmd, cmd);
220         } else {
221             DumpOneService(service);
222         }
223     }
224     return;
225 }
226 
ProcessModuleMgrControlFd(uint16_t type,const char * serviceCmd)227 static void ProcessModuleMgrControlFd(uint16_t type, const char *serviceCmd)
228 {
229     if ((type != ACTION_MODULEMGR) || (serviceCmd == NULL)) {
230         return;
231     }
232     INIT_LOGE("ProcessModuleMgrControlFd argc [%s] \n", serviceCmd);
233     if (strcmp(serviceCmd, "list") == 0) {
234         InitModuleMgrDump();
235         return;
236     }
237 }
238 
ProcessControlFd(uint16_t type,const char * serviceCmd,const void * context)239 void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context)
240 {
241     if ((type >= ACTION_MAX) || (serviceCmd == NULL)) {
242         return;
243     }
244     switch (type) {
245         case ACTION_SANDBOX :
246             ProcessSandboxControlFd(type, serviceCmd);
247             break;
248         case ACTION_DUMP :
249             ProcessDumpServiceControlFd(type, serviceCmd);
250             break;
251         case ACTION_MODULEMGR :
252             ProcessModuleMgrControlFd(type, serviceCmd);
253             break;
254         default :
255             INIT_LOGW("Unknown control fd type.");
256             break;
257     }
258 }
259 
InitControlFd(void)260 void InitControlFd(void)
261 {
262     CmdServiceInit(INIT_CONTROL_FD_SOCKET_PATH, ProcessControlFd, LE_GetDefaultLoop());
263     return;
264 }
265