• 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 "init_param.h"
26 #include "parameter.h"
27 #include "securec.h"
28 
StartProcess(const char * name,const char * extArgv[],int extArgc)29 static int StartProcess(const char *name, const char *extArgv[], int extArgc)
30 {
31     BEGET_ERROR_CHECK(name != NULL, return -1, "Service name is null.");
32     int extraArg = 0;
33     if ((extArgv != NULL) && (extArgc > 0)) {
34         BEGET_LOGI("Start service by extra args");
35         extraArg = 1;
36     }
37     int ret = 0;
38     if (extraArg == 1) {
39         unsigned int len = 0;
40         for (int i = 0; i < extArgc; i++) {
41             len += strlen(extArgv[i]);
42         }
43         len += strlen(name) + extArgc + 1;
44         char *nameValue = (char *)calloc(len, sizeof(char));
45         BEGET_ERROR_CHECK(nameValue != NULL, return -1, "Failed calloc err=%d", errno);
46 
47         ret = strncat_s(nameValue, len, name, strlen(name));
48         if (ret != 0) {
49             free(nameValue);
50             BEGET_LOGE("Failed to cat name");
51             return -1;
52         }
53         for (int j = 0; j < extArgc; j++) {
54             ret = strncat_s(nameValue, len, "|", 1);
55             if (ret == 0) {
56                 ret = strncat_s(nameValue, len, extArgv[j], strlen(extArgv[j]));
57             }
58             if (ret != 0) {
59                 free(nameValue);
60                 BEGET_LOGE("Failed to cat name");
61                 return -1;
62             }
63         }
64         ret = SystemSetParameter("ohos.ctl.start", nameValue);
65         free(nameValue);
66     } else {
67         ret = SystemSetParameter("ohos.ctl.start", name);
68     }
69     return ret;
70 }
71 
StopProcess(const char * serviceName)72 static int StopProcess(const char *serviceName)
73 {
74     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
75     return SystemSetParameter("ohos.ctl.stop", serviceName);
76 }
77 
TermProcess(const char * serviceName)78 static int TermProcess(const char *serviceName)
79 {
80     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
81     return SystemSetParameter("ohos.ctl.term", serviceName);
82 }
83 
GetCurrentServiceStatus(const char * serviceName,ServiceStatus * status)84 static int GetCurrentServiceStatus(const char *serviceName, ServiceStatus *status)
85 {
86     char paramName[PARAM_NAME_LEN_MAX] = {0};
87     if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1,
88         "%s.%s", STARTUP_SERVICE_CTL, serviceName) == -1) {
89         BEGET_LOGE("Failed snprintf_s err=%d", errno);
90         return -1;
91     }
92     uint32_t value = GetUintParameter(paramName, SERVICE_IDLE);
93     *status = (ServiceStatus)value;
94     return 0;
95 }
96 
RestartProcess(const char * serviceName,const char * extArgv[],int extArgc)97 static int RestartProcess(const char *serviceName, const char *extArgv[], int extArgc)
98 {
99     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
100     ServiceStatus status = SERVICE_IDLE;
101     if (GetCurrentServiceStatus(serviceName, &status) != 0) {
102         BEGET_LOGE("Get service status failed.\n");
103         return -1;
104     }
105     BEGET_LOGE("Process service %s status: %d ", serviceName, status);
106     if (status == SERVICE_STARTED || status == SERVICE_READY) {
107         if (StopProcess(serviceName) != 0) {
108             BEGET_LOGE("Stop service %s failed", serviceName);
109             return -1;
110         }
111         if (ServiceWaitForStatus(serviceName, SERVICE_STOPPED, DEFAULT_PARAM_WAIT_TIMEOUT) != 0) {
112             BEGET_LOGE("Failed wait service %s stopped", serviceName);
113             return -1;
114         }
115         if (StartProcess(serviceName, extArgv, extArgc) != 0) {
116             BEGET_LOGE("Start service %s failed", serviceName);
117             return -1;
118         }
119     } else if (status != SERVICE_STARTING) {
120         if (StartProcess(serviceName, extArgv, extArgc) != 0) {
121             BEGET_LOGE("Start service %s failed", serviceName);
122             return -1;
123         }
124     }
125     return 0;
126 }
127 
ServiceControlWithExtra(const char * serviceName,int action,const char * extArgv[],int extArgc)128 int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc)
129 {
130     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
131     int ret = 0;
132     switch (action) {
133         case START:
134             ret = StartProcess(serviceName, extArgv, extArgc);
135             break;
136         case STOP:
137             ret = StopProcess(serviceName);
138             break;
139         case RESTART:
140             ret = RestartProcess(serviceName, extArgv, extArgc);
141             break;
142         case TERM:
143             ret = TermProcess(serviceName);
144             break;
145         default:
146             BEGET_LOGE("Set service %s action %d error", serviceName, action);
147             ret = -1;
148             break;
149     }
150     return ret;
151 }
152 
ServiceControl(const char * serviceName,int action)153 int ServiceControl(const char *serviceName, int action)
154 {
155     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
156     int ret = ServiceControlWithExtra(serviceName, action, NULL, 0);
157     return ret;
158 }
159 
GetProcessInfo(const char * serviceName,char * nameBuffer,char * valueBuffer,ServiceStatus status)160 static int GetProcessInfo(const char *serviceName, char *nameBuffer, char *valueBuffer, ServiceStatus status)
161 {
162     if (snprintf_s(nameBuffer, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
163         STARTUP_SERVICE_CTL, serviceName) == -1) {
164         BEGET_LOGE("Failed snprintf_s err=%d", errno);
165         return -1;
166     }
167     if (snprintf_s(valueBuffer, MAX_INT_LEN, MAX_INT_LEN - 1, "%d", (int)status) == -1) {
168         BEGET_LOGE("Failed snprintf_s err=%d", errno);
169         return -1;
170     }
171     return 0;
172 }
173 
ServiceWaitForStatus(const char * serviceName,ServiceStatus status,int waitTimeout)174 int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout)
175 {
176     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
177     BEGET_ERROR_CHECK(waitTimeout >= 0, return -1, "Invalid timeout.");
178     char paramName[PARAM_NAME_LEN_MAX] = {0};
179     char value[MAX_INT_LEN] = {0};
180     int ret = GetProcessInfo(serviceName, paramName, value, status);
181     BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get param info.");
182     return (SystemWaitParameter(paramName, value, waitTimeout) != 0) ? -1 : 0;
183 }
184 
ServiceSetReady(const char * serviceName)185 int ServiceSetReady(const char *serviceName)
186 {
187     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
188     char paramName[PARAM_NAME_LEN_MAX] = {0};
189     char value[MAX_INT_LEN] = {0};
190     int ret = GetProcessInfo(serviceName, paramName, value, SERVICE_READY);
191     BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get param info.");
192     return SystemSetParameter(paramName, value);
193 }
194 
StartServiceByTimer(const char * serviceName,uint64_t timeout)195 int StartServiceByTimer(const char *serviceName, uint64_t timeout)
196 {
197     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
198     if (timeout == 0) {
199         // start service immediately.
200         return ServiceControl(serviceName, START);
201     }
202     // restrict timeout value, not too long.
203     char value[PARAM_VALUE_LEN_MAX] = {};
204     if (snprintf_s(value, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s|%lld", serviceName, timeout) == -1) {
205         BEGET_LOGE("Failed to build parameter value");
206         return -1;
207     }
208     return SystemSetParameter("ohos.servicectrl.timer_start", value);
209 }
210 
StopServiceTimer(const char * serviceName)211 int StopServiceTimer(const char *serviceName)
212 {
213     BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");
214     return SystemSetParameter("ohos.servicectrl.timer_stop", serviceName);
215 }
216