service_control.c 8.7 KB
Newer Older
X
xionglei6 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

X
xionglei6 已提交
16
#include "service_control.h"
X
xionglei6 已提交
17 18 19 20 21 22

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

X
xionglei6 已提交
23
#include "beget_ext.h"
X
xionglei6 已提交
24 25 26 27
#include "init_utils.h"
#include "securec.h"
#include "sys_param.h"

X
xionglei6 已提交
28
static int StartProcess(const char *name, const char *extArgv[], int extArgc)
X
xionglei6 已提交
29 30
{
    if (name == NULL) {
X
xionglei6 已提交
31
        BEGET_LOGE("Start dynamic service failed, service name is null.");
X
xionglei6 已提交
32 33 34 35
        return -1;
    }
    int extraArg = 0;
    if ((extArgv != NULL) && (extArgc > 0)) {
X
xionglei6 已提交
36
        BEGET_LOGI("Start service by extra args");
X
xionglei6 已提交
37 38 39 40 41 42 43 44 45 46
        extraArg = 1;
    }
    if (extraArg == 1) {
        unsigned int len = 0;
        for (int i = 0; i < extArgc; i++) {
            len += strlen(extArgv[i]);
        }
        len += strlen(name) + extArgc + 1;
        char *nameValue = (char *)calloc(len, sizeof(char));
        if (nameValue == NULL) {
X
xionglei6 已提交
47
            BEGET_LOGE("Failed calloc err=%d", errno);
X
xionglei6 已提交
48 49 50
            return -1;
        }
        if (strncat_s(nameValue, len, name, strlen(name)) != 0) {
X
xionglei6 已提交
51
            BEGET_LOGE("Failed strncat_s name err=%d", errno);
X
xionglei6 已提交
52 53 54 55
            return -1;
        }
        for (int j = 0; j < extArgc; j++) {
            if (strncat_s(nameValue, len, "|", 1) != 0) {
X
xionglei6 已提交
56
                BEGET_LOGE("Failed strncat_s \"|\"err=%d", errno);
X
xionglei6 已提交
57 58 59
                return -1;
            }
            if (strncat_s(nameValue, len, extArgv[j], strlen(extArgv[j])) != 0) {
X
xionglei6 已提交
60
                BEGET_LOGE("Failed strncat_s err=%d", errno);
X
xionglei6 已提交
61 62 63 64
                return -1;
            }
        }
        if (SystemSetParameter("ohos.ctl.start", nameValue) != 0) {
X
xionglei6 已提交
65
            BEGET_LOGE("Set param for %s failed.\n", nameValue);
X
xionglei6 已提交
66 67 68 69 70 71
            free(nameValue);
            return -1;
        }
        free(nameValue);
    } else {
        if (SystemSetParameter("ohos.ctl.start", name) != 0) {
X
xionglei6 已提交
72
            BEGET_LOGE("Set param for %s failed.\n", name);
X
xionglei6 已提交
73 74 75 76 77 78
            return -1;
        }
    }
    return 0;
}

X
xionglei6 已提交
79
static int StopProcess(const char *serviceName)
X
xionglei6 已提交
80 81
{
    if (serviceName == NULL) {
X
xionglei6 已提交
82
        BEGET_LOGE("Stop dynamic service failed, service is null.\n");
X
xionglei6 已提交
83 84 85
        return -1;
    }
    if (SystemSetParameter("ohos.ctl.stop", serviceName) != 0) {
X
xionglei6 已提交
86
        BEGET_LOGE("Set param for %s failed.\n", serviceName);
X
xionglei6 已提交
87 88 89 90 91
        return -1;
    }
    return 0;
}

X
xionglei6 已提交
92
static int GetCurrentServiceStatus(const char *serviceName, ServiceStatus *status)
X
xionglei6 已提交
93 94
{
    char paramName[PARAM_NAME_LEN_MAX] = {0};
X
xionglei6 已提交
95 96
    if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1,
        "%s.%s", STARTUP_SERVICE_CTL, serviceName) == -1) {
X
xionglei6 已提交
97
        BEGET_LOGE("Failed snprintf_s err=%d", errno);
X
xionglei6 已提交
98 99
        return -1;
    }
