• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2021 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 "service_control.h"
17 
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "beget_ext.h"
24 #include "init_utils.h"
25 #include "securec.h"
26 #include "sys_param.h"
27 
StartProcess(const char * name,const char * extArgv[],int extArgc)28 static int StartProcess(const char *name, const char *extArgv[], int extArgc)
29 {
30     if (name == NULL) {
31         BEGET_LOGE("Start dynamic service failed, service name is null.");
32         return -1;
33     }
34     int extraArg = 0;
35     if ((extArgv != NULL) && (extArgc > 0)) {
36         BEGET_LOGI("Start service by extra args");
37         extraArg = 1;
38     }
39     if (extraArg == 1) {
40         unsigned int len = 0;
41         for (int i = 0; i < extArgc; i++) {
42             len += strlen(extArgv[i]);
43         }
44         len += strlen(name) + extArgc + 1;
45         char *nameValue = (char *)calloc(len, sizeof(char));
46         if (nameValue == NULL) {
47             BEGET_LOGE("Failed calloc err=%d", errno);
48             return -1;
49         }
50         if (strncat_s(nameValue, len, name, strlen(name)) != 0) {
51             BEGET_LOGE("Failed strncat_s name err=%d", errno);
52             return -1;
53         }
54         for (int j = 0; j < extArgc; j++) {
55             if (strncat_s(nameValue, len, "|", 1) != 0) {
56                 BEGET_LOGE("Failed strncat_s \"|\"err=%d", errno);
57                 return -1;
58             }
59             if (strncat_s(nameValue, len, extArgv[j], strlen(extArgv[j])) != 0) {
60                 BEGET_LOGE("Failed strncat_s err=%d", errno);
61                 return -1;
62             }
63         }
64         if (SystemSetParameter("ohos.ctl.start", nameValue) != 0) {
65             BEGET_LOGE("Set param for %s failed.\n", nameValue);
66             free(nameValue);
67             return -1;
68         }
69         free(nameValue);
70     } else {
71         if (SystemSetParameter("ohos.ctl.start", name) != 0) {
72             BEGET_LOGE("Set param for %s failed.\n", name);
73             return -1;
74         }
75     }
76     return 0;
77 }
78 
StopProcess(const char * serviceName)79 static int StopProcess(const char *serviceName)
80 {
81     if (serviceName == NULL) {
82         BEGET_LOGE("Stop dynamic service failed, service is null.\n");
83         return -1;
84     }
85     if (SystemSetParameter("ohos.ctl.stop", serviceName) != 0) {
86         BEGET_LOGE("Set param for %s failed.\n", serviceName);
87         return -1;
88     }
89     return 0;
90 }
91 
GetCurrentServiceStatus(const char * serviceName,ServiceStatus * status)92 static int GetCurrentServiceStatus(const char *serviceName, ServiceStatus *status)
93 {
94     char paramName[PARAM_NAME_LEN_MAX] = {0};
95     if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1,
96         "%s.%s", STARTUP_SERVICE_CTL, serviceName) == -1) {
97         BEGET_LOGE("Failed snprintf_s err=%d", errno);
98         return -1;
99     }
100     char paramValue[PARAM_VALUE_LEN_MAX] = {0};
101     unsigned int valueLen = PARAM_VALUE_LEN_MAX;
102     if (SystemGetParameter(paramName, paramValue, &valueLen) != 0) {
103         BEGET_LOGE("Failed get paramName.");
104         return -1;
105     }
106     int size = 0;
107     const InitArgInfo *statusMap = GetServieStatusMap(&size);
108     *status = GetMapValue(paramValue, statusMap, size, SERVICE_IDLE);
109     return 0;
110 }
111 
RestartProcess(const char * serviceName,const char * extArgv[],int extArgc)112 static int RestartProcess(const char *serviceName, const char *extArgv[], int extArgc)
113 {
114     if (serviceName == NULL) {
115         BEGET_LOGE("Restart dynamic service failed, service is null.\n");
116         return -1;
117     }
118     ServiceStatus status = SERVICE_IDLE;
119     if (GetCurrentServiceStatus(serviceName, &status) != 0) {
120         BEGET_LOGE("Get service status failed.\n");
121         return -1;
122     }
123     if (status == SERVICE_STARTED || status == SERVICE_READY) {
124         if (StopProcess(serviceName) != 0) {
125             BEGET_LOGE("Stop service %s failed", serviceName);
126             return -1;
127         }
128         if (ServiceWaitForStatus(serviceName, SERVICE_STOPPED, DEFAULT_PARAM_WAIT_TIMEOUT) != 0) {
129             BEGET_LOGE("Failed wait service %s stopped", serviceName);
130             return -1;
131         }
132         if (StartProcess(serviceName, extArgv, extArgc) != 0) {
133             BEGET_LOGE("Start service %s failed", serviceName);
134             return -1;
135         }
136     } else if (status != SERVICE_STARTING) {
137         if (StartProcess(serviceName, extArgv, extArgc) != 0) {
138             BEGET_LOGE("Start service %s failed", serviceName);
139             return -1;
140         }
141     } else {
142         BEGET_LOGE("Current service status: %d is not support.", status);
143     }
144     return 0;
145 }
146 
ServiceControlWithExtra(const char * serviceName,int action,const char * extArgv[],int extArgc)147 int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc)
148 {
149     if (serviceName == NULL) {
150         BEGET_LOGE("Service wait failed, service is null.\n");
151         return -1;
152     }
153     int ret = 0;
154     switch (action) {
155         case START:
156             ret = StartProcess(serviceName, extArgv, extArgc);
157             break;
158         case STOP:
159             ret = StopProcess(serviceName);
160             break;
161         case RESTART:
162             ret = RestartProcess(serviceName, extArgv, extArgc);
163             break;
164         default:
165             BEGET_LOGE("Set service %s action %d error", serviceName, action);
166             ret = -1;
167             break;
168     }
169     return ret;
170 }
171 
ServiceControl(const char * serviceName,int action)172 int ServiceControl(const char *serviceName, int action)
173 {
174     if (serviceName == NULL) {
175         BEGET_LOGE("Service getctl failed, service is null.");
176         return -1;
177     }
178     int ret = ServiceControlWithExtra(serviceName, action, NULL, 0);
179     return ret;
180 }
181 
ServiceWaitForStatus(const char * serviceName,ServiceStatus status,int waitTimeout)182 int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout)
183 {
184     char *state = NULL;
185     int size = 0;
186     const InitArgInfo *statusMap = GetServieStatusMap(&size);
187     if (((int)status < size) && (statusMap[status].value == (int)status)) {
188         state = statusMap[status].name;
189     }
190     if (serviceName == NULL || state == NULL || waitTimeout <= 0) {
191         BEGET_LOGE("Service wait failed, service name is null or status invalid %d", status);
192         return -1;
193     }
194     char paramName[PARAM_NAME_LEN_MAX] = {0};
195     if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
196         STARTUP_SERVICE_CTL, serviceName) == -1) {
197         BEGET_LOGE("Failed snprintf_s err=%d", errno);
198         return -1;
199     }
200     if (SystemWaitParameter(paramName, state, waitTimeout) != 0) {
201         BEGET_LOGE("Wait param for %s failed.", paramName);
202         return -1;
203     }
204     BEGET_LOGI("Success wait");
205     return 0;
206 }
207 
ServiceSetReady(const char * serviceName)208 int ServiceSetReady(const char *serviceName)
209 {
210     if (serviceName == NULL) {
211         BEGET_LOGE("Service wait failed, service is null.");
212         return -1;
213     }
214     char paramName[PARAM_NAME_LEN_MAX] = {0};
215     if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
216         STARTUP_SERVICE_CTL, serviceName) == -1) {
217         BEGET_LOGE("Failed snprintf_s err=%d", errno);
218         return -1;
219     }
220     if (SystemSetParameter(paramName, "ready") != 0) {
221         BEGET_LOGE("Set param for %s failed.", paramName);
222         return -1;
223     }
224     BEGET_LOGI("Success set %d read", serviceName);
225     return 0;
226 }
227 
StartServiceByTimer(const char * serviceName,uint64_t timeout)228 int StartServiceByTimer(const char *serviceName, uint64_t timeout)
229 {
230     if (serviceName == NULL) {
231         BEGET_LOGE("Request start serivce by timer with invalid service name");
232         return -1;
233     }
234 
235     if (timeout == 0) {
236         // start service immediately.
237         return ServiceControl(serviceName, START);
238     }
239     // restrict timeout value, not too long.
240     char value[PARAM_VALUE_LEN_MAX] = {};
241     if (snprintf_s(value, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s|%lld", serviceName, timeout) == -1) {
242         BEGET_LOGE("Failed to build parameter value");
243         return -1;
244     }
245 
246     if (SystemSetParameter("ohos.servicectrl.timer_start", value) != 0) {
247         BEGET_LOGE("Failed to set parameter \' ohos.servicectrl.timer_start \' with value \' %s \'", value);
248         return -1;
249     }
250     return 0;
251 }
252 
StopServiceTimer(const char * serviceName)253 int StopServiceTimer(const char *serviceName)
254 {
255     if (serviceName == NULL) {
256         BEGET_LOGE("Request stop serivce timer with invalid service name");
257         return -1;
258     }
259 
260     char value[PARAM_VALUE_LEN_MAX] = {};
261     int ret = strncpy_s(value, PARAM_VALUE_LEN_MAX - 1, serviceName, strlen(serviceName));
262     if (ret < 0) {
263         BEGET_LOGE("Failed to copy service name to parameter");
264         return -1;
265     }
266 
267     if (SystemSetParameter("ohos.servicectrl", value) != 0) {
268         BEGET_LOGE("Failed to set parameter \' ohos.servicectrl.timer_stop \' with value \' %s \'", value);
269         return -1;
270     }
271     return 0;
272 }
273