service_control.c 6.4 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, char *status, int len)
X
xionglei6 已提交
93 94 95
{
    char paramName[PARAM_NAME_LEN_MAX] = {0};
    if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", serviceName) == -1) {
X
xionglei6 已提交
96
        BEGET_LOGE("Failed snprintf_s err=%d", errno);
X
xionglei6 已提交
97 98
        return -1;
    }
X
xionglei6 已提交
99 100
    char paramValue[PARAM_VALUE_LEN_MAX] = {0};
    unsigned int valueLen = PARAM_VALUE_LEN_MAX;
X
xionglei6 已提交
101
    if (SystemGetParameter(paramName, paramValue, &valueLen) != 0) {
X
xionglei6 已提交
102 103 104 105 106
        BEGET_LOGE("Failed get paramName.");
        return -1;
    }
    if (strncpy_s(status, len, paramValue, len - 1) < 0) {
        BEGET_LOGE("Failed strncpy_s err=%d", errno);
X
xionglei6 已提交
107 108 109 110 111
        return -1;
    }
    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 120
    char status[PARAM_VALUE_LEN_MAX] = {0};
    if (GetCurrentServiceStatus(serviceName, status, PARAM_VALUE_LEN_MAX) != 0) {
        BEGET_LOGE("Get service status failed.\n");
X
xionglei6 已提交
121 122
        return -1;
    }
X
xionglei6 已提交
123 124 125
    if (strcmp(status, "running") == 0) {
        if (StopProcess(serviceName) != 0) {
            BEGET_LOGE("Stop service %s failed", serviceName);
X
xionglei6 已提交
126 127 128
            return -1;
        }
        if (ServiceWaitForStatus(serviceName, "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 137 138
    } else if (strcmp(status, "stopped") == 0) {
        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: %s 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 182 183 184 185
        return -1;
    }
    int ret = ServiceControlWithExtra(serviceName, action, NULL, 0);
    return ret;
}

// Service status can set "running", "stopping", "stopped", "reseting". waitTimeout(s).
int ServiceWaitForStatus(const char *serviceName, const char *status, int waitTimeout)
{
    if (serviceName == NULL) {
X
xionglei6 已提交
186
        BEGET_LOGE("Service wait failed, service is null.");
X
xionglei6 已提交
187 188 189 190
        return -1;
    }
    char paramName[PARAM_NAME_LEN_MAX] = {0};
    if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", serviceName) == -1) {
X
xionglei6 已提交
191
        BEGET_LOGE("Failed snprintf_s err=%d", errno);
X
xionglei6 已提交
192 193 194
        return -1;
    }
    if (SystemWaitParameter(paramName, status, waitTimeout) != 0) {
X
xionglei6 已提交
195
        BEGET_LOGE("Wait param for %s failed.", paramName);
X
xionglei6 已提交
196 197
        return -1;
    }
X
xionglei6 已提交
198
    BEGET_LOGI("Success wait");
X
xionglei6 已提交
199 200
    return 0;
}