X
xionglei6 已提交
100 101
    char paramValue[PARAM_VALUE_LEN_MAX] = {0};
    unsigned int valueLen = PARAM_VALUE_LEN_MAX;
X
xionglei6 已提交
102
    if (SystemGetParameter(paramName, paramValue, &valueLen) != 0) {
X
xionglei6 已提交
103 104 105
        BEGET_LOGE("Failed get paramName.");
        return -1;
    }
X
xionglei6 已提交
106 107 108
    int size = 0;
    const InitArgInfo *statusMap = GetServieStatusMap(&size);
    *status = GetMapValue(paramValue, statusMap, size, SERVICE_IDLE);
X
xionglei6 已提交
109 110 111
    return 0;
}

X
xionglei6 已提交
112
static int RestartProcess(const char *serviceName, const char *extArgv[], int extArgc)
X
xionglei6 已提交
113 114
{
    if (serviceName == NULL) {
X
xionglei6 已提交
115
        BEGET_LOGE("Restart dynamic service failed, service is null.\n");
X
xionglei6 已提交
116 117
        return -1;
    }
X
xionglei6 已提交
118 119
    ServiceStatus status = SERVICE_IDLE;
    if (GetCurrentServiceStatus(serviceName, &status) != 0) {
X
xionglei6 已提交
120
        BEGET_LOGE("Get service status failed.\n");
X
xionglei6 已提交
121 122
        return -1;
    }
X
xionglei6 已提交
123
    if (status == SERVICE_STARTED || status == SERVICE_READY) {
X
xionglei6 已提交
124 125
        if (StopProcess(serviceName) != 0) {
            BEGET_LOGE("Stop service %s failed", serviceName);
X
xionglei6 已提交
126 127
            return -1;
        }
X
xionglei6 已提交
128
        if (ServiceWaitForStatus(serviceName, SERVICE_STOPPED, DEFAULT_PARAM_WAIT_TIMEOUT) != 0) {
X
xionglei6 已提交
129
            BEGET_LOGE("Failed wait service %s stopped", serviceName);
X
xionglei6 已提交
130 131
            return -1;
        }
X
xionglei6 已提交
132 133
        if (StartProcess(serviceName, extArgv, extArgc) != 0) {
            BEGET_LOGE("Start service %s failed", serviceName);
X
xionglei6 已提交
134 135
            return -1;
        }
X
xionglei6 已提交
136
    } else if (status != SERVICE_STARTING) {
X
xionglei6 已提交
137 138
        if (StartProcess(serviceName, extArgv, extArgc) != 0) {
            BEGET_LOGE("Start service %s failed", serviceName);
X
xionglei6 已提交
139 140 141
            return -1;
        }
    } else {
X
xionglei6 已提交
142
        BEGET_LOGE("Current service status: %d is not support.", status);
X
xionglei6 已提交
143 144 145 146 147 148 149
    }
    return 0;
}

int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc)
{
    if (serviceName == NULL) {
X
xionglei6 已提交
150
        BEGET_LOGE("Service wait failed, service is null.\n");
X
xionglei6 已提交
151 152 153 154 155
        return -1;
    }
    int ret = 0;
    switch (action) {
        case START:
X
xionglei6 已提交
156
            ret = StartProcess(serviceName, extArgv, extArgc);
X
xionglei6 已提交
157 158
            break;
        case STOP:
X
xionglei6 已提交
159
            ret = StopProcess(serviceName);
X
xionglei6 已提交
160 161
            break;
        case RESTART:
X
xionglei6 已提交
162
            ret = RestartProcess(serviceName, extArgv, extArgc);
X
xionglei6 已提交
163 164
            break;
        default:
X
xionglei6 已提交
165
            BEGET_LOGE("Set service %s action %d error", serviceName, action);
X
xionglei6 已提交
166 167 168 169 170 171 172 173
            ret = -1;
            break;
    }
    return ret;
}

