init_service.c 4.8 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 17 18 19 20 21
 * 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"

#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>

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

#define MIN_IMPORTANT_LEVEL (-20)
#define MAX_IMPORTANT_LEVEL 19

X
xionglei6 已提交
35
void NotifyServiceChange(Service *service, int status)
36
{
X
xionglei6 已提交
37 38 39 40 41 42 43 44 45 46
    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;
    }
47
    char paramName[PARAM_NAME_LEN_MAX] = { 0 };
X
xionglei6 已提交
48 49 50 51 52
    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);
    }
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
}

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 已提交
76
int ServiceExec(const Service *service)
77 78 79 80 81
{
    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 已提交
82 83
            INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
                service->name, service->importance, errno);
84
                _exit(0x7f); // 0x7f: user specified
85 86
        }
    }
X
add ut  
xionglei6 已提交
87
    INIT_CHECK_ONLY_ELOG(unsetenv("UV_THREADPOOL_SIZE") == 0, "set UV_THREADPOOL_SIZE error : %d.", errno);
88
    // L2 Can not be reset env
X
xionglei6 已提交
89
    if (service->extraArgs.argv != NULL && service->extraArgs.count > 0) {
X
xionglei6 已提交
90
        INIT_CHECK_ONLY_ELOG(execv(service->extraArgs.argv[0], service->extraArgs.argv) == 0,
X
xionglei6 已提交
91 92 93 94 95
            "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);
    }
96
    return SERVICE_SUCCESS;
Q
Qin Fandong 已提交
97
}
98 99 100 101

int SetAccessToken(const Service *service)
{
    INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "%s failed", service->name);
X
xionglei6 已提交
102 103 104 105
    if (service->tokenId != 0 && SetSelfTokenID(service->tokenId) != 0) {
        INIT_LOGE("%s: token id %lld, set token id result %d", service->name, service->tokenId, errno);
    }
    return 0;
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
}

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) {
                (void)strncpy_s(service->apl, sizeof(service->apl),
		    "system_core", sizeof(service->apl) - 1);
            }
            uint64_t tokenId = GetAccessTokenId(service->name, (const char **)service->capsArgs.argv,
                service->capsArgs.count, service->apl);
            if (tokenId  == 0) {
                INIT_LOGE("Set totken id %lld of service \' %s \' failed", service->name, tokenId);
            }
            service->tokenId = tokenId;
        }
        node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
    }
}