提交 3275e747 编写于 作者: X xionglei6

add beget control api

Signed-off-by: Nxionglei6 <xionglei6@huawei.com>
上级 f5ed759c
......@@ -30,6 +30,7 @@ ohos_shared_library("libbegetutil") {
"file/init_file.c",
"reboot/init_reboot_innerkits.c",
"socket/init_socket.c",
"begetctl_utils/begetctl_utils.c",
]
sources += fs_manager_sources
......@@ -39,7 +40,6 @@ ohos_shared_library("libbegetutil") {
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/include/param",
"//base/startup/syspara_lite/hals/parameter/include",
]
deps = [
"//base/startup/init_lite/services/log:init_log",
......@@ -49,8 +49,32 @@ ohos_shared_library("libbegetutil") {
"//third_party/openssl:libcrypto_static",
"//utils/native/base:utils",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
public_configs = [ ":exported_header_files" ]
part_name = "init"
install_images = [
"system",
"updater",
]
}
# watcher lib must separate compilation avoid interdependence.
ohos_shared_library("libbegetctl_watcher") {
sources = [ "begetctl_watcher/begetctl_watcher.c" ]
include_dirs = [
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/include/param",
"//third_party/bounds_checking_function/include",
]
deps = [
"//base/startup/init_lite/services/param/watcher:param_watcheragent",
"//base/startup/init_lite/services/utils:libinit_utils",
"//third_party/bounds_checking_function:libsec_shared",
]
public_configs = [ ":exported_header_files" ]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
part_name = "init"
install_images = [
"system",
......
/*
* 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.
*/
#include "begetctl_utils.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hilog/log.h"
#include "init_utils.h"
#include "securec.h"
#include "sys_param.h"
static int StartDynamicProcess(const char *name, const char *extArgv[], int extArgc)
{
if (name == NULL) {
HILOG_ERROR(LOG_CORE, "Start dynamic service failed, service name is null.");
return -1;
}
int extraArg = 0;
if ((extArgv != NULL) && (extArgc > 0)) {
HILOG_INFO(LOG_CORE, "Start service by extra args");
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) {
HILOG_ERROR(LOG_CORE, "Failed calloc err=%{public}d", errno);
return -1;
}
if (strncat_s(nameValue, len, name, strlen(name)) != 0) {
HILOG_ERROR(LOG_CORE, "Failed strncat_s name err=%{public}d", errno);
return -1;
}
for (int j = 0; j < extArgc; j++) {
if (strncat_s(nameValue, len, "|", 1) != 0) {
HILOG_ERROR(LOG_CORE, "Failed strncat_s \"|\"err=%{public}d", errno);
return -1;
}
if (strncat_s(nameValue, len, extArgv[j], strlen(extArgv[j])) != 0) {
HILOG_ERROR(LOG_CORE, "Failed strncat_s err=%{public}d", errno);
return -1;
}
}
HILOG_INFO(LOG_CORE,"nameValue is %{public}s", nameValue);
if (SystemSetParameter("ohos.ctl.start", nameValue) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", nameValue);
free(nameValue);
return -1;
}
free(nameValue);
} else {
if (SystemSetParameter("ohos.ctl.start", name) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name);
return -1;
}
}
return 0;
}
static int StopDynamicProcess(const char *serviceName)
{
if (serviceName == NULL) {
HILOG_ERROR(LOG_CORE, "Stop dynamic service failed, service is null.\n");
return -1;
}
if (SystemSetParameter("ohos.ctl.stop", serviceName) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", serviceName);
return -1;
}
return 0;
}
static int GetCurrentServiceStatus(const char *serviceName, char *paramValue, unsigned int valueLen)
{
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) {
HILOG_ERROR(LOG_CORE, "Failed snprintf_s err=%{public}d", errno);
return -1;
}
if (SystemGetParameter(paramName, paramValue, &valueLen) != 0) {
HILOG_ERROR(LOG_CORE, "Failed get paramName.");
return -1;
}
return 0;
}
static int RestartDynamicProcess(const char *serviceName, const char *extArgv[], int extArgc)
{
if (serviceName == NULL) {
HILOG_ERROR(LOG_CORE, "Restart dynamic service failed, service is null.\n");
return -1;
}
char paramValue[PARAM_VALUE_LEN_MAX] = {0};
unsigned int valueLen = PARAM_VALUE_LEN_MAX;
if (GetCurrentServiceStatus(serviceName, paramValue, valueLen) != 0) {
HILOG_ERROR(LOG_CORE, "Get service status failed.\n");
return -1;
}
if (strcmp(paramValue, "running") == 0) {
if (StopDynamicProcess(serviceName) != 0) {
HILOG_ERROR(LOG_CORE, "Stop service %{public}s failed", serviceName);
return -1;
}
if (ServiceWaitForStatus(serviceName, "stopped", DEFAULT_PARAM_WAIT_TIMEOUT) != 0) {
HILOG_ERROR(LOG_CORE, "Failed wait service %{public}s stopped", serviceName);
return -1;
}
if (StartDynamicProcess(serviceName, extArgv, extArgc) != 0) {
HILOG_ERROR(LOG_CORE, "Start service %{public}s failed", serviceName);
return -1;
}
} else if (strcmp(paramValue, "stopped") == 0) {
if (StartDynamicProcess(serviceName, extArgv, extArgc) != 0) {
HILOG_ERROR(LOG_CORE, "Start service %{public}s failed", serviceName);
return -1;
}
} else {
HILOG_ERROR(LOG_CORE, "Current service status: %{public}s is not support.", paramValue);
}
return 0;
}
int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc)
{
if (serviceName == NULL) {
HILOG_ERROR(LOG_CORE, "Service wait failed, service is null.\n");
return -1;
}
int ret = 0;
switch (action) {
case START:
ret = StartDynamicProcess(serviceName, extArgv, extArgc);
break;
case STOP:
ret = StopDynamicProcess(serviceName);
break;
case RESTART:
ret = RestartDynamicProcess(serviceName, extArgv, extArgc);
break;
default:
HILOG_ERROR(LOG_CORE, "Set service %{public}s action %d error", serviceName, action);
ret = -1;
break;
}
return ret;
}
int ServiceControl(const char *serviceName, int action)
{
if (serviceName == 0) {
HILOG_ERROR(LOG_CORE, "Service getctl failed, service is null.\n");
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) {
HILOG_ERROR(LOG_CORE, "Service wait failed, service is null.\n");
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) {
HILOG_ERROR(LOG_CORE, "Failed snprintf_s err=%{public}d", errno);
return -1;
}
if (SystemWaitParameter(paramName, status, waitTimeout) != 0) {
HILOG_ERROR(LOG_CORE, "Wait param for %{public}s failed.\n", paramName);
return -1;
}
HILOG_INFO(LOG_CORE, "Success wait");
return 0;
}
......@@ -12,41 +12,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "begetctl_watcher.h"
#include "dynamic_service.h"
#include <errno.h>
#include <stdio.h>
#include "hilog/log.h"
#include "parameter.h"
#include <stdlib.h>
#include <string.h>
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Init"
#define LOG_DOMAIN 0xD000719
#include "hilog/log.h"
#include "init_utils.h"
#include "securec.h"
int32_t StartDynamicProcess(const char *name)
int ServiceWatchForStatus(const char *serviceName, void *context, ServiceStatusChangePtr changeCallback)
{
if (name == NULL) {
HILOG_ERROR(LOG_CORE, "Start dynamic service failed, service name is null.");
return -1;
}
if (SetParameter("ohos.ctl.start", name) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name);
if (serviceName == NULL) {
HILOG_ERROR(LOG_CORE, "Service wait failed, service is null.\n");
return -1;
}
return 0;
}
int32_t StopDynamicProcess(const char *name)
{
if (name == NULL) {
HILOG_ERROR(LOG_CORE, "Stop dynamic service failed, service is null.\n");
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) {
HILOG_ERROR(LOG_CORE, "Failed snprintf_s err=%{public}d", errno);
return -1;
}
if (SetParameter("ohos.ctl.stop", name) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name);
if (SystemWatchParameter(paramName, changeCallback, context) != 0) {
HILOG_ERROR(LOG_CORE, "Wait param for %{public}s failed.\n", paramName);
return -1;
}
return 0;
}
/*
* 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.
*/
#ifndef BEGET_UTILS_API_H
#define BEGET_UTILS_API_H
#include <inttypes.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
enum ServiceAction {
START = 0,
STOP = 1,
RESTART = 2,
};
int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc);
int ServiceControl(const char *serviceName, int action);
int ServiceWaitForStatus(const char *serviceName, const char *status, int waitTimeout);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif
/*
* 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.
*/
#ifndef DYNAMIC_SERVICE_API_H
#define DYNAMIC_SERVICE_API_H
#include <inttypes.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int32_t StartDynamicProcess(const char *name);
int32_t StopDynamicProcess(const char *name);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // DYNAMIC_SERVICE_API_H
\ No newline at end of file
/*
* 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.
*/
#ifndef SERVICE_WATCH_API_H
#define SERVICE_WATCH_API_H
#include "sys_param.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef ParameterChangePtr ServiceStatusChangePtr;
int ServiceWatchForStatus(const char *serviceName, void *context, ServiceStatusChangePtr changeCallback);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif
......@@ -8,22 +8,29 @@
"//base/startup/init_lite/watchdog:watchdog",
"//base/startup/init_lite/services/begetctl:begetctl",
"//base/startup/init_lite/interfaces/innerkits:libbegetutil",
"//base/startup/init_lite/interfaces/innerkits/file:libfile",
"//base/startup/init_lite/interfaces/innerkits/socket:libsocket"
"//base/startup/init_lite/interfaces/innerkits:libbegetctl_watcher"
],
"inner_kits": [{
"header": {
"header_files": [
"init_socket.h",
"dynamic_service.h",
"init_file.h",
"fs_manager/fs_manager_log.h",
"fs_manager/fs_manager.h",
"init_reboot.h"
"init_reboot.h",
"begetctl_utils.h"
],
"header_base": "//base/startup/init_lite/interfaces/innerkits/include/"
},
"name": "//base/startup/init_lite/interfaces/innerkits:libbegetutil"
}, {
"header": {
"header_files": [
"begetctl_watcher.h"
],
"header_base": "//base/startup/init_lite/interfaces/innerkits/include/"
},
"name": "//base/startup/init_lite/interfaces/innerkits:libbegetctl_watcher"
}
],
"test_list": [
......
......@@ -83,6 +83,7 @@ typedef struct {
int importance;
Perms servPerm;
ServiceArgs pathArgs;
ServiceArgs extraArgs;
ServiceArgs writePidArgs;
CmdLines *restartArg;
ServiceSocket *socketCfg;
......@@ -98,7 +99,7 @@ void NotifyServiceChange(const char *serviceName, const char *change);
int IsForbidden(const char *fieldStr);
int SetImportantValue(Service *curServ, const char *attrName, int value, int flag);
int GetServiceCaps(const cJSON *curArrItem, Service *curServ);
int ServiceExec(const Service *service);
int ServiceExec(Service *service);
#ifdef __cplusplus
#if __cplusplus
......
......@@ -617,6 +617,7 @@ void StartServiceByName(const char *servName, bool checkDynamic)
if (checkDynamic && (service->attribute & SERVICE_ATTR_DYNAMIC)) {
INIT_LOGI("%s is dynamic service.", servName);
NotifyServiceChange(servName, "stopped");
return;
}
if (ServiceStart(service) != SERVICE_SUCCESS) {
......@@ -663,6 +664,25 @@ Service *GetServiceByPid(pid_t pid)
return NULL;
}
static int SetServiceExtraArgs(Service *service, const char *fullServName)
{
INIT_ERROR_CHECK(service != NULL && fullServName != NULL, return -1, "Failed get parameters");
int returnCount = 0;
char *tmpServName = strdup(fullServName);
char **extArgv = SplitStringExt(tmpServName, "|", &returnCount, MAX_PATH_ARGS_CNT);
free(tmpServName);
INIT_ERROR_CHECK(extArgv != NULL && returnCount > 0, return -1, "Split servName: %s failed", fullServName);
service->extraArgs.count = returnCount - 1;
service->extraArgs.argv = (char **)calloc(service->extraArgs.count, sizeof(char *));
INIT_ERROR_CHECK(service->extraArgs.argv != NULL, FreeStringVector(extArgv, returnCount); return -1,
"Failed calloc err=%d", errno);
for (int i = 0; i < service->extraArgs.count; i++) {
service->extraArgs.argv[i] = strdup(extArgv[i + 1]);
}
FreeStringVector(extArgv, returnCount);
return 0;
}
Service *GetServiceByName(const char *servName)
{
INIT_ERROR_CHECK(servName != NULL, return NULL, "Failed get servName");
......@@ -670,7 +690,12 @@ Service *GetServiceByName(const char *servName)
while (node != &g_serviceSpace.services) {
Service *service = ListEntry(node, Service, node);
if (service != NULL) {
INIT_CHECK_RETURN_VALUE(strcmp(service->name, servName) != 0, service);
if (strcmp(service->name, servName) == 0) {
return service;
} else if (strncmp(service->name, servName, strlen(service->name)) == 0) {
SetServiceExtraArgs(service, servName);
return service;
}
}
node = node->next;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册