int ServiceControl(const char *serviceName, int action)
{
174
    if (serviceName == NULL) {
X
xionglei6 已提交
175
        BEGET_LOGE("Service getctl failed, service is null.");
X
xionglei6 已提交
176 177 178 179 180 181
        return -1;
    }
    int ret = ServiceControlWithExtra(serviceName, action, NULL, 0);
    return ret;
}

X
xionglei6 已提交
182
int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout)
X
xionglei6 已提交
183
{
X
xionglei6 已提交
184 185 186 187 188 189 190 191
    char *state = NULL;
    int size = 0;
    const InitArgInfo *statusMap = GetServieStatusMap(&size);
    if (((int)status < size) && (statusMap[status].value == (int)status)) {
        state = statusMap[status].name;
    }
    if (serviceName == NULL || state == NULL || waitTimeout <= 0) {
        BEGET_LOGE("Service wait failed, service name is null or status invalid %d", status);
X
xionglei6 已提交
192 193 194
        return -1;
    }
    char paramName[PARAM_NAME_LEN_MAX] = {0};
X
xionglei6 已提交
195 196
    if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
        STARTUP_SERVICE_CTL, serviceName) == -1) {
X
xionglei6 已提交
197
        BEGET_LOGE("Failed snprintf_s err=%d", errno);
X
xionglei6 已提交
198 199
        return -1;
    }
X
xionglei6 已提交
200
    if (SystemWaitParameter(paramName, state, waitTimeout) != 0) {
X
xionglei6 已提交
201
        BEGET_LOGE("Wait param for %s failed.", paramName);
X
xionglei6 已提交
202 203
        return -1;
    }
X
xionglei6 已提交
204
    BEGET_LOGI("Success wait");
X
xionglei6 已提交
205 206
    return 0;
}
X
xionglei6 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

int ServiceSetReady(const char *serviceName)
{
    if (serviceName == NULL) {
        BEGET_LOGE("Service wait failed, service is null.");
        return -1;
    }
    char paramName[PARAM_NAME_LEN_MAX] = {0};
    if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
        STARTUP_SERVICE_CTL, serviceName) == -1) {
        BEGET_LOGE("Failed snprintf_s err=%d", errno);
        return -1;
    }
    if (SystemSetParameter(paramName, "ready") != 0) {
        BEGET_LOGE("Set param for %s failed.", paramName);
        return -1;
    }
X
xionglei6 已提交
224
    BEGET_LOGI("Success set %s read", serviceName);
X
xionglei6 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
    return 0;
}

int StartServiceByTimer(const char *serviceName, uint64_t timeout)
{
    if (serviceName == NULL) {
        BEGET_LOGE("Request start serivce by timer with invalid service name");
        return -1;
    }

    if (timeout == 0) {
        // start service immediately.
        return ServiceControl(serviceName, START);
    }
    // restrict timeout value, not too long.
    char value[PARAM_VALUE_LEN_MAX] = {};
    if (snprintf_s(value, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s|%lld", serviceName, timeout) == -1) {
        BEGET_LOGE("Failed to build parameter value");
        return -1;
    }

    if (SystemSetParameter("ohos.servicectrl.timer_start", value) != 0) {
        BEGET_LOGE("Failed to set parameter \' ohos.servicectrl.timer_start \' with value \' %s \'", value);
        return -1;
    }
    return 0;
}

int StopServiceTimer(const char *serviceName)
{
    if (serviceName == NULL) {
        BEGET_LOGE("Request stop serivce timer with invalid service name");
        return -1;
    }

    char value[PARAM_VALUE_LEN_MAX] = {};
    int ret = strncpy_s(value, PARAM_VALUE_LEN_MAX - 1, serviceName, strlen(serviceName));
    if (ret < 0) {
        BEGET_LOGE("Failed to copy service name to parameter");
        return -1;
    }

    if (SystemSetParameter("ohos.servicectrl", value) != 0) {
        BEGET_LOGE("Failed to set parameter \' ohos.servicectrl.timer_stop \' with value \' %s \'", value);
        return -1;
    }
    return 0;
}