init_service.c 5.3 KB
Newer Older
1
/*
2
 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 4 5 6 7 8 9 10 11 12 13 14 15 16
 * 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.
 */
#include "init_service.h"

17
#include <dlfcn.h>
18 19 20 21 22
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>

23
#include "init_group_manager.h"
24 25 26
#include "init.h"
#include "init_log.h"
#include "init_param.h"
X
xionglei6 已提交
27
#include "init_utils.h"
28
#include "securec.h"
29 30
#include "token_setproc.h"
#include "nativetoken_kit.h"
X
xionglei6 已提交
31
#include "service_control.h"
32 33 34 35

#define MIN_IMPORTANT_LEVEL (-20)
#define MAX_IMPORTANT_LEVEL 19

X
xionglei6 已提交
36
void NotifyServiceChange(Service *service, int status)
37
{
X
xionglei6 已提交
38 39 40 41 42 43 44 45 46 47
    int size = 0;
    const InitArgInfo *statusMap = GetServieStatusMap(&size);
    INIT_ERROR_CHECK(statusMap != NULL && size > status, service->status = status;
        return, "Service status error %d", status);
    INIT_LOGI("NotifyServiceChange %s %s to %s", service->name,
        statusMap[service->status].name, statusMap[status].name);
    service->status = status;
    if (status == SERVICE_IDLE) {
        return;
    }
48
    char paramName[PARAM_NAME_LEN_MAX] = { 0 };
X
xionglei6 已提交
49 50 51 52 53
    int ret = snprintf_s(paramName, sizeof(paramName), sizeof(paramName) - 1,
        "%s.%s", STARTUP_SERVICE_CTL, service->name);
    if (ret >= 0) {
        SystemWriteParam(paramName, statusMap[status].name);
    }
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
}

int IsForbidden(const char *fieldStr)
{
    UNUSED(fieldStr);
    return 0;
}

int SetImportantValue(Service *service, const char *attrName, int value, int flag)
{
    UNUSED(attrName);
    UNUSED(flag);
    INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Set service attr failed! null ptr.");
    if (value >= MIN_IMPORTANT_LEVEL && value <= MAX_IMPORTANT_LEVEL) { // -20~19
        service->attribute |= SERVICE_ATTR_IMPORTANT;
        service->importance = value;
    } else {
        INIT_LOGE("Importance level = %d, is not between -20 and 19, error", value);
        return SERVICE_FAILURE;
    }
    return SERVICE_SUCCESS;
}

X
xionglei6 已提交
77
int ServiceExec(const Service *service)
78 79 80 81 82
{
    INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
        return SERVICE_FAILURE, "Exec service failed! null ptr.");
    if (service->importance != 0) {
        if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
X
xionglei6 已提交
83 84
            INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
                service->name, service->importance, errno);
85
                _exit(0x7f); // 0x7f: user specified
86 87
        }
    }
X
add ut  
xionglei6 已提交
88
    INIT_CHECK_ONLY_ELOG(unsetenv("UV_THREADPOOL_SIZE") == 0, "set UV_THREADPOOL_SIZE error : %d.", errno);
Y
yanmengzhao 已提交
89
#ifdef SUPPORT_PROFILER_HIDEBUG
90 91 92 93 94 95 96 97 98 99 100 101
    void* handle = dlopen("/system/lib/libhidebug.so", RTLD_LAZY);
    if (handle == NULL) {
        INIT_LOGE("Failed to dlopen libhidebug.so, %s\n", dlerror());
        return SERVICE_FAILURE;
    }
    bool (* initParam)();
    initParam = (bool (*)())dlsym(handle, "InitEnvironmentParam");
    if (initParam == NULL) {
        INIT_LOGE("Failed to dlsym InitEnvironmentParam, %s\n", dlerror());
        return SERVICE_FAILURE;
    }
    (*initParam)(service->name);
Y
yanmengzhao 已提交
102
#endif
103
    // L2 Can not be reset env
X
xionglei6 已提交
104
    if (service->extraArgs.argv != NULL && service->extraArgs.count > 0) {
X
xionglei6 已提交
105
        INIT_CHECK_ONLY_ELOG(execv(service->extraArgs.argv[0], service->extraArgs.argv) == 0,
X
xionglei6 已提交
106 107 108 109 110
            "service %s execve failed! err %d.", service->name, errno);
    } else {
        INIT_CHECK_ONLY_ELOG(execv(service->pathArgs.argv[0], service->pathArgs.argv) == 0,
            "service %s execve failed! err %d.", service->name, errno);
    }
111
    return SERVICE_SUCCESS;
Q
Qin Fandong 已提交
112
}
113 114 115 116

int SetAccessToken(const Service *service)
{
    INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "%s failed", service->name);
X
xlei1030 已提交
117 118 119
    int ret = SetSelfTokenID(service->tokenId);
    INIT_LOGI("%s: token id %lld, set token id result %d", service->name, service->tokenId, ret);
    return ret == 0 ? SERVICE_SUCCESS : SERVICE_FAILURE;
120 121 122 123 124 125 126 127 128 129 130 131
}

void GetAccessToken(void)
{
    InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
    while (node != NULL) {
        Service *service = node->data.service;
        if (service != NULL) {
            if (service->capsArgs.count == 0) {
                service->capsArgs.argv = NULL;
            }
            if (strlen(service->apl) == 0) {
X
xionglei6 已提交
132
                (void)strncpy_s(service->apl, sizeof(service->apl), "system_core", sizeof(service->apl) - 1);
133 134 135 136
            }
            uint64_t tokenId = GetAccessTokenId(service->name, (const char **)service->capsArgs.argv,
                service->capsArgs.count, service->apl);
            if (tokenId  == 0) {
X
xionglei6 已提交
137
                INIT_LOGE("Get totken id %lld of service \' %s \' failed", tokenId, service->name);
138 139 140 141 142 143
            }
            service->tokenId = tokenId;
        }
        node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
    }
}