1/* 2 * Copyright (c) 2023 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#include "init_context.h" 16 17#include "init_module_engine.h" 18#include "init_utils.h" 19#include "plugin_adapter.h" 20#include "securec.h" 21 22static SubInitContext g_subInitContext[INIT_CONTEXT_MAIN] = { 0 }; 23static ConfigContext g_currContext = { INIT_CONTEXT_MAIN }; 24static int g_subInitRunning = 0; 25 26int InitSubInitContext(InitContextType type, const SubInitContext *context) 27{ 28 PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type); 29 PLUGIN_CHECK(context != NULL, return -1, "Invalid context %d", type); 30 g_subInitContext[type].type = type; 31 g_subInitContext[type].startSubInit = context->startSubInit; 32 g_subInitContext[type].stopSubInit = context->stopSubInit; 33 g_subInitContext[type].executeCmdInSubInit = context->executeCmdInSubInit; 34 g_subInitContext[type].setSubInitContext = context->setSubInitContext; 35 return 0; 36} 37 38void StopSubInit(pid_t pid) 39{ 40 if (g_subInitContext[0].stopSubInit != NULL) { 41 g_subInitContext[0].stopSubInit(pid); 42 } 43} 44 45int StartSubInit(InitContextType type) 46{ 47 PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type); 48 if (!g_subInitRunning) { 49 // install init context 50#ifndef STARTUP_INIT_TEST 51 InitModuleMgrInstall("init_context"); 52#endif 53 } 54 PLUGIN_CHECK(g_subInitContext[type].startSubInit != NULL, return -1, "Invalid context %d", type); 55 g_subInitRunning = 1; 56 return g_subInitContext[type].startSubInit(type); 57} 58 59int ExecuteCmdInSubInit(const ConfigContext *context, const char *name, const char *cmdContent) 60{ 61 PLUGIN_CHECK(context != NULL, return -1, "Invalid context"); 62 PLUGIN_CHECK(name != NULL, return -1, "Invalid name"); 63 PLUGIN_CHECK(context->type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", context->type); 64 PLUGIN_LOGV("Execute command '%s %s' in context %d", name, cmdContent, context->type); 65 StartSubInit(context->type); 66 PLUGIN_CHECK(g_subInitContext[context->type].executeCmdInSubInit != NULL, 67 return -1, "Invalid context %d", context->type); 68 return g_subInitContext[context->type].executeCmdInSubInit(context->type, name, cmdContent); 69} 70 71int SetSubInitContext(const ConfigContext *context, const char *service) 72{ 73 if (InUpdaterMode() == 1) { // not support sub init in update mode 74 return 0; 75 } 76 PLUGIN_CHECK(context != NULL, return -1, "Invalid context"); 77 if (context->type >= INIT_CONTEXT_MAIN) { 78 g_currContext.type = INIT_CONTEXT_MAIN; 79 return 0; 80 } 81 g_currContext.type = context->type; 82 PLUGIN_CHECK(g_subInitContext[context->type].setSubInitContext != NULL, 83 return -1, "Invalid context %d", context->type); 84 PLUGIN_LOGI("Set selinux context %d for %s", context->type, service); 85 return g_subInitContext[context->type].setSubInitContext(context->type); 86} 87 88int CheckExecuteInSubInit(const ConfigContext *context) 89{ 90 if (InUpdaterMode() == 1) { // not support sub init in update mode 91 return 0; 92 } 93#ifdef INIT_SUPPORT_CHIPSET_INIT 94 return !(context == NULL || context->type == INIT_CONTEXT_MAIN || g_currContext.type != INIT_CONTEXT_MAIN); 95#else 96 return 0; 97#endif 98} 99 100#ifdef STARTUP_INIT_TEST 101SubInitContext *GetSubInitContext(InitContextType type) 102{ 103 PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return NULL, "Invalid type %d", type); 104 return &g_subInitContext[type]; 105} 106#endif 107