提交 ce79ebd3 编写于 作者: X xionglei6

init: add func

Signed-off-by: Nxionglei6 <xionglei6@huawei.com>
上级 fcec75a6
...@@ -14,4 +14,9 @@ ...@@ -14,4 +14,9 @@
declare_args() { declare_args() {
param_feature_watcher = true param_feature_watcher = true
param_test = false param_test = false
if (defined(product_name) && product_name == "rk3568") {
boot_kernel_extended_cmdline =
"hardware=rk3568 default_boot_device=fe310000.sdhci"
}
} }
...@@ -288,11 +288,10 @@ FstabItem *FindFstabItemForPath(Fstab fstab, const char *path) ...@@ -288,11 +288,10 @@ FstabItem *FindFstabItemForPath(Fstab fstab, const char *path)
return item; return item;
} }
char *GetFstabFile(void) static char *GetFstabFile(char *fileName, int size)
{ {
char file[PATH_MAX] = {0};
if (InUpdaterMode() == 1) { if (InUpdaterMode() == 1) {
if (strncpy_s(file, PATH_MAX, "/etc/fstab.updater", strlen("/etc/fstab.updater")) != 0) { if (strncpy_s(fileName, size, "/etc/fstab.updater", strlen("/etc/fstab.updater")) != 0) {
BEGET_LOGE("Failed strncpy_s err=%d", errno); BEGET_LOGE("Failed strncpy_s err=%d", errno);
return NULL; return NULL;
} }
...@@ -309,13 +308,13 @@ char *GetFstabFile(void) ...@@ -309,13 +308,13 @@ char *GetFstabFile(void)
BEGET_LOGE("Failed get hardware from cmdline"); BEGET_LOGE("Failed get hardware from cmdline");
return NULL; return NULL;
} }
if (snprintf_s(file, PATH_MAX, PATH_MAX - 1, "/vendor/etc/fstab.%s", hardware) == -1) { if (snprintf_s(fileName, size, size - 1, "/vendor/etc/fstab.%s", hardware) == -1) {
BEGET_LOGE("Fail snprintf_s err=%d", errno); BEGET_LOGE("Fail snprintf_s err=%d", errno);
return NULL; return NULL;
} }
} }
BEGET_LOGI("file is %s", file); BEGET_LOGI("file is %s", fileName);
return strdup(file); // After the return value is used up, it must be free. return fileName;
} }
int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char *deviceName, int nameLen) int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char *deviceName, int nameLen)
...@@ -425,6 +424,22 @@ unsigned long GetMountFlags(char *mountFlag, char *fsSpecificData, size_t fsSpec ...@@ -425,6 +424,22 @@ unsigned long GetMountFlags(char *mountFlag, char *fsSpecificData, size_t fsSpec
FreeStringVector(flagsVector, flagCount); FreeStringVector(flagsVector, flagCount);
return flags; return flags;
} }
int GetBlockDevicePath(const char *partName, char *path, int size)
{
char *fstabFile = GetFstabFile(path, size);
if (fstabFile == NULL) {
return -1;
}
Fstab *fstab = ReadFstabFromFile(fstabFile, false);
if (fstab == NULL) {
return -1;
}
int ret = GetBlockDeviceByMountPoint(partName, fstab, path, size);
ReleaseFstab(fstab);
return ret;
}
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -276,9 +276,11 @@ static int Mount(const char *source, const char *target, const char *fsType, ...@@ -276,9 +276,11 @@ static int Mount(const char *source, const char *target, const char *fsType,
if (errno == EAGAIN) { if (errno == EAGAIN) {
BEGET_LOGE("Mount %s to %s failed. try again", source, target); BEGET_LOGE("Mount %s to %s failed. try again", source, target);
continue; continue;
} else {
break;
} }
if (errno == EBUSY) {
rc = 0;
}
break;
} }
return rc; return rc;
} }
......
...@@ -60,7 +60,7 @@ void ReleaseFstab(Fstab *fstab); ...@@ -60,7 +60,7 @@ void ReleaseFstab(Fstab *fstab);
Fstab *ReadFstabFromFile(const char *file, bool procMounts); Fstab *ReadFstabFromFile(const char *file, bool procMounts);
FstabItem *FindFstabItemForPath(Fstab fstab, const char *path); FstabItem *FindFstabItemForPath(Fstab fstab, const char *path);
FstabItem* FindFstabItemForMountPoint(Fstab fstab, const char *mp); FstabItem* FindFstabItemForMountPoint(Fstab fstab, const char *mp);
char *GetFstabFile(void);
int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char *deviceName, int nameLen); int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char *deviceName, int nameLen);
bool IsSupportedFilesystem(const char *fsType); bool IsSupportedFilesystem(const char *fsType);
int DoFormat(const char *devPath, const char *fsType); int DoFormat(const char *devPath, const char *fsType);
...@@ -70,6 +70,8 @@ int MountAllWithFstabFile(const char *fstabFile, bool required); ...@@ -70,6 +70,8 @@ int MountAllWithFstabFile(const char *fstabFile, bool required);
int MountAllWithFstab(const Fstab *fstab, bool required); int MountAllWithFstab(const Fstab *fstab, bool required);
int UmountAllWithFstabFile(const char *file); int UmountAllWithFstabFile(const char *file);
unsigned long GetMountFlags(char *mountFlag, char *fsSpecificFlags, size_t fsSpecificFlagSize); unsigned long GetMountFlags(char *mountFlag, char *fsSpecificFlags, size_t fsSpecificFlagSize);
int GetBlockDevicePath(const char *partName, char *path, int size);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -22,6 +22,13 @@ extern "C" { ...@@ -22,6 +22,13 @@ extern "C" {
#endif #endif
#endif #endif
#define STARTUP_DEVICE_CTL "startup.device.ctl"
#define DEVICE_CMD_STOP "stop"
#define DEVICE_CMD_SUSPEND "suspend"
#define DEVICE_CMD_RESUME "resume"
#define DEVICE_CMD_FREEZE "freeze"
#define DEVICE_CMD_RESTORE "restore"
int DoReboot(const char *cmdContent); int DoReboot(const char *cmdContent);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -24,6 +24,22 @@ extern "C" { ...@@ -24,6 +24,22 @@ extern "C" {
#endif #endif
#endif #endif
#define STARTUP_SERVICE_CTL "startup.service.ctl"
typedef enum {
SERVICE_IDLE = 0, // service add
SERVICE_STARTING, // service start
SERVICE_STARTED,
SERVICE_READY,
SERVICE_STOPPING,
SERVICE_STOPPED,
SERVICE_ERROR,
SERVICE_SUSPENDED,
SERVICE_FREEZED,
SERVICE_DISABLED,
SERVICE_CRITIAL
} ServiceStatus;
enum ServiceAction { enum ServiceAction {
START = 0, START = 0,
STOP = 1, STOP = 1,
...@@ -32,9 +48,10 @@ enum ServiceAction { ...@@ -32,9 +48,10 @@ enum ServiceAction {
int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc); int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc);
int ServiceControl(const char *serviceName, int action); int ServiceControl(const char *serviceName, int action);
// Service status can set "running", "stopping", "stopped", "reseting". waitTimeout(s). int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout);
int ServiceWaitForStatus(const char *serviceName, const char *status, int waitTimeout); int ServiceSetReady(const char *serviceName);
int StartServiceByTimer(const char *serviceName, uint64_t timeout);
int StopServiceTimer(const char *serviceName);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -17,14 +17,16 @@ ...@@ -17,14 +17,16 @@
#define SERVICE_WATCH_API_H #define SERVICE_WATCH_API_H
#include "sys_param.h" #include "sys_param.h"
#include "service_control.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
#endif #endif
#endif #endif
typedef ParameterChangePtr ServiceStatusChangePtr;
int ServiceWatchForStatus(const char *serviceName, void *context, ServiceStatusChangePtr changeCallback); typedef void (*ServiceStatusChangePtr)(const char *key, ServiceStatus status);
int ServiceWatchForStatus(const char *serviceName, ServiceStatusChangePtr changeCallback);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
...@@ -35,20 +35,31 @@ ...@@ -35,20 +35,31 @@
int DoReboot(const char *option) int DoReboot(const char *option)
{ {
char value[MAX_REBOOT_OPTION_SIZE]; char value[MAX_REBOOT_OPTION_SIZE];
int ret = 0;
if (option == NULL || strlen(option) == 0) { if (option == NULL || strlen(option) == 0) {
BEGET_ERROR_CHECK(snprintf_s(value, MAX_REBOOT_OPTION_SIZE, strlen("reboot") + 1, "%s", "reboot") >= 0, ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_STOP);
return -1, "reboot options too large, overflow"); BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
BEGET_ERROR_CHECK(SystemSetParameter(DOREBOOT_PARAM, value) == 0, return -1, ret = SystemSetParameter(DOREBOOT_PARAM, "reboot");
"Set parameter to trigger reboot command \" %s \" failed", value); BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set reboot param");
return 0; return 0;
} }
int length = strlen(option); int length = strlen(option);
BEGET_ERROR_CHECK(length <= MAX_REBOOT_OPTION_SIZE, return -1, BEGET_ERROR_CHECK(length <= MAX_REBOOT_OPTION_SIZE, return -1,
"Reboot option \" %s \" is too large, overflow", option); "Reboot option \" %s \" is too large, overflow", option);
BEGET_ERROR_CHECK(snprintf_s(value, MAX_REBOOT_OPTION_SIZE, MAX_REBOOT_OPTION_SIZE - 1, "%s%s", "reboot,", ret = snprintf_s(value, MAX_REBOOT_OPTION_SIZE, MAX_REBOOT_OPTION_SIZE - 1, "reboot,%s", option);
option) >= 0, return -1, "Failed to copy boot option \" %s \"", option); BEGET_ERROR_CHECK(ret >= 0, return -1, "Failed to copy boot option \" %s \"", option);
BEGET_ERROR_CHECK(SystemSetParameter(DOREBOOT_PARAM, value) == 0, return -1,
"Set parameter to trigger reboot command \" %s \" failed", value); if (strcmp(option, DEVICE_CMD_SUSPEND) == 0) {
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_SUSPEND);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
} else if (strcmp(option, DEVICE_CMD_FREEZE) == 0) {
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_FREEZE);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
} else {
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_STOP);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
}
ret = SystemSetParameter(DOREBOOT_PARAM, value);
BEGET_ERROR_CHECK(ret == 0, return -1, "Set parameter to trigger reboot command \" %s \" failed", value);
return 0; return 0;
} }
...@@ -89,10 +89,11 @@ static int StopProcess(const char *serviceName) ...@@ -89,10 +89,11 @@ static int StopProcess(const char *serviceName)
return 0; return 0;
} }
static int GetCurrentServiceStatus(const char *serviceName, char *status, int len) static int GetCurrentServiceStatus(const char *serviceName, ServiceStatus *status)
{ {
char paramName[PARAM_NAME_LEN_MAX] = {0}; 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) { if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1,
"%s.%s", STARTUP_SERVICE_CTL, serviceName) == -1) {
BEGET_LOGE("Failed snprintf_s err=%d", errno); BEGET_LOGE("Failed snprintf_s err=%d", errno);
return -1; return -1;
} }
...@@ -102,10 +103,9 @@ static int GetCurrentServiceStatus(const char *serviceName, char *status, int le ...@@ -102,10 +103,9 @@ static int GetCurrentServiceStatus(const char *serviceName, char *status, int le
BEGET_LOGE("Failed get paramName."); BEGET_LOGE("Failed get paramName.");
return -1; return -1;
} }
if (strncpy_s(status, len, paramValue, len - 1) < 0) { int size = 0;
BEGET_LOGE("Failed strncpy_s err=%d", errno); const InitArgInfo *statusMap = GetServieStatusMap(&size);
return -1; *status = GetMapValue(paramValue, statusMap, size, SERVICE_IDLE);
}
return 0; return 0;
} }
...@@ -115,17 +115,17 @@ static int RestartProcess(const char *serviceName, const char *extArgv[], int ex ...@@ -115,17 +115,17 @@ static int RestartProcess(const char *serviceName, const char *extArgv[], int ex
BEGET_LOGE("Restart dynamic service failed, service is null.\n"); BEGET_LOGE("Restart dynamic service failed, service is null.\n");
return -1; return -1;
} }
char status[PARAM_VALUE_LEN_MAX] = {0}; ServiceStatus status = SERVICE_IDLE;
if (GetCurrentServiceStatus(serviceName, status, PARAM_VALUE_LEN_MAX) != 0) { if (GetCurrentServiceStatus(serviceName, &status) != 0) {
BEGET_LOGE("Get service status failed.\n"); BEGET_LOGE("Get service status failed.\n");
return -1; return -1;
} }
if (strcmp(status, "running") == 0) { if (status == SERVICE_STARTED || status == SERVICE_READY) {
if (StopProcess(serviceName) != 0) { if (StopProcess(serviceName) != 0) {
BEGET_LOGE("Stop service %s failed", serviceName); BEGET_LOGE("Stop service %s failed", serviceName);
return -1; return -1;
} }
if (ServiceWaitForStatus(serviceName, "stopped", DEFAULT_PARAM_WAIT_TIMEOUT) != 0) { if (ServiceWaitForStatus(serviceName, SERVICE_STOPPED, DEFAULT_PARAM_WAIT_TIMEOUT) != 0) {
BEGET_LOGE("Failed wait service %s stopped", serviceName); BEGET_LOGE("Failed wait service %s stopped", serviceName);
return -1; return -1;
} }
...@@ -133,13 +133,13 @@ static int RestartProcess(const char *serviceName, const char *extArgv[], int ex ...@@ -133,13 +133,13 @@ static int RestartProcess(const char *serviceName, const char *extArgv[], int ex
BEGET_LOGE("Start service %s failed", serviceName); BEGET_LOGE("Start service %s failed", serviceName);
return -1; return -1;
} }
} else if (strcmp(status, "stopped") == 0) { } else if (status != SERVICE_STARTING) {
if (StartProcess(serviceName, extArgv, extArgc) != 0) { if (StartProcess(serviceName, extArgv, extArgc) != 0) {
BEGET_LOGE("Start service %s failed", serviceName); BEGET_LOGE("Start service %s failed", serviceName);
return -1; return -1;
} }
} else { } else {
BEGET_LOGE("Current service status: %s is not support.", status); BEGET_LOGE("Current service status: %d is not support.", status);
} }
return 0; return 0;
} }
...@@ -179,22 +179,94 @@ int ServiceControl(const char *serviceName, int action) ...@@ -179,22 +179,94 @@ int ServiceControl(const char *serviceName, int action)
return ret; return ret;
} }
// Service status can set "running", "stopping", "stopped", "reseting". waitTimeout(s). int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout)
int ServiceWaitForStatus(const char *serviceName, const char *status, int waitTimeout)
{ {
if (serviceName == NULL) { char *state = NULL;
BEGET_LOGE("Service wait failed, service is null."); int size = 0;
const InitArgInfo *statusMap = GetServieStatusMap(&size);
if (((int)status < size) && (statusMap[status].value == (int)status)) {
state = statusMap[status].name;
}
if (serviceName == NULL || state == NULL || waitTimeout <= 0) {
BEGET_LOGE("Service wait failed, service name is null or status invalid %d", status);
return -1; return -1;
} }
char paramName[PARAM_NAME_LEN_MAX] = {0}; 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) { if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
STARTUP_SERVICE_CTL, serviceName) == -1) {
BEGET_LOGE("Failed snprintf_s err=%d", errno); BEGET_LOGE("Failed snprintf_s err=%d", errno);
return -1; return -1;
} }
if (SystemWaitParameter(paramName, status, waitTimeout) != 0) { if (SystemWaitParameter(paramName, state, waitTimeout) != 0) {
BEGET_LOGE("Wait param for %s failed.", paramName); BEGET_LOGE("Wait param for %s failed.", paramName);
return -1; return -1;
} }
BEGET_LOGI("Success wait"); BEGET_LOGI("Success wait");
return 0; return 0;
} }
int ServiceSetReady(const char *serviceName)
{
if (serviceName == NULL) {
BEGET_LOGE("Service wait failed, service is null.");
return -1;
}
char paramName[PARAM_NAME_LEN_MAX] = {0};
if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s.%s",
STARTUP_SERVICE_CTL, serviceName) == -1) {
BEGET_LOGE("Failed snprintf_s err=%d", errno);
return -1;
}
if (SystemSetParameter(paramName, "ready") != 0) {
BEGET_LOGE("Set param for %s failed.", paramName);
return -1;
}
BEGET_LOGI("Success set %d read", serviceName);
return 0;
}
int StartServiceByTimer(const char *serviceName, uint64_t timeout)
{
if (serviceName == NULL) {
BEGET_LOGE("Request start serivce by timer with invalid service name");
return -1;
}
if (timeout == 0) {
// start service immediately.
return ServiceControl(serviceName, START);
}
// restrict timeout value, not too long.
char value[PARAM_VALUE_LEN_MAX] = {};
if (snprintf_s(value, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "%s|%lld", serviceName, timeout) == -1) {
BEGET_LOGE("Failed to build parameter value");
return -1;
}
if (SystemSetParameter("ohos.servicectrl.timer_start", value) != 0) {
BEGET_LOGE("Failed to set parameter \' ohos.servicectrl.timer_start \' with value \' %s \'", value);
return -1;
}
return 0;
}
int StopServiceTimer(const char *serviceName)
{
if (serviceName == NULL) {
BEGET_LOGE("Request stop serivce timer with invalid service name");
return -1;
}
char value[PARAM_VALUE_LEN_MAX] = {};
int ret = strncpy_s(value, PARAM_VALUE_LEN_MAX - 1, serviceName, strlen(serviceName));
if (ret < 0) {
BEGET_LOGE("Failed to copy service name to parameter");
return -1;
}
if (SystemSetParameter("ohos.servicectrl", value) != 0) {
BEGET_LOGE("Failed to set parameter \' ohos.servicectrl.timer_stop \' with value \' %s \'", value);
return -1;
}
return 0;
}
...@@ -22,19 +22,34 @@ ...@@ -22,19 +22,34 @@
#include "beget_ext.h" #include "beget_ext.h"
#include "init_utils.h" #include "init_utils.h"
#include "securec.h" #include "securec.h"
#include "service_control.h"
int ServiceWatchForStatus(const char *serviceName, void *context, ServiceStatusChangePtr changeCallback) static void ServiceStateChange(const char *key, const char *value, void *context)
{
ServiceStatusChangePtr callback = (ServiceStatusChangePtr)context;
int size = 0;
const InitArgInfo *statusMap = GetServieStatusMap(&size);
ServiceStatus status = (ServiceStatus)GetMapValue(value, statusMap, size, SERVICE_IDLE);
if (strlen(key) > strlen(STARTUP_SERVICE_CTL)) {
callback(key + strlen(STARTUP_SERVICE_CTL), status);
} else {
BEGET_LOGE("Invalid service name %s %s", key, value);
}
}
int ServiceWatchForStatus(const char *serviceName, ServiceStatusChangePtr changeCallback)
{ {
if (serviceName == NULL) { if (serviceName == NULL) {
BEGET_LOGE("Service wait failed, service is null."); BEGET_LOGE("Service wait failed, service is null.");
return -1; return -1;
} }
char paramName[PARAM_NAME_LEN_MAX] = {0}; 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) { if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1,
"%s.%s", STARTUP_SERVICE_CTL, serviceName) == -1) {
BEGET_LOGE("Failed snprintf_s err=%d", errno); BEGET_LOGE("Failed snprintf_s err=%d", errno);
return -1; return -1;
} }
if (SystemWatchParameter(paramName, changeCallback, context) != 0) { if (SystemWatchParameter(paramName, ServiceStateChange, (void *)changeCallback) != 0) {
BEGET_LOGE("Wait param for %s failed.", paramName); BEGET_LOGE("Wait param for %s failed.", paramName);
return -1; return -1;
} }
......
...@@ -172,7 +172,14 @@ if (defined(ohos_lite)) { ...@@ -172,7 +172,14 @@ if (defined(ohos_lite)) {
cflags += [ "-DWITH_SELINUX" ] cflags += [ "-DWITH_SELINUX" ]
} }
defines = [ "OHOS_SERVICE_DUMP" ] defines = []
if (param_test) {
defines += [
"OHOS_SERVICE_DUMP",
"INIT_TEST",
]
}
if (!enable_ramdisk) { if (!enable_ramdisk) {
defines += [ "DISABLE_INIT_TWO_STAGES" ] defines += [ "DISABLE_INIT_TWO_STAGES" ]
} }
...@@ -263,9 +270,15 @@ if (defined(ohos_lite)) { ...@@ -263,9 +270,15 @@ if (defined(ohos_lite)) {
part_name = "init" part_name = "init"
} }
ohos_prebuilt_etc("charing.group") {
source = "//base/startup/init_lite/services/etc/device.charing.group.cfg"
part_name = "init"
}
group("init_etc") { group("init_etc") {
deps = [ deps = [
":boot.group", ":boot.group",
":charing.group",
":group", ":group",
":init.cfg", ":init.cfg",
":init.usb.cfg", ":init.usb.cfg",
......
...@@ -43,36 +43,14 @@ struct option g_options[] = { ...@@ -43,36 +43,14 @@ struct option g_options[] = {
static std::string GetMiscDevicePath() static std::string GetMiscDevicePath()
{ {
std::string miscDev {}; char miscDevice[PATH_MAX] = {0};
// Get misc device path from fstab int ret = GetBlockDevicePath("/misc", miscDevice, PATH_MAX);
uint32_t size = PARAM_VALUE_LEN_MAX;
std::vector<char> buffer(PARAM_VALUE_LEN_MAX);
int ret = SystemGetParameter((char *)"ohos.boot.hardware", buffer.data(), &size);
if (ret != 0) { if (ret != 0) {
std::cout << "get ohos.boot.hardware failed\n"; return std::string("");
return "";
} }
std::string hardwareVal(buffer.data()); return std::string(miscDevice);
std::string fstabFileName = std::string("fstab.") + hardwareVal;
std::string fstabFile = std::string("/vendor/etc/") + fstabFileName;
Fstab *fstab = ReadFstabFromFile(fstabFile.c_str(), false);
if (fstab == nullptr) {
std::cout << "Failed to read fstab\n";
return miscDev;
}
FstabItem *misc = FindFstabItemForMountPoint(*fstab, "/misc");
if (misc == nullptr) {
std::cout << "Cannot find misc partition from fstab\n";
ReleaseFstab(fstab);
return miscDev;
}
miscDev = misc->deviceName;
ReleaseFstab(fstab);
return miscDev;
} }
static void ClearLogo(int fd) static void ClearLogo(int fd)
{ {
if (fd < 0) { if (fd < 0) {
......
...@@ -151,11 +151,16 @@ static void ShowParam(BShellHandle shell, const char *name, const char *value) ...@@ -151,11 +151,16 @@ static void ShowParam(BShellHandle shell, const char *name, const char *value)
ParamAuditData auditData = {}; ParamAuditData auditData = {};
int ret = GetParamSecurityAuditData(name, 0, &auditData); int ret = GetParamSecurityAuditData(name, 0, &auditData);
if (ret != 0) { if (ret != 0) {
BSH_LOGE("Failed to get param security for %s", name);
return; return;
} }
char permissionStr[MASK_LENGTH_MAX] = {'-', '-', '-', 0}; char permissionStr[MASK_LENGTH_MAX] = {'-', '-', '-', 0};
struct passwd *user = getpwuid(auditData.dacData.uid); struct passwd *user = getpwuid(auditData.dacData.uid);
struct group *group = getgrgid(auditData.dacData.gid); struct group *group = getgrgid(auditData.dacData.gid);
if (user == NULL || group == NULL) {
BSH_LOGE("Failed to get group for user for %s", name);
return;
}
BShellEnvOutput(shell, "Parameter infomation:\r\n"); BShellEnvOutput(shell, "Parameter infomation:\r\n");
BShellEnvOutput(shell, " dac : %s(%s) %s(%s) (%s) \r\n", BShellEnvOutput(shell, " dac : %s(%s) %s(%s) (%s) \r\n",
user->pw_name, GetPermissionString(auditData.dacData.mode, 0, permissionStr, MASK_LENGTH_MAX), user->pw_name, GetPermissionString(auditData.dacData.mode, 0, permissionStr, MASK_LENGTH_MAX),
...@@ -346,7 +351,7 @@ static int32_t BShellParamCmdWait(BShellHandle shell, int32_t argc, char *argv[] ...@@ -346,7 +351,7 @@ static int32_t BShellParamCmdWait(BShellHandle shell, int32_t argc, char *argv[]
static int32_t BShellParamCmdDump(BShellHandle shell, int32_t argc, char *argv[]) static int32_t BShellParamCmdDump(BShellHandle shell, int32_t argc, char *argv[])
{ {
BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
if (argc > 2 && strcmp(argv[1], "verbose") == 0) { // 2 min arg if (argc >= 2 && strcmp(argv[1], "verbose") == 0) { // 2 min arg
SystemSetParameter("ohos.servicectrl.display", "system"); SystemSetParameter("ohos.servicectrl.display", "system");
SystemDumpParameters(1); SystemDumpParameters(1);
} else { } else {
......
...@@ -46,6 +46,19 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) ...@@ -46,6 +46,19 @@ static int main_cmd(BShellHandle shell, int argc, char **argv)
ServiceControlWithExtra(argv[1], 0, (const char **)argv + SERVICE_START_NUMBER, argc - SERVICE_START_NUMBER); ServiceControlWithExtra(argv[1], 0, (const char **)argv + SERVICE_START_NUMBER, argc - SERVICE_START_NUMBER);
} else if (strcmp(argv[0], "stop") == 0) { } else if (strcmp(argv[0], "stop") == 0) {
ServiceControlWithExtra(argv[1], 1, (const char **)argv + SERVICE_START_NUMBER, argc - SERVICE_START_NUMBER); ServiceControlWithExtra(argv[1], 1, (const char **)argv + SERVICE_START_NUMBER, argc - SERVICE_START_NUMBER);
} else if (strcmp(argv[0], "timer_start") == 0) {
if (argc < SERVICE_START_NUMBER) {
return -1;
}
char *timeBuffer = argv[SERVICE_START_NUMBER];
errno = 0;
uint64_t timeout = strtoull(timeBuffer, NULL, 10);
if (errno != 0) {
return -1;
}
StartServiceByTimer(argv[1], timeout);
} else if (strcmp(argv[0], "timer_stop") == 0) {
StopServiceTimer(argv[1]);
} else { } else {
ServiceControlUsage(shell, argc, argv); ServiceControlUsage(shell, argc, argv);
} }
...@@ -58,7 +71,9 @@ MODULE_CONSTRUCTOR(void) ...@@ -58,7 +71,9 @@ MODULE_CONSTRUCTOR(void)
{"service_control", main_cmd, "stop service", "service_control stop servicename", "service_control stop"}, {"service_control", main_cmd, "stop service", "service_control stop servicename", "service_control stop"},
{"service_control", main_cmd, "start service", "service_control start servicename", "service_control start"}, {"service_control", main_cmd, "start service", "service_control start servicename", "service_control start"},
{"stop_service", main_cmd, "stop service", "stop_service servicename", ""}, {"stop_service", main_cmd, "stop service", "stop_service servicename", ""},
{"start_service", main_cmd, "start service", "start_service servicename", ""} {"start_service", main_cmd, "start service", "start_service servicename", ""},
{"timer_start", main_cmd, "start service by timer", "timer_start servicename timeout", ""},
{"timer_stop", main_cmd, "stop service timer", "timer_stop servicename", ""},
}; };
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegitsterCmd(GetShellHandle(), &infos[i]); BShellEnvRegitsterCmd(GetShellHandle(), &infos[i]);
......
...@@ -56,6 +56,7 @@ BShellHandle GetShellHandle(void) ...@@ -56,6 +56,7 @@ BShellHandle GetShellHandle(void)
return g_handle; return g_handle;
} }
#ifndef STARTUP_INIT_TEST
int main(int argc, char *args[]) int main(int argc, char *args[])
{ {
(void)signal(SIGINT, signalHandler); (void)signal(SIGINT, signalHandler);
...@@ -67,6 +68,8 @@ int main(int argc, char *args[]) ...@@ -67,6 +68,8 @@ int main(int argc, char *args[])
if (tcgetattr(0, &tio)) { if (tcgetattr(0, &tio)) {
return -1; return -1;
} }
setuid(2000); // 2000 shell group
setgid(2000); // 2000 shell group
tio.c_lflag &= ~(ECHO | ICANON | ISIG); tio.c_lflag &= ~(ECHO | ICANON | ISIG);
tio.c_cc[VTIME] = 0; tio.c_cc[VTIME] = 0;
tio.c_cc[VMIN] = 1; tio.c_cc[VMIN] = 1;
...@@ -96,3 +99,4 @@ int main(int argc, char *args[]) ...@@ -96,3 +99,4 @@ int main(int argc, char *args[])
tcsetattr(0, TCSAFLUSH, &terminalState); tcsetattr(0, TCSAFLUSH, &terminalState);
return 0; return 0;
} }
#endif
{
"jobs": [],
"services": [],
"groups": []
}
\ No newline at end of file
...@@ -184,7 +184,6 @@ ...@@ -184,7 +184,6 @@
}, { }, {
"name" : "post-fs-data", "name" : "post-fs-data",
"cmds" : [ "cmds" : [
"start misc",
"chown system system /data", "chown system system /data",
"chmod 0771 /data", "chmod 0771 /data",
"mkdir /data/app 0711 root root", "mkdir /data/app 0711 root root",
...@@ -418,10 +417,23 @@ ...@@ -418,10 +417,23 @@
"name" : "boot && param:const.debuggable=1", "name" : "boot && param:const.debuggable=1",
"condition" : "boot && const.debuggable=1", "condition" : "boot && const.debuggable=1",
"cmds" : [ "cmds" : [
"chmod 0773 /data/misc/trace",
"chmod 0775 /data/misc/wmtrace",
"start console" "start console"
] ]
}, {
"name" : "services:console",
"cmds" : [
"chmod 0773 /data/misc/trace",
"chmod 0775 /data/misc/wmtrace"
]
}, {
"name" : "reboot",
"cmds" : [
"stopAllServices ",
"sync ",
"umount /vendor",
"umount /data MNT_FORCE",
"sync "
]
} }
], ],
"services" : [{ "services" : [{
...@@ -443,22 +455,29 @@ ...@@ -443,22 +455,29 @@
] ]
}], }],
"critical" : [ 0, 15, 5], "critical" : [ 0, 15, 5],
"ondemand" : true "ondemand" : true,
"start-mode" : "condition"
}, { }, {
"name" : "console", "name" : "console",
"path" : ["/system/bin/sh"], "path" : ["/system/bin/sh"],
"start-mode" : "condition",
"disabled" : 1, "disabled" : 1,
"console" : 1, "console" : 1,
"uid" : "root", "uid" : "root",
"gid" : ["shell", "log", "readproc"] "gid" : ["shell", "log", "readproc"],
"jobs" : {
"on-start" : "services:console"
}
}, { }, {
"name" : "watchdog_service", "name" : "watchdog_service",
"start-mode" : "condition",
"path" : ["/system/bin/watchdog_service", "10", "2"], "path" : ["/system/bin/watchdog_service", "10", "2"],
"disabled" : 1, "disabled" : 1,
"uid" : "root", "uid" : "root",
"gid" : ["shell", "log", "readproc"] "gid" : ["shell", "log", "readproc"]
}, { }, {
"name" : "misc", "name" : "misc",
"start-mode" : "condition",
"path" : ["/system/bin/misc_daemon", "--write_logo", "/vendor/logo.rgb"], "path" : ["/system/bin/misc_daemon", "--write_logo", "/vendor/logo.rgb"],
"once" : 1 "once" : 1
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
"uid" : "system", "uid" : "system",
"gid" : "system" "gid" : "system"
}], }],
"start-mode" : "condition",
"disabled" : 1 "disabled" : 1
} }
] ]
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
"setparam sys.usb.state ${sys.usb.config}" "setparam sys.usb.state ${sys.usb.config}"
] ]
}, { }, {
"name" : "param:init.svc.hdcd=stopped", "name" : "param:startup.service.ctl.hdcd=stopped",
"condition" : "init.svc.hdcd=stopped", "condition" : "startup.service.ctl.hdcd=stopped",
"cmds" : [ "cmds" : [
"setparam sys.usb.ffs.ready 0" "setparam sys.usb.ffs.ready 0"
] ]
......
...@@ -57,6 +57,7 @@ int InUpdaterMode(void); ...@@ -57,6 +57,7 @@ int InUpdaterMode(void);
int StringReplaceChr(char *strl, char oldChr, char newChr); int StringReplaceChr(char *strl, char oldChr, char newChr);
int GetMapValue(const char *name, const InitArgInfo *infos, int argNum, int defValue); int GetMapValue(const char *name, const InitArgInfo *infos, int argNum, int defValue);
const InitArgInfo *GetServieStatusMap(int *size);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -30,8 +30,8 @@ extern "C" { ...@@ -30,8 +30,8 @@ extern "C" {
#define GROUP_NAME_MAX_LENGTH 64 #define GROUP_NAME_MAX_LENGTH 64
#define GROUP_HASHMAP_BUCKET 32 #define GROUP_HASHMAP_BUCKET 32
#ifdef STARTUP_INIT_TEST #ifdef STARTUP_INIT_TEST
#define GROUP_DEFAULT_PATH "/home/axw/init_ut" // "/system/init" #define GROUP_DEFAULT_PATH "/data/init_ut"
#define BOOT_CMD_LINE GROUP_DEFAULT_PATH "/proc/cmdline" #define BOOT_CMD_LINE "/data/init_ut/cmdline"
#else #else
#define GROUP_DEFAULT_PATH "/system/etc" #define GROUP_DEFAULT_PATH "/system/etc"
#define BOOT_CMD_LINE "/proc/cmdline" #define BOOT_CMD_LINE "/proc/cmdline"
...@@ -42,7 +42,6 @@ extern "C" { ...@@ -42,7 +42,6 @@ extern "C" {
typedef enum { typedef enum {
GROUP_BOOT, GROUP_BOOT,
GROUP_CHARING, GROUP_CHARING,
GROUP_UPDATER,
GROUP_UNKNOW GROUP_UNKNOW
} InitGroupType; } InitGroupType;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
# include "init_selinux_param.h" # include "init_selinux_param.h"
#endif // WITH_SELINUX #endif // WITH_SELINUX
#include "list.h" #include "list.h"
#include "loop_event.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
...@@ -47,6 +48,7 @@ extern "C" { ...@@ -47,6 +48,7 @@ extern "C" {
#define SERVICE_ATTR_CONSOLE 0x080 // console #define SERVICE_ATTR_CONSOLE 0x080 // console
#define SERVICE_ATTR_DYNAMIC 0x100 // dynamic service #define SERVICE_ATTR_DYNAMIC 0x100 // dynamic service
#define SERVICE_ATTR_ONDEMAND 0x200 // ondemand, manage socket by init #define SERVICE_ATTR_ONDEMAND 0x200 // ondemand, manage socket by init
#define SERVICE_ATTR_TIMERSTART 0x400 // Mark a service will be started by timer
#define MAX_SERVICE_NAME 32 #define MAX_SERVICE_NAME 32
#define MAX_APL_NAME 32 #define MAX_APL_NAME 32
...@@ -65,6 +67,15 @@ extern "C" { ...@@ -65,6 +67,15 @@ extern "C" {
#define IsOnDemandService(service) \ #define IsOnDemandService(service) \
(((service)->attribute & SERVICE_ATTR_ONDEMAND) == SERVICE_ATTR_ONDEMAND) (((service)->attribute & SERVICE_ATTR_ONDEMAND) == SERVICE_ATTR_ONDEMAND)
#define IsServiceWithTimerEnabled(service) \
(((service)->attribute & SERVICE_ATTR_TIMERSTART) == SERVICE_ATTR_TIMERSTART)
#define DisableServiceTimer(service) \
((service)->attribute &= ~SERVICE_ATTR_TIMERSTART)
#define EnableServiceTimer(service) \
((service)->attribute |= SERVICE_ATTR_TIMERSTART)
typedef enum { typedef enum {
START_MODE_CONDITION, START_MODE_CONDITION,
START_MODE_BOOT, START_MODE_BOOT,
...@@ -122,6 +133,7 @@ typedef struct Service_ { ...@@ -122,6 +133,7 @@ typedef struct Service_ {
int importance; int importance;
int startMode : 4; // startCondition/ startBoot / startNormal int startMode : 4; // startCondition/ startBoot / startNormal
int endMode : 4; // preFork/ fork / exec / ready int endMode : 4; // preFork/ fork / exec / ready
int status : 4; // ServiceStatus
uint64_t tokenId; uint64_t tokenId;
char apl[MAX_APL_NAME + 1]; char apl[MAX_APL_NAME + 1];
ServiceArgs capsArgs; ServiceArgs capsArgs;
...@@ -134,6 +146,7 @@ typedef struct Service_ { ...@@ -134,6 +146,7 @@ typedef struct Service_ {
ServiceFile *fileCfg; ServiceFile *fileCfg;
int *fds; int *fds;
size_t fdCount; size_t fdCount;
TimerHandle timer;
ServiceJobs serviceJobs; ServiceJobs serviceJobs;
CpuArgs cpuInfo; CpuArgs cpuInfo;
} Service; } Service;
...@@ -143,7 +156,7 @@ int ServiceStop(Service *service); ...@@ -143,7 +156,7 @@ int ServiceStop(Service *service);
void ServiceReap(Service *service); void ServiceReap(Service *service);
void ReapService(Service *service); void ReapService(Service *service);
void NotifyServiceChange(const char *serviceName, const char *change); void NotifyServiceChange(Service *service, int status);
int IsForbidden(const char *fieldStr); int IsForbidden(const char *fieldStr);
int SetImportantValue(Service *curServ, const char *attrName, int value, int flag); int SetImportantValue(Service *curServ, const char *attrName, int value, int flag);
int GetServiceCaps(const cJSON *curArrItem, Service *curServ); int GetServiceCaps(const cJSON *curArrItem, Service *curServ);
...@@ -152,6 +165,8 @@ void CloseServiceFds(Service *service, bool needFree); ...@@ -152,6 +165,8 @@ void CloseServiceFds(Service *service, bool needFree);
int UpdaterServiceFds(Service *service, int *fds, size_t fdCount); int UpdaterServiceFds(Service *service, int *fds, size_t fdCount);
int SetAccessToken(const Service *service); int SetAccessToken(const Service *service);
void GetAccessToken(void); void GetAccessToken(void);
void ServiceStopTimer(Service *service);
void ServiceStartTimer(Service *service, uint64_t timeout);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
...@@ -55,11 +55,14 @@ int ParseOneService(const cJSON *curItem, Service *service); ...@@ -55,11 +55,14 @@ int ParseOneService(const cJSON *curItem, Service *service);
void StartServiceByName(const char *serviceName, bool checkDynamic); void StartServiceByName(const char *serviceName, bool checkDynamic);
void StopServiceByName(const char *serviceName); void StopServiceByName(const char *serviceName);
void StopAllServices(int flags); void StopAllServices(int flags, const char **exclude, int size,
int (*filter)(const Service *service, const char **exclude, int size));
void ParseAllServices(const cJSON *fileRoot); void ParseAllServices(const cJSON *fileRoot);
void ReleaseService(Service *service); void ReleaseService(Service *service);
void StartAllServices(int startMode); void StartAllServices(int startMode);
void LoadAccessTokenId(void); void LoadAccessTokenId(void);
Service *AddService(const char *name);
#ifdef OHOS_SERVICE_DUMP #ifdef OHOS_SERVICE_DUMP
void DumpAllServices(); void DumpAllServices();
#endif #endif
......
...@@ -40,7 +40,9 @@ ...@@ -40,7 +40,9 @@
#include "init_service_socket.h" #include "init_service_socket.h"
#include "init_utils.h" #include "init_utils.h"
#include "fd_holder_internal.h" #include "fd_holder_internal.h"
#include "loop_event.h"
#include "securec.h" #include "securec.h"
#include "service_control.h"
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
#include "init_selinux_param.h" #include "init_selinux_param.h"
...@@ -212,8 +214,15 @@ static void PublishHoldFds(Service *service) ...@@ -212,8 +214,15 @@ static void PublishHoldFds(Service *service)
if (service->fdCount > 0 && service->fds != NULL) { if (service->fdCount > 0 && service->fds != NULL) {
size_t pos = 0; size_t pos = 0;
for (size_t i = 0; i < service->fdCount; i++) { for (size_t i = 0; i < service->fdCount; i++) {
(void)snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, int fd = dup(service->fds[i]);
"%d ", service->fds[i]); if (fd < 0) {
INIT_LOGE("Duplicate file descriptors of Service \' %s \' failed. err = %d", service->name, errno);
continue;
}
if (snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, "%d ", fd) < 0) {
INIT_LOGE("snprintf_s failed err=%d", errno);
return;
}
pos = strlen(fdBuffer); pos = strlen(fdBuffer);
} }
fdBuffer[pos - 1] = '\0'; // Remove last ' ' fdBuffer[pos - 1] = '\0'; // Remove last ' '
...@@ -299,7 +308,7 @@ int ServiceStart(Service *service) ...@@ -299,7 +308,7 @@ int ServiceStart(Service *service)
DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]); DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
} }
(void)ClearEnvironment(); ClearEnvironment();
if (!IsOnDemandService(service)) { if (!IsOnDemandService(service)) {
int ret = CreateServiceSocket(service); int ret = CreateServiceSocket(service);
...@@ -329,7 +338,7 @@ int ServiceStart(Service *service) ...@@ -329,7 +338,7 @@ int ServiceStart(Service *service)
} }
INIT_LOGI("service %s starting pid %d", service->name, pid); INIT_LOGI("service %s starting pid %d", service->name, pid);
service->pid = pid; service->pid = pid;
NotifyServiceChange(service->name, "running"); NotifyServiceChange(service, SERVICE_STARTED);
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
...@@ -351,9 +360,13 @@ int ServiceStop(Service *service) ...@@ -351,9 +360,13 @@ int ServiceStop(Service *service)
if (service->fdCount != 0) { if (service->fdCount != 0) {
CloseServiceFds(service, true); CloseServiceFds(service, true);
} }
if (IsServiceWithTimerEnabled(service)) {
ServiceStopTimer(service);
}
INIT_ERROR_CHECK(kill(service->pid, SIGKILL) == 0, return SERVICE_FAILURE, INIT_ERROR_CHECK(kill(service->pid, SIGKILL) == 0, return SERVICE_FAILURE,
"stop service %s pid %d failed! err %d.", service->name, service->pid, errno); "stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
NotifyServiceChange(service->name, "stopping"); NotifyServiceChange(service, SERVICE_STOPPING);
INIT_LOGI("stop service %s, pid %d.", service->name, service->pid); INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
...@@ -381,16 +394,18 @@ static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCo ...@@ -381,16 +394,18 @@ static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCo
return true; return true;
} }
static int ExecRestartCmd(const Service *service) static int ExecRestartCmd(Service *service)
{ {
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr."); INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
INIT_ERROR_CHECK(service->restartArg != NULL, return SERVICE_FAILURE, "restartArg is null"); if (service->restartArg == NULL) {
return SERVICE_SUCCESS;
}
for (int i = 0; i < service->restartArg->cmdNum; i++) { for (int i = 0; i < service->restartArg->cmdNum; i++) {
INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent); INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent); DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent);
} }
free(service->restartArg); free(service->restartArg);
service->restartArg = NULL;
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
...@@ -417,13 +432,18 @@ void ServiceReap(Service *service) ...@@ -417,13 +432,18 @@ void ServiceReap(Service *service)
INIT_CHECK(service != NULL, return); INIT_CHECK(service != NULL, return);
INIT_LOGI("Reap service %s, pid %d.", service->name, service->pid); INIT_LOGI("Reap service %s, pid %d.", service->name, service->pid);
service->pid = -1; service->pid = -1;
NotifyServiceChange(service->name, "stopped"); NotifyServiceChange(service, SERVICE_STOPPED);
if (service->attribute & SERVICE_ATTR_INVALID) { if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("Reap service %s invalid.", service->name); INIT_LOGE("Reap service %s invalid.", service->name);
return; return;
} }
// If the service set timer
// which means the timer handler will start the service
// Init should not start it automatically.
INIT_CHECK(IsServiceWithTimerEnabled(service) == 0, return);
if (!IsOnDemandService(service)) { if (!IsOnDemandService(service)) {
CloseServiceSocket(service); CloseServiceSocket(service);
} }
...@@ -463,15 +483,14 @@ void ServiceReap(Service *service) ...@@ -463,15 +483,14 @@ void ServiceReap(Service *service)
return; return;
} }
int ret; int ret = ExecRestartCmd(service);
if (service->restartArg != NULL) { INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "Failed to exec restartArg for %s", service->name);
ret = ExecRestartCmd(service);
INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "Failed to exec restartArg for %s", service->name); if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
} }
ret = ServiceStart(service); ret = ServiceStart(service);
if (ret != SERVICE_SUCCESS) { INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "reap service %s start failed!", service->name);
INIT_LOGE("reap service %s start failed!", service->name);
}
service->attribute &= (~SERVICE_ATTR_NEED_RESTART); service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
} }
...@@ -535,3 +554,63 @@ int UpdaterServiceFds(Service *service, int *fds, size_t fdCount) ...@@ -535,3 +554,63 @@ int UpdaterServiceFds(Service *service, int *fds, size_t fdCount)
INIT_LOGI("Hold fd for service \' %s \' done", service->name); INIT_LOGI("Hold fd for service \' %s \' done", service->name);
return ret; return ret;
} }
void ServiceStopTimer(Service *service)
{
INIT_ERROR_CHECK(service != NULL, return, "Stop timer with invalid service");
if (IsServiceWithTimerEnabled(service)) {
// Stop timer first
if (service->timer) {
LE_StopTimer(LE_GetDefaultLoop(), service->timer);
}
service->timer = NULL;
DisableServiceTimer(service);
}
}
static void ServiceTimerStartProcess(const TimerHandle handler, void *context)
{
UNUSED(handler);
Service *service = (Service *)context;
if (service == NULL) {
INIT_LOGE("Service timer process with invalid service");
return;
}
// OK, service is ready to start.
// Before start the service, stop service timer.
// make sure it will not enter timer handler next time.
ServiceStopTimer(service);
int ret = ServiceStart(service);
if (ret != SERVICE_SUCCESS) {
INIT_LOGE("Start service \' %s \' in timer failed");
}
}
void ServiceStartTimer(Service *service, uint64_t timeout)
{
bool oldTimerClean = false;
INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
// If the service already set a timer.
// And a new request coming. close it and create a new one.
if (IsServiceWithTimerEnabled(service)) {
ServiceStopTimer(service);
oldTimerClean = true;
}
LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerStartProcess,
(void *)service);
if (status != LE_SUCCESS) {
INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
if (oldTimerClean) {
INIT_LOGE("previous timer is cleared");
}
return;
}
status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
if (status != LE_SUCCESS) {
INIT_LOGE("Start service timer for service \' %s \' failed, status = %d", service->name, status);
return;
}
EnableServiceTimer(service);
}
...@@ -32,8 +32,17 @@ static void ParseInitCfgContents(const char *cfgName, const cJSON *root) ...@@ -32,8 +32,17 @@ static void ParseInitCfgContents(const char *cfgName, const cJSON *root)
int ParseInitCfg(const char *configFile, void *context) int ParseInitCfg(const char *configFile, void *context)
{ {
INIT_LOGI("ParseInitCfg %s", configFile);
UNUSED(context); UNUSED(context);
INIT_LOGI("ParseInitCfg %s", configFile);
static const char *excludeCfg[] = {
"/system/etc/init/weston.cfg"
};
for (int i = 0; i < (int)ARRAY_LENGTH(excludeCfg); i++) {
if (strcmp(configFile, excludeCfg[i]) == 0) {
INIT_LOGE("ParseInitCfg %s not support", configFile);
return 0;
}
}
char *fileBuf = ReadFileToBuf(configFile); char *fileBuf = ReadFileToBuf(configFile);
INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", configFile); INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", configFile);
...@@ -87,6 +96,7 @@ void ReadConfig(void) ...@@ -87,6 +96,7 @@ void ReadConfig(void)
if (InUpdaterMode() == 0) { if (InUpdaterMode() == 0) {
ParseInitCfg(INIT_CONFIGURATION_FILE, NULL); ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
ReadFileInDir(OTHER_CFG_PATH, ".cfg", ParseInitCfg, NULL); ReadFileInDir(OTHER_CFG_PATH, ".cfg", ParseInitCfg, NULL);
ReadFileInDir("/vendor/etc/init", ".cfg", ParseInitCfg, NULL);
} else { } else {
ReadFileInDir("/etc", ".cfg", ParseInitCfg, NULL); ReadFileInDir("/etc", ".cfg", ParseInitCfg, NULL);
} }
......
...@@ -34,15 +34,14 @@ static int GetBootGroupMode(void) ...@@ -34,15 +34,14 @@ static int GetBootGroupMode(void)
{ {
static const char *groupModes[] = { static const char *groupModes[] = {
"device.boot.group", "device.boot.group",
"device.charing.group", "device.charing.group"
"device.updater.group"
}; };
for (size_t i = 0; i < ARRAY_LENGTH(groupModes); i++) { for (size_t i = 0; i < ARRAY_LENGTH(groupModes); i++) {
if (strcmp(g_initWorkspace.groupModeStr, groupModes[i]) == 0) { if (strcmp(g_initWorkspace.groupModeStr, groupModes[i]) == 0) {
return i; return i;
} }
} }
return (int)GROUP_BOOT; return (int)GROUP_UNKNOW;
} }
static int ParseGroupCfgItem(cJSON *root, int type, const char *itemName) static int ParseGroupCfgItem(cJSON *root, int type, const char *itemName)
...@@ -65,7 +64,7 @@ static int ParseGroupCfgItem(cJSON *root, int type, const char *itemName) ...@@ -65,7 +64,7 @@ static int ParseGroupCfgItem(cJSON *root, int type, const char *itemName)
static int InitParseGroupCfg_(const char *groupCfg) static int InitParseGroupCfg_(const char *groupCfg)
{ {
INIT_LOGV("parse group config %s", groupCfg); INIT_LOGI("Parse group config %s", groupCfg);
char *fileBuf = ReadFileToBuf(groupCfg); char *fileBuf = ReadFileToBuf(groupCfg);
INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", groupCfg); INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", groupCfg);
cJSON *fileRoot = cJSON_Parse(fileBuf); cJSON *fileRoot = cJSON_Parse(fileBuf);
...@@ -115,10 +114,10 @@ static char *GetAbsolutePath(const char *path, const char *cfgName, char *buffer ...@@ -115,10 +114,10 @@ static char *GetAbsolutePath(const char *path, const char *cfgName, char *buffer
ext = strcmp(cfgName + cfgNameLen - strlen(".cfg"), ".cfg") == 0; ext = strcmp(cfgName + cfgNameLen - strlen(".cfg"), ".cfg") == 0;
} }
if (cfgName[0] != '/') { if (cfgName[0] != '/') {
const char *format = ext != 0 ? "%s/%s" : "%s/%s.cfg"; const char *format = (ext != 0) ? "%s/%s" : "%s/%s.cfg";
len = sprintf_s(buffer, buffSize, format, path, cfgName); len = sprintf_s(buffer, buffSize, format, path, cfgName);
} else { } else {
const char *format = ext != 0 ? "%s" : "%s.cfg"; const char *format = (ext != 0) ? "%s" : "%s.cfg";
len = sprintf_s(buffer, buffSize, format, cfgName); len = sprintf_s(buffer, buffSize, format, cfgName);
} }
if (len <= 0) { if (len <= 0) {
...@@ -176,7 +175,6 @@ void InitServiceSpace(void) ...@@ -176,7 +175,6 @@ void InitServiceSpace(void)
if (ret != 0) { if (ret != 0) {
INIT_LOGE("%s", "Failed to create hash map"); INIT_LOGE("%s", "Failed to create hash map");
} }
INIT_LOGI("HashMapCreate %p", g_initWorkspace.hashMap[i]);
} }
for (int i = 0; i < NODE_TYPE_MAX; i++) { for (int i = 0; i < NODE_TYPE_MAX; i++) {
...@@ -203,10 +201,12 @@ int InitParseGroupCfg(void) ...@@ -203,10 +201,12 @@ int InitParseGroupCfg(void)
char buffer[128] = {0}; // 128 buffer size char buffer[128] = {0}; // 128 buffer size
char *realPath = GetAbsolutePath(GROUP_DEFAULT_PATH, char *realPath = GetAbsolutePath(GROUP_DEFAULT_PATH,
g_initWorkspace.groupModeStr, buffer, sizeof(buffer)); g_initWorkspace.groupModeStr, buffer, sizeof(buffer));
INIT_ERROR_CHECK(realPath != NULL, return -1,
"Failed to get path for %s", g_initWorkspace.groupModeStr);
InitParseGroupCfg_(realPath); InitParseGroupCfg_(realPath);
InitGroupNode *groupRoot = g_initWorkspace.groupNodes[NODE_TYPE_GROUPS]; InitGroupNode *groupRoot = g_initWorkspace.groupNodes[NODE_TYPE_GROUPS];
int level = 0; int level = 0;
while (groupRoot != NULL && level < GROUP_IMPORT_MAX_LEVEL) { // for more import while ((groupRoot != NULL) && (level < GROUP_IMPORT_MAX_LEVEL)) { // for more import
g_initWorkspace.groupNodes[NODE_TYPE_GROUPS] = NULL; g_initWorkspace.groupNodes[NODE_TYPE_GROUPS] = NULL;
InitImportGroupCfg_(groupRoot); InitImportGroupCfg_(groupRoot);
groupRoot = g_initWorkspace.groupNodes[NODE_TYPE_GROUPS]; groupRoot = g_initWorkspace.groupNodes[NODE_TYPE_GROUPS];
...@@ -294,6 +294,7 @@ int CheckNodeValid(int type, const char *name) ...@@ -294,6 +294,7 @@ int CheckNodeValid(int type, const char *name)
if (type >= NODE_TYPE_GROUPS) { if (type >= NODE_TYPE_GROUPS) {
return -1; return -1;
} }
#ifndef INIT_TEST
if (g_initWorkspace.groupMode == GROUP_BOOT) { if (g_initWorkspace.groupMode == GROUP_BOOT) {
return 0; return 0;
} }
...@@ -301,6 +302,16 @@ int CheckNodeValid(int type, const char *name) ...@@ -301,6 +302,16 @@ int CheckNodeValid(int type, const char *name)
if (node != NULL) { if (node != NULL) {
return 0; return 0;
} }
#else
HashNode *node = HashMapGet(g_initWorkspace.hashMap[type], name);
if (node != NULL) {
INIT_LOGI("Found %s in %s group", name, type == NODE_TYPE_JOBS ? "job" : "service");
return 0;
}
if (g_initWorkspace.groupMode == GROUP_BOOT) {
return 0;
}
#endif
return -1; return -1;
} }
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include "init_service_socket.h" #include "init_service_socket.h"
#include "init_utils.h" #include "init_utils.h"
#include "securec.h" #include "securec.h"
#include "service_control.h"
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
# include "init_selinux_param.h" # include "init_selinux_param.h"
#endif // WITH_SELINUX #endif // WITH_SELINUX
...@@ -43,7 +45,7 @@ static const int CRITICAL_CONFIG_ARRAY_LEN = 3; ...@@ -43,7 +45,7 @@ static const int CRITICAL_CONFIG_ARRAY_LEN = 3;
#ifdef OHOS_SERVICE_DUMP #ifdef OHOS_SERVICE_DUMP
static void DumpServiceArgs(const char *info, const ServiceArgs *args) static void DumpServiceArgs(const char *info, const ServiceArgs *args)
{ {
INIT_LOGI("\t\t%s count %d", info, args->count); INIT_LOGI("\tservice %s count %d", info, args->count);
for (int j = 0; j < args->count; j++) { for (int j = 0; j < args->count; j++) {
if (args->argv[j] != NULL) { if (args->argv[j] != NULL) {
INIT_LOGI("\t\tinfo [%d] %s", j, args->argv[j]); INIT_LOGI("\t\tinfo [%d] %s", j, args->argv[j]);
...@@ -51,8 +53,45 @@ static void DumpServiceArgs(const char *info, const ServiceArgs *args) ...@@ -51,8 +53,45 @@ static void DumpServiceArgs(const char *info, const ServiceArgs *args)
} }
} }
static void DumpServiceJobs(const Service *service)
{
INIT_LOGI("\tservice job info");
if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) {
INIT_LOGI("\t\tservice boot job %s", service->serviceJobs.jobsName[JOB_ON_BOOT]);
}
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
INIT_LOGI("\t\tservice start job %s", service->serviceJobs.jobsName[JOB_ON_START]);
}
if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
INIT_LOGI("\t\tservice stop job %s", service->serviceJobs.jobsName[JOB_ON_STOP]);
}
if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
INIT_LOGI("\t\tservice restart job %s", service->serviceJobs.jobsName[JOB_ON_RESTART]);
}
}
static void DumpServiceSocket(const Service *service)
{
INIT_LOGI("\tservice socket info");
ServiceSocket *sockopt = service->socketCfg;
while (sockopt != NULL) {
INIT_LOGI("\t\tsocket name: %s", sockopt->name);
INIT_LOGI("\t\tsocket type: %d", sockopt->type);
INIT_LOGI("\t\tsocket uid: %d", sockopt->uid);
INIT_LOGI("\t\tsocket gid: %d", sockopt->gid);
sockopt = sockopt->next;
}
}
void DumpAllServices() void DumpAllServices()
{ {
const InitArgInfo startModeMap[] = {
{"condition", START_MODE_CONDITION},
{"boot", START_MODE_BOOT},
{"normal", START_MODE_NARMAL}
};
int size = 0;
const InitArgInfo *statusMap = GetServieStatusMap(&size);
INIT_LOGI("Ready to dump all services:"); INIT_LOGI("Ready to dump all services:");
INIT_LOGI("total service number: %d", g_serviceSpace.serviceCount); INIT_LOGI("total service number: %d", g_serviceSpace.serviceCount);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL); InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
...@@ -67,31 +106,22 @@ void DumpAllServices() ...@@ -67,31 +106,22 @@ void DumpAllServices()
INIT_LOGI("\tservice crashCnt: [%d]", service->crashCnt); INIT_LOGI("\tservice crashCnt: [%d]", service->crashCnt);
INIT_LOGI("\tservice attribute: [%d]", service->attribute); INIT_LOGI("\tservice attribute: [%d]", service->attribute);
INIT_LOGI("\tservice importance: [%d]", service->importance); INIT_LOGI("\tservice importance: [%d]", service->importance);
INIT_LOGI("\tservice startMode: [%s]", startModeMap[service->status].name);
INIT_LOGI("\tservice status: [%s]", statusMap[service->status].name);
INIT_LOGI("\tservice perms uID [%d]", service->servPerm.uID); INIT_LOGI("\tservice perms uID [%d]", service->servPerm.uID);
DumpServiceArgs("path arg", &service->pathArgs); DumpServiceArgs("path arg", &service->pathArgs);
DumpServiceArgs("writepid file", &service->writePidArgs); DumpServiceArgs("writepid file", &service->writePidArgs);
DumpServiceJobs(service);
DumpServiceSocket(service);
INIT_LOGI("\tservice perms groupId %d", service->servPerm.gIDCnt); INIT_LOGI("\tservice perms groupId %d", service->servPerm.gIDCnt);
for (int i = 0; i < service->servPerm.gIDCnt; i++) { for (int i = 0; i < service->servPerm.gIDCnt; i++) {
INIT_LOGI("\t\tservice perms groupId %d", service->servPerm.gIDArray[i]); INIT_LOGI("\t\tservice perms groupId %d", service->servPerm.gIDArray[i]);
} }
INIT_LOGI("\tservice perms capability %d", service->servPerm.capsCnt); INIT_LOGI("\tservice perms capability %d", service->servPerm.capsCnt);
for (int i = 0; i < (int)service->servPerm.capsCnt; i++) { for (int i = 0; i < (int)service->servPerm.capsCnt; i++) {
INIT_LOGI("\t\tservice perms capability %d", service->servPerm.caps[i]); INIT_LOGI("\t\tservice perms capability %d", service->servPerm.caps[i]);
} }
if (service->restartArg != NULL) {
for (int j = 0; j < service->restartArg->cmdNum; j++) {
CmdLine *cmd = &service->restartArg->cmds[j];
INIT_LOGI("\t\tcmd arg: %s %s", GetCmdKey(cmd->cmdIndex), cmd->cmdContent);
}
}
if (service->socketCfg != NULL) {
INIT_LOGI("\tservice socket name: %s", service->socketCfg->name);
INIT_LOGI("\tservice socket type: %d", service->socketCfg->type);
INIT_LOGI("\tservice socket uid: %d", service->socketCfg->uid);
INIT_LOGI("\tservice socket gid: %d", service->socketCfg->gid);
}
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
} }
INIT_LOGI("Dump all services finished"); INIT_LOGI("Dump all services finished");
...@@ -128,20 +158,23 @@ static void FreeServiceSocket(ServiceSocket *sockopt) ...@@ -128,20 +158,23 @@ static void FreeServiceSocket(ServiceSocket *sockopt)
return; return;
} }
static Service *AddService(const char *name) Service *AddService(const char *name)
{ {
// check service in group // check service in group
if (CheckNodeValid(NODE_TYPE_SERVICES, name) != 0) { if (CheckNodeValid(NODE_TYPE_SERVICES, name) != 0) {
INIT_LOGI("Service %s not exist in group ", name);
return NULL; return NULL;
} }
InitGroupNode *node = AddGroupNode(NODE_TYPE_SERVICES, name); InitGroupNode *node = AddGroupNode(NODE_TYPE_SERVICES, name);
if (node == NULL) { if (node == NULL) {
INIT_LOGE("Failed to create service name %s", name);
return NULL; return NULL;
} }
Service *service = (Service *)calloc(1, sizeof(Service)); Service *service = (Service *)calloc(1, sizeof(Service));
INIT_ERROR_CHECK(service != NULL, return NULL, "Failed to malloc for service"); INIT_ERROR_CHECK(service != NULL, return NULL, "Failed to malloc for service");
node->data.service = service; node->data.service = service;
service->name = node->name; service->name = node->name;
service->status = SERVICE_IDLE;
g_serviceSpace.serviceCount++; g_serviceSpace.serviceCount++;
INIT_LOGV("AddService %s", node->name); INIT_LOGV("AddService %s", node->name);
return service; return service;
...@@ -597,6 +630,10 @@ static int GetServiceOnDemand(const cJSON *curArrItem, Service *curServ) ...@@ -597,6 +630,10 @@ static int GetServiceOnDemand(const cJSON *curArrItem, Service *curServ)
bool isOnDemand = (bool)cJSON_GetNumberValue(item); bool isOnDemand = (bool)cJSON_GetNumberValue(item);
INIT_INFO_CHECK(isOnDemand, return SERVICE_SUCCESS, INIT_INFO_CHECK(isOnDemand, return SERVICE_SUCCESS,
"Service : %s ondemand value is false, it will be manage socket by itself", curServ->name); "Service : %s ondemand value is false, it will be manage socket by itself", curServ->name);
if (curServ->attribute & SERVICE_ATTR_CRITICAL) {
INIT_LOGE("Service : %s is invalid which has both critical and ondemand attribute", curServ->name);
return SERVICE_FAILURE;
}
curServ->attribute |= SERVICE_ATTR_ONDEMAND; curServ->attribute |= SERVICE_ATTR_ONDEMAND;
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
...@@ -651,12 +688,12 @@ static int GetServiceMode(Service *service, const cJSON *json) ...@@ -651,12 +688,12 @@ static int GetServiceMode(Service *service, const cJSON *json)
char *value = cJSON_GetStringValue(cJSON_GetObjectItem(json, "start-mode")); char *value = cJSON_GetStringValue(cJSON_GetObjectItem(json, "start-mode"));
if (value != NULL) { if (value != NULL) {
service->startMode = GetMapValue(value, service->startMode = GetMapValue(value,
(InitArgInfo *)&startModeMap, (int)ARRAY_LENGTH(startModeMap), START_MODE_NARMAL); (InitArgInfo *)startModeMap, (int)ARRAY_LENGTH(startModeMap), START_MODE_NARMAL);
} }
value = cJSON_GetStringValue(cJSON_GetObjectItem(json, "end-mode")); value = cJSON_GetStringValue(cJSON_GetObjectItem(json, "end-mode"));
if (value != NULL) { if (value != NULL) {
service->endMode = GetMapValue(value, service->endMode = GetMapValue(value,
(InitArgInfo *)&endModeMap, (int)ARRAY_LENGTH(endModeMap), END_AFTER_EXEC); (InitArgInfo *)endModeMap, (int)ARRAY_LENGTH(endModeMap), END_AFTER_EXEC);
} }
return 0; return 0;
} }
...@@ -670,6 +707,8 @@ static int GetServiceJobs(Service *service, cJSON *json) ...@@ -670,6 +707,8 @@ static int GetServiceJobs(Service *service, cJSON *json)
char *jobName = cJSON_GetStringValue(cJSON_GetObjectItem(json, jobTypes[i])); char *jobName = cJSON_GetStringValue(cJSON_GetObjectItem(json, jobTypes[i]));
if (jobName != NULL) { if (jobName != NULL) {
service->serviceJobs.jobsName[i] = strdup(jobName); service->serviceJobs.jobsName[i] = strdup(jobName);
// save job name for group job check
AddGroupNode(NODE_TYPE_JOBS, jobName);
} }
} }
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
...@@ -916,7 +955,7 @@ void StartServiceByName(const char *servName, bool checkDynamic) ...@@ -916,7 +955,7 @@ void StartServiceByName(const char *servName, bool checkDynamic)
if (checkDynamic && (service->attribute & SERVICE_ATTR_DYNAMIC)) { if (checkDynamic && (service->attribute & SERVICE_ATTR_DYNAMIC)) {
INIT_LOGI("%s is dynamic service.", servName); INIT_LOGI("%s is dynamic service.", servName);
NotifyServiceChange(servName, "stopped"); NotifyServiceChange(service, SERVICE_STOPPED);
return; return;
} }
if (ServiceStart(service) != SERVICE_SUCCESS) { if (ServiceStart(service) != SERVICE_SUCCESS) {
...@@ -940,17 +979,25 @@ void StopServiceByName(const char *servName) ...@@ -940,17 +979,25 @@ void StopServiceByName(const char *servName)
return; return;
} }
void StopAllServices(int flags) void StopAllServices(int flags, const char **exclude, int size,
int (*filter)(const Service *service, const char **exclude, int size))
{ {
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL); InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) { while (node != NULL) {
Service *service = node->data.service; Service *service = node->data.service;
if (service != NULL) { if (service == NULL) {
service->attribute |= flags; node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
int ret = ServiceStop(service); continue;
if (ret != SERVICE_SUCCESS) { }
INIT_LOGE("Service %s stop failed!", service->name); INIT_LOGI("StopAllServices stop service %s ", service->name);
} if (filter != NULL && filter(service, exclude, size) != 0) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
service->attribute |= flags;
int ret = ServiceStop(service);
if (ret != SERVICE_SUCCESS) {
INIT_LOGE("Service %s stop failed!", service->name);
} }
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
} }
...@@ -982,7 +1029,6 @@ Service *GetServiceByName(const char *servName) ...@@ -982,7 +1029,6 @@ Service *GetServiceByName(const char *servName)
void StartAllServices(int startMode) void StartAllServices(int startMode)
{ {
INIT_LOGI("StartAllServices %d", startMode); INIT_LOGI("StartAllServices %d", startMode);
#ifdef SUPPORT_GROUP_SERVICE_START
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL); InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) { while (node != NULL) {
Service *service = node->data.service; Service *service = node->data.service;
...@@ -999,7 +1045,7 @@ void StartAllServices(int startMode) ...@@ -999,7 +1045,7 @@ void StartAllServices(int startMode)
} }
if (service->attribute & SERVICE_ATTR_DYNAMIC) { if (service->attribute & SERVICE_ATTR_DYNAMIC) {
INIT_LOGI("%s is dynamic service.", service->name); INIT_LOGI("%s is dynamic service.", service->name);
NotifyServiceChange(service->name, "stopped"); NotifyServiceChange(service, SERVICE_STOPPED);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue; continue;
} }
...@@ -1008,7 +1054,6 @@ void StartAllServices(int startMode) ...@@ -1008,7 +1054,6 @@ void StartAllServices(int startMode)
} }
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
} }
#endif
INIT_LOGI("StartAllServices %d finsh", startMode); INIT_LOGI("StartAllServices %d finsh", startMode);
} }
......
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
#include "init_service_manager.h" #include "init_service_manager.h"
#include "securec.h" #include "securec.h"
void NotifyServiceChange(const char *serviceName, const char *change) void NotifyServiceChange(Service *service, int status)
{ {
UNUSED(serviceName); UNUSED(service);
UNUSED(change); UNUSED(status);
} }
int IsForbidden(const char *fieldStr) int IsForbidden(const char *fieldStr)
......
...@@ -26,7 +26,7 @@ void ReapService(Service *service) ...@@ -26,7 +26,7 @@ void ReapService(Service *service)
if (service->attribute & SERVICE_ATTR_IMPORTANT) { if (service->attribute & SERVICE_ATTR_IMPORTANT) {
// important process exit, need to reboot system // important process exit, need to reboot system
service->pid = -1; service->pid = -1;
StopAllServices(0); StopAllServices(0, NULL, 0, NULL);
RebootSystem(); RebootSystem();
} }
ServiceReap(service); ServiceReap(service);
...@@ -49,7 +49,7 @@ static void SigHandler(int sig) ...@@ -49,7 +49,7 @@ static void SigHandler(int sig)
break; break;
} }
case SIGTERM: { case SIGTERM: {
StopAllServices(0); StopAllServices(0, NULL, 0, NULL);
break; break;
} }
default: default:
......
...@@ -33,10 +33,13 @@ int main(int argc, char * const argv[]) ...@@ -33,10 +33,13 @@ int main(int argc, char * const argv[])
INIT_LOGE("Process id error %d!", getpid()); INIT_LOGE("Process id error %d!", getpid());
return 0; return 0;
} }
LogInit();
if (isSecondStage == 0) { if (isSecondStage == 0) {
SystemPrepare(); SystemPrepare();
} else {
LogInit();
} }
LogInit();
(void)AtlibInit(); (void)AtlibInit();
SystemInit(); SystemInit();
SystemExecuteRcs(); SystemExecuteRcs();
......
...@@ -121,8 +121,6 @@ void LogInit(void) ...@@ -121,8 +121,6 @@ void LogInit(void)
} }
} }
#ifndef DISABLE_INIT_TWO_STAGES
static char **GetRequiredDevices(Fstab fstab, int *requiredNum) static char **GetRequiredDevices(Fstab fstab, int *requiredNum)
{ {
int num = 0; int num = 0;
...@@ -167,6 +165,9 @@ static void StartInitSecondStage(void) ...@@ -167,6 +165,9 @@ static void StartInitSecondStage(void)
{ {
const char *fstabFile = "/etc/fstab.required"; const char *fstabFile = "/etc/fstab.required";
Fstab *fstab = NULL; Fstab *fstab = NULL;
if (access(fstabFile, F_OK) != 0) {
fstabFile = "/system/etc/fstab.required";
}
INIT_ERROR_CHECK(access(fstabFile, F_OK) == 0, abort(), "Failed get fstab.required"); INIT_ERROR_CHECK(access(fstabFile, F_OK) == 0, abort(), "Failed get fstab.required");
fstab = ReadFstabFromFile(fstabFile, false); fstab = ReadFstabFromFile(fstabFile, false);
INIT_ERROR_CHECK(fstab != NULL, abort(), "Read fstab file \" %s \" failed\n", fstabFile); INIT_ERROR_CHECK(fstab != NULL, abort(), "Read fstab file \" %s \" failed\n", fstabFile);
...@@ -186,10 +187,13 @@ static void StartInitSecondStage(void) ...@@ -186,10 +187,13 @@ static void StartInitSecondStage(void)
// If mount required partitions failure. // If mount required partitions failure.
// There is no necessary to continue. // There is no necessary to continue.
// Just abort // Just abort
INIT_LOGE("Mount requried partitions failed"); INIT_LOGE("Mount requried partitions failed; please check fstab file");
// Execute sh for debugging
execv("/bin/sh", NULL);
abort(); abort();
} }
} }
#ifndef DISABLE_INIT_TWO_STAGES
SwitchRoot("/usr"); SwitchRoot("/usr");
// Execute init second stage // Execute init second stage
char * const args[] = { char * const args[] = {
...@@ -201,16 +205,16 @@ static void StartInitSecondStage(void) ...@@ -201,16 +205,16 @@ static void StartInitSecondStage(void)
INIT_LOGE("Failed to exec \"/bin/init\", err = %d", errno); INIT_LOGE("Failed to exec \"/bin/init\", err = %d", errno);
exit(-1); exit(-1);
} }
}
#endif #endif
}
void SystemPrepare(void) void SystemPrepare(void)
{ {
MountBasicFs(); MountBasicFs();
LogInit();
// Make sure init log always output to /dev/kmsg. // Make sure init log always output to /dev/kmsg.
EnableDevKmsg(); EnableDevKmsg();
CreateDeviceNode(); CreateDeviceNode();
#ifndef DISABLE_INIT_TWO_STAGES
// Only ohos normal system support // Only ohos normal system support
// two stages of init. // two stages of init.
// If we are in updater mode, only one stage of init, // If we are in updater mode, only one stage of init,
...@@ -218,9 +222,6 @@ void SystemPrepare(void) ...@@ -218,9 +222,6 @@ void SystemPrepare(void)
if (InUpdaterMode() == 0) { if (InUpdaterMode() == 0) {
StartInitSecondStage(); StartInitSecondStage();
} }
#else
INIT_LOGI("DISABLE_INIT_TWO_STAGES defined");
#endif
} }
void SystemLoadSelinux(void) void SystemLoadSelinux(void)
...@@ -241,7 +242,12 @@ static void BootStateChange(const char *content) ...@@ -241,7 +242,12 @@ static void BootStateChange(const char *content)
{ {
INIT_LOGI("boot start %s finish.", content); INIT_LOGI("boot start %s finish.", content);
if (strcmp("init", content) == 0) { if (strcmp("init", content) == 0) {
StartAllServices(START_MODE_BOOT); static const char *bootServiceNames[] = {
"hdf_devmgr", "samgr", "appspawn", "faultloggerd"
};
for (int i = 0; i < ARRAY_LENGTH(bootServiceNames); i++) {
StartServiceByName(bootServiceNames[i], 0);
}
return; return;
} }
if (strcmp("post-init", content) == 0) { if (strcmp("post-init", content) == 0) {
......
...@@ -282,6 +282,89 @@ static void DoLoadAccessTokenId(const struct CmdArgs *ctx) ...@@ -282,6 +282,89 @@ static void DoLoadAccessTokenId(const struct CmdArgs *ctx)
LoadAccessTokenId(); LoadAccessTokenId();
} }
static int FilterService(const Service *service, const char **exclude, int size)
{
for (int i = 0; i < size; i++) {
if (exclude[i] != NULL && strcmp(service->name, exclude[i]) == 0) {
return 0;
}
}
return 1;
}
static void DoStopAllServices(const struct CmdArgs *ctx)
{
StopAllServices(SERVICE_ATTR_INVALID, (const char **)ctx->argv, ctx->argc, FilterService);
return;
}
static void DoUmount(const struct CmdArgs *ctx)
{
INIT_LOGI("DoUmount %s", ctx->argv[0]);
int ret = GetMountStatusForMountPoint(ctx->argv[0]);
if (ret == 0) {
ret = umount(ctx->argv[0]);
if ((ret != 0) && (ctx->argc > 1) && (strcmp(ctx->argv[0], "MNT_FORCE") == 0)) {
ret = umount2(ctx->argv[0], MNT_FORCE);
}
}
INIT_ERROR_CHECK(ret == 0, return, "Failed to umount %s errno = %d.", ctx->argv[0], errno);
}
static void DoSync(const struct CmdArgs *ctx)
{
sync();
}
static void DoTimerStart(const struct CmdArgs*ctx)
{
INIT_LOGI("Timer start service with arg = %s", ctx->argv[0]);
char *arg = ctx->argv[0];
int count = 0;
int expectedCount = 2;
char **splitArgs = SplitStringExt(ctx->argv[0], "|", &count, expectedCount);
if (splitArgs == NULL) {
INIT_LOGE("Call timer_start with invalid arguments");
return;
}
if (count != expectedCount) {
INIT_LOGE("Call timer_start with unexpect arguments %s", arg);
FreeStringVector(splitArgs, count);
return;
}
Service *service = GetServiceByName(splitArgs[0]);
if (service == NULL) {
INIT_LOGE("Cannot find service in timer_start command");
FreeStringVector(splitArgs, count);
return;
}
errno = 0;
uint64_t timeout = strtoull(splitArgs[1], NULL, DECIMAL_BASE);
if (errno != 0) {
INIT_LOGE("call timer_start with invalid timer");
FreeStringVector(splitArgs, count);
return;
}
// not need this anymore , release memory.
FreeStringVector(splitArgs, count);
ServiceStartTimer(service, timeout);
}
static void DoTimerStop(const struct CmdArgs*ctx)
{
INIT_LOGI("Stop service timer with arg = %s", ctx->argv[0]);
const char *serviceName = ctx->argv[0];
Service *service = GetServiceByName(serviceName);
if (service == NULL) {
INIT_LOGE("Cannot find service in timer_stop command");
return;
}
ServiceStopTimer(service);
}
static const struct CmdTable g_cmdTable[] = { static const struct CmdTable g_cmdTable[] = {
{ "exec ", 1, 10, DoExec }, { "exec ", 1, 10, DoExec },
{ "mknode ", 1, 5, DoMakeNode }, { "mknode ", 1, 5, DoMakeNode },
...@@ -297,6 +380,11 @@ static const struct CmdTable g_cmdTable[] = { ...@@ -297,6 +380,11 @@ static const struct CmdTable g_cmdTable[] = {
{ "mount_fstab ", 1, 1, DoMountFstabFile }, { "mount_fstab ", 1, 1, DoMountFstabFile },
{ "umount_fstab ", 1, 1, DoUmountFstabFile }, { "umount_fstab ", 1, 1, DoUmountFstabFile },
{ "restorecon ", 0, 1, DoRestorecon }, { "restorecon ", 0, 1, DoRestorecon },
{ "stopAllServices ", 0, 10, DoStopAllServices },
{ "umount ", 1, 1, DoUmount },
{ "sync ", 0, 1, DoSync },
{ "timer_start", 1, 1, DoTimerStart },
{ "timer_stop", 1, 1, DoTimerStop },
}; };
const struct CmdTable *GetCmdTable(int *number) const struct CmdTable *GetCmdTable(int *number)
......
...@@ -284,6 +284,7 @@ int SetPluginInterface(void) ...@@ -284,6 +284,7 @@ int SetPluginInterface(void)
return 0; return 0;
} }
char *realPath = GetRealPath("/system/lib/libplugin.z.so"); char *realPath = GetRealPath("/system/lib/libplugin.z.so");
#ifndef STARTUP_INIT_TEST
void* handle = dlopen(realPath, RTLD_LAZY); void* handle = dlopen(realPath, RTLD_LAZY);
if (handle == NULL) { if (handle == NULL) {
INIT_LOGE("Failed to load module %s, err %s", realPath, dlerror()); INIT_LOGE("Failed to load module %s, err %s", realPath, dlerror());
...@@ -291,6 +292,9 @@ int SetPluginInterface(void) ...@@ -291,6 +292,9 @@ int SetPluginInterface(void)
return -1; return -1;
} }
GetPluginInterfaceFunc getPluginInterface = (GetPluginInterfaceFunc)dlsym(handle, "GetPluginInterface"); GetPluginInterfaceFunc getPluginInterface = (GetPluginInterfaceFunc)dlsym(handle, "GetPluginInterface");
#else
GetPluginInterfaceFunc getPluginInterface = GetPluginInterface;
#endif
INIT_LOGI("PluginManagerInit getPluginInterface %p ", getPluginInterface); INIT_LOGI("PluginManagerInit getPluginInterface %p ", getPluginInterface);
if (getPluginInterface != NULL) { if (getPluginInterface != NULL) {
pluginInterface = getPluginInterface(); pluginInterface = getPluginInterface();
...@@ -303,8 +307,9 @@ int SetPluginInterface(void) ...@@ -303,8 +307,9 @@ int SetPluginInterface(void)
INIT_LOGI("PluginManagerInit pluginInterface %p %p %p", INIT_LOGI("PluginManagerInit pluginInterface %p %p %p",
pluginInterface, pluginInterface->pluginRegister, getPluginInterface); pluginInterface, pluginInterface->pluginRegister, getPluginInterface);
} }
free(realPath); free(realPath);
#ifndef STARTUP_INIT_TEST
dlclose(handle); dlclose(handle);
#endif
return 0; return 0;
} }
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "fs_manager/fs_manager.h" #include "fs_manager/fs_manager.h"
#include "init_log.h" #include "init_log.h"
#include "init_jobs_internal.h"
#include "init_service.h" #include "init_service.h"
#include "init_service_manager.h" #include "init_service_manager.h"
#include "init_utils.h" #include "init_utils.h"
...@@ -82,11 +83,15 @@ static int RBMiscReadUpdaterMessage(const char *path, struct RBMiscUpdateMessage ...@@ -82,11 +83,15 @@ static int RBMiscReadUpdaterMessage(const char *path, struct RBMiscUpdateMessage
} }
static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, static int CheckAndRebootToUpdater(const char *valueData, const char *cmd,
const char *cmdExt, const char *boot, const char *miscFile) const char *cmdExt, const char *boot)
{ {
char miscFile[PATH_MAX] = {0};
int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX);
INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc path for %s.", valueData);
// "updater" or "updater:" // "updater" or "updater:"
struct RBMiscUpdateMessage msg; struct RBMiscUpdateMessage msg;
int ret = RBMiscReadUpdaterMessage(miscFile, &msg); ret = RBMiscReadUpdaterMessage(miscFile, &msg);
INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info for %s.", cmd); INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info for %s.", cmd);
if (boot != NULL) { if (boot != NULL) {
...@@ -118,74 +123,110 @@ static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, ...@@ -118,74 +123,110 @@ static int CheckAndRebootToUpdater(const char *valueData, const char *cmd,
return ret; return ret;
} }
static int CheckRebootParam(const char *valueData) int DoRebootCmd(const char *cmd, const char *opt)
{ {
if (valueData == NULL) { // by job to stop service and unmount
return 0; DoJobNow("reboot");
} #ifndef PRODUCT_RK
static const char *cmdParams[] = { return CheckAndRebootToUpdater(NULL, "reboot", NULL, NULL);
"shutdown", "updater", "updater:", "flash", "flash:", "NoArgument", "loader", "bootloader" #else
}; reboot(RB_AUTOBOOT);
size_t i = 0;
for (; i < ARRAY_LENGTH(cmdParams); i++) {
if (strncmp(valueData, cmdParams[i], strlen(cmdParams[i])) == 0) {
break;
}
}
INIT_CHECK_RETURN_VALUE(i < ARRAY_LENGTH(cmdParams), -1);
return 0; return 0;
#endif
} }
void ExecReboot(const char *value) int DoShutdownCmd(const char *cmd, const char *opt)
{ {
INIT_ERROR_CHECK(value != NULL && strlen(value) <= MAX_VALUE_LENGTH, return, "Invalid arg"); // by job to stop service and unmount
const char *valueData = NULL; DoJobNow("reboot");
if (strncmp(value, "reboot,", strlen("reboot,")) == 0) { #ifndef STARTUP_INIT_TEST
valueData = value + strlen("reboot,"); return reboot(RB_POWER_OFF);
} else if (strcmp(value, "reboot") != 0) {
INIT_LOGE("Reboot value = %s, must started with reboot", value);
return;
}
INIT_ERROR_CHECK(CheckRebootParam(valueData) == 0, return, "Invalid arg %s for reboot.", value);
char miscDevice[PATH_MAX] = {0};
char *fstabFile = GetFstabFile();
if (fstabFile != NULL) {
Fstab *fstab = ReadFstabFromFile(fstabFile, false);
free(fstabFile);
if (fstab != NULL) {
INIT_CHECK_ONLY_ELOG(GetBlockDeviceByMountPoint("/misc", fstab, miscDevice, PATH_MAX) == 0,
"Failed to get misc device name.");
ReleaseFstab(fstab);
}
}
StopAllServices(SERVICE_ATTR_INVALID);
sync();
INIT_CHECK_ONLY_ELOG(GetMountStatusForMountPoint("/vendor") == 0 || umount("/vendor") == 0,
"Failed to umount vendor. errno = %d.", errno);
INIT_CHECK_ONLY_ELOG(GetMountStatusForMountPoint("/data") == 0 || umount("/data") == 0 ||
umount2("/data", MNT_FORCE) == 0, "Failed umount data. errno = %d.", errno);
int ret = 0;
if (valueData == NULL) {
#ifndef PRODUCT_RK
ret = CheckAndRebootToUpdater(NULL, "reboot", NULL, NULL, miscDevice);
#else #else
reboot(RB_AUTOBOOT); return 0;
#endif #endif
} else if (strcmp(valueData, "shutdown") == 0) { }
int DoUpdaterCmd(const char *cmd, const char *opt)
{
// by job to stop service and unmount
DoJobNow("reboot");
return CheckAndRebootToUpdater(opt, "updater", "updater:", "boot_updater");
}
int DoFlashdCmd(const char *cmd, const char *opt)
{
// by job to stop service and unmount
DoJobNow("reboot");
return CheckAndRebootToUpdater(opt, "flash", "flash:", "boot_flash");
}
#ifdef PRODUCT_RK
int DoLoaderCmd(const char *cmd, const char *opt)
{
syscall(__NR_reboot, REBOOT_MAGIC1, REBOOT_MAGIC2, REBOOT_CMD_RESTART2, "loader");
return 0;
}
#endif
int DoSuspendCmd(const char *cmd, const char *opt)
{
// by job to stop service and unmount
DoJobNow("suspend");
#ifndef STARTUP_INIT_TEST #ifndef STARTUP_INIT_TEST
ret = reboot(RB_POWER_OFF); return reboot(RB_POWER_OFF);
} else if (strcmp(valueData, "bootloader") == 0) { #else
ret = reboot(RB_POWER_OFF); return 0;
#endif
}
int DoFreezeCmd(const char *cmd, const char *opt)
{
// by job to stop service and unmount
DoJobNow("freeze");
#ifndef STARTUP_INIT_TEST
return reboot(RB_POWER_OFF);
#else
return 0;
#endif #endif
} else if (strncmp(valueData, "updater", strlen("updater")) == 0) { }
ret = CheckAndRebootToUpdater(valueData, "updater", "updater:", "boot_updater", miscDevice);
} else if (strncmp(valueData, "flash", strlen("flash")) == 0) { struct {
ret = CheckAndRebootToUpdater(valueData, "flash", "flash:", "boot_flash", miscDevice); char *cmdName;
int (*doCmd)(const char *cmd, const char *opt);
} g_rebootCmd[] = {
{ "reboot", DoRebootCmd },
{ "shutdown", DoShutdownCmd },
{ "bootloader", DoShutdownCmd },
{ "updater", DoUpdaterCmd },
{ "flashd", DoFlashdCmd },
#ifdef PRODUCT_RK #ifdef PRODUCT_RK
} else if (strncmp(valueData, "loader", strlen("loader")) == 0) { { "loader", DoLoaderCmd },
syscall(__NR_reboot, REBOOT_MAGIC1, REBOOT_MAGIC2, REBOOT_CMD_RESTART2, "loader");
#endif #endif
{ "suspend", DoSuspendCmd },
{ "freeze", DoFreezeCmd },
};
void ExecReboot(const char *value)
{
INIT_ERROR_CHECK(value != NULL && strlen(value) <= MAX_VALUE_LENGTH, return, "Invalid arg");
char *cmd = NULL;
if (strcmp(value, "reboot") == 0) {
cmd = "reboot";
} else if (strncmp(value, "reboot,", strlen("reboot,")) == 0) {
cmd = (char *)(value + strlen("reboot,"));
} else {
INIT_LOGE("Invalid rebot cmd %s.", value);
return;
}
INIT_LOGE("ExecReboot %s.", cmd);
for (int i = 0; i < (int)ARRAY_LENGTH(g_rebootCmd); i++) {
if (strncmp(cmd, g_rebootCmd[i].cmdName, strlen(g_rebootCmd[i].cmdName)) == 0) {
int ret = g_rebootCmd[i].doCmd(cmd, cmd);
INIT_LOGI("Reboot %s %s.", value, (ret == 0) ? "success" : "fail");
return;
}
} }
INIT_LOGI("Reboot %s %s.", value, (ret == 0) ? "success" : "fail"); INIT_LOGE("Invalid rebot cmd %s.", value);
return; return;
} }
...@@ -27,16 +27,29 @@ ...@@ -27,16 +27,29 @@
#include "securec.h" #include "securec.h"
#include "token_setproc.h" #include "token_setproc.h"
#include "nativetoken_kit.h" #include "nativetoken_kit.h"
#include "service_control.h"
#define MIN_IMPORTANT_LEVEL (-20) #define MIN_IMPORTANT_LEVEL (-20)
#define MAX_IMPORTANT_LEVEL 19 #define MAX_IMPORTANT_LEVEL 19
void NotifyServiceChange(const char *serviceName, const char *change) void NotifyServiceChange(Service *service, int status)
{ {
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;
}
char paramName[PARAM_NAME_LEN_MAX] = { 0 }; char paramName[PARAM_NAME_LEN_MAX] = { 0 };
INIT_CHECK_ONLY_ELOG(snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", int ret = snprintf_s(paramName, sizeof(paramName), sizeof(paramName) - 1,
serviceName) >= 0, "snprintf_s paramName error %d ", errno); "%s.%s", STARTUP_SERVICE_CTL, service->name);
SystemWriteParam(paramName, change); if (ret >= 0) {
SystemWriteParam(paramName, statusMap[status].name);
}
} }
int IsForbidden(const char *fieldStr) int IsForbidden(const char *fieldStr)
...@@ -86,9 +99,10 @@ int ServiceExec(const Service *service) ...@@ -86,9 +99,10 @@ int ServiceExec(const Service *service)
int SetAccessToken(const Service *service) int SetAccessToken(const Service *service)
{ {
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "%s failed", service->name); INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "%s failed", service->name);
int ret = SetSelfTokenID(service->tokenId); if (service->tokenId != 0 && SetSelfTokenID(service->tokenId) != 0) {
INIT_LOGI("%s: token id %lld, set token id result %d", service->name, service->tokenId, ret); INIT_LOGE("%s: token id %lld, set token id result %d", service->name, service->tokenId, errno);
return ret == 0 ? SERVICE_SUCCESS : SERVICE_FAILURE; }
return 0;
} }
void GetAccessToken(void) void GetAccessToken(void)
......
...@@ -48,7 +48,7 @@ static void ProcessSignal(const struct signalfd_siginfo *siginfo) ...@@ -48,7 +48,7 @@ static void ProcessSignal(const struct signalfd_siginfo *siginfo)
} }
case SIGTERM: { case SIGTERM: {
INIT_LOGI("SigHandler, SIGTERM received."); INIT_LOGI("SigHandler, SIGTERM received.");
StopAllServices(0); StopAllServices(0, NULL, 0, NULL);
break; break;
} }
default: default:
......
...@@ -58,7 +58,7 @@ BaseTask *CreateTask(const LoopHandle loopHandle, int fd, const LE_BaseInfo *inf ...@@ -58,7 +58,7 @@ BaseTask *CreateTask(const LoopHandle loopHandle, int fd, const LE_BaseInfo *inf
void CloseTask(const LoopHandle loopHandle, BaseTask *task) void CloseTask(const LoopHandle loopHandle, BaseTask *task)
{ {
LE_LOGI("CloseTask %p", task); LE_LOGV("CloseTask %p", task);
LE_CHECK(loopHandle != NULL && task != NULL, return, "Invalid parameters"); LE_CHECK(loopHandle != NULL && task != NULL, return, "Invalid parameters");
if (CheckTaskFlags(task, TASK_STREAM | TASK_CONNECT) || if (CheckTaskFlags(task, TASK_STREAM | TASK_CONNECT) ||
CheckTaskFlags(task, TASK_EVENT | TASK_ASYNC_EVENT)) { CheckTaskFlags(task, TASK_EVENT | TASK_ASYNC_EVENT)) {
...@@ -189,7 +189,7 @@ LE_STATUS LE_Send(const LoopHandle loopHandle, ...@@ -189,7 +189,7 @@ LE_STATUS LE_Send(const LoopHandle loopHandle,
void LE_CloseTask(const LoopHandle loopHandle, const TaskHandle taskHandle) void LE_CloseTask(const LoopHandle loopHandle, const TaskHandle taskHandle)
{ {
LE_CHECK(loopHandle != NULL && taskHandle != NULL, return, "Invalid parameters"); LE_CHECK(loopHandle != NULL && taskHandle != NULL, return, "Invalid parameters");
LE_LOGI("LE_CloseTask %d %p", GetSocketFd(taskHandle), taskHandle); LE_LOGV("LE_CloseTask %d %p", GetSocketFd(taskHandle), taskHandle);
BaseTask *task = (BaseTask *)taskHandle; BaseTask *task = (BaseTask *)taskHandle;
if (task->innerClose != NULL) { if (task->innerClose != NULL) {
task->innerClose(loopHandle, taskHandle); task->innerClose(loopHandle, taskHandle);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import("//base/startup/init_lite/begetd.gni")
import("//build/ohos.gni") import("//build/ohos.gni")
declare_args() { declare_args() {
...@@ -46,6 +47,10 @@ ohos_static_library("param_service") { ...@@ -46,6 +47,10 @@ ohos_static_library("param_service") {
defines = [ "PARAM_SUPPORT_SAVE_PERSIST" ] defines = [ "PARAM_SUPPORT_SAVE_PERSIST" ]
if (defined(boot_kernel_extended_cmdline)) {
defines += [ "BOOT_EXTENDED_CMDLINE=\"${boot_kernel_extended_cmdline}\"" ]
}
if (param_security == "selinux") { if (param_security == "selinux") {
sources += [ "adapter/param_selinux.c" ] sources += [ "adapter/param_selinux.c" ]
defines += [ "PARAM_SUPPORT_SELINUX" ] defines += [ "PARAM_SUPPORT_SELINUX" ]
......
...@@ -201,6 +201,11 @@ static int CheckUserInGroup(gid_t groupId, uid_t uid) ...@@ -201,6 +201,11 @@ static int CheckUserInGroup(gid_t groupId, uid_t uid)
return -1; return -1;
} }
if (grpResult->gr_name == NULL || grpResult->gr_name == NULL) {
PARAM_LOGE("CheckUserInGroup gr_name %s pw_name %s %d %d",
grpResult->gr_name, userResult->pw_name, groupId, uid);
return -1;
}
PARAM_LOGV("CheckUserInGroup pw_name %s ", userResult->pw_name); PARAM_LOGV("CheckUserInGroup pw_name %s ", userResult->pw_name);
if (strcmp(grpResult->gr_name, userResult->pw_name) == 0) { if (strcmp(grpResult->gr_name, userResult->pw_name) == 0) {
return 0; return 0;
......
...@@ -25,11 +25,13 @@ static void OnReceiveRequest(const TaskHandle task, const uint8_t *buffer, uint3 ...@@ -25,11 +25,13 @@ static void OnReceiveRequest(const TaskHandle task, const uint8_t *buffer, uint3
uint32_t curr = 0; uint32_t curr = 0;
while (curr < nread) { while (curr < nread) {
const ParamMessage *msg = (const ParamMessage *)(buffer + curr); const ParamMessage *msg = (const ParamMessage *)(buffer + curr);
if ((msg->msgSize + curr) > nread) { if (((msg->msgSize + curr) > nread)
|| ((sizeof(ParamMessage) + curr) > nread)
|| (msg->msgSize < sizeof(ParamMessage))) {
break; break;
} }
g_recvMessage(task, msg);
curr += msg->msgSize; curr += msg->msgSize;
g_recvMessage(task, msg);
} }
} }
......
...@@ -113,7 +113,11 @@ static int StartRequest(int *fd, ParamMessage *request, int timeout) ...@@ -113,7 +113,11 @@ static int StartRequest(int *fd, ParamMessage *request, int timeout)
{ {
int ret = 0; int ret = 0;
struct timeval time; struct timeval time;
#ifndef STARTUP_INIT_TEST
time.tv_sec = timeout; time.tv_sec = timeout;
#else
time.tv_sec = 1;
#endif
time.tv_usec = 0; time.tv_usec = 0;
do { do {
int clientFd = *fd; int clientFd = *fd;
......
...@@ -39,6 +39,7 @@ static void OnClose(ParamTaskPtr client) ...@@ -39,6 +39,7 @@ static void OnClose(ParamTaskPtr client)
ParamWatcher *watcher = (ParamWatcher *)ParamGetTaskUserData(client); ParamWatcher *watcher = (ParamWatcher *)ParamGetTaskUserData(client);
if (client == g_paramWorkSpace.watcherTask) { if (client == g_paramWorkSpace.watcherTask) {
ClearWatchTrigger(watcher, TRIGGER_PARAM_WATCH); ClearWatchTrigger(watcher, TRIGGER_PARAM_WATCH);
g_paramWorkSpace.watcherTask = NULL;
} else { } else {
ClearWatchTrigger(watcher, TRIGGER_PARAM_WAIT); ClearWatchTrigger(watcher, TRIGGER_PARAM_WAIT);
} }
...@@ -182,7 +183,7 @@ static char *GetServiceCtrlName(ParamWorkSpace *workSpace, const char *name, con ...@@ -182,7 +183,7 @@ static char *GetServiceCtrlName(ParamWorkSpace *workSpace, const char *name, con
"ohos.ctl.stop" "ohos.ctl.stop"
}; };
static char *installParam[] = { static char *installParam[] = {
"ohos.servicectrl" "ohos.servicectrl."
}; };
static char *powerCtrlArg[][2] = { static char *powerCtrlArg[][2] = {
{"reboot,shutdown", "reboot.shutdown"}, {"reboot,shutdown", "reboot.shutdown"},
...@@ -206,7 +207,7 @@ static char *GetServiceCtrlName(ParamWorkSpace *workSpace, const char *name, con ...@@ -206,7 +207,7 @@ static char *GetServiceCtrlName(ParamWorkSpace *workSpace, const char *name, con
} }
for (size_t i = 0; i < ARRAY_LENGTH(installParam); i++) { for (size_t i = 0; i < ARRAY_LENGTH(installParam); i++) {
if (strcmp(name, installParam[i]) == 0) { if (strncmp(name, installParam[i], strlen(installParam[i])) == 0) {
return BuildKey(workSpace, "%s.%s", name, value); return BuildKey(workSpace, "%s.%s", name, value);
} }
} }
...@@ -497,7 +498,7 @@ static int HandleParamWatcherDel(ParamWorkSpace *workSpace, const ParamTaskPtr w ...@@ -497,7 +498,7 @@ static int HandleParamWatcherDel(ParamWorkSpace *workSpace, const ParamTaskPtr w
PARAM_STATIC int ProcessMessage(const ParamTaskPtr worker, const ParamMessage *msg) PARAM_STATIC int ProcessMessage(const ParamTaskPtr worker, const ParamMessage *msg)
{ {
PARAM_CHECK(msg != NULL, return -1, "Invalid msg"); PARAM_CHECK((msg != NULL) && (msg->msgSize >= sizeof(ParamMessage)), return -1, "Invalid msg");
PARAM_CHECK(worker != NULL, return -1, "Invalid worker"); PARAM_CHECK(worker != NULL, return -1, "Invalid worker");
int ret = PARAM_CODE_INVALID_PARAM; int ret = PARAM_CODE_INVALID_PARAM;
switch (msg->type) { switch (msg->type) {
...@@ -589,6 +590,7 @@ static int GetParamValueFromBuffer(const char *name, const char *buffer, char *v ...@@ -589,6 +590,7 @@ static int GetParamValueFromBuffer(const char *name, const char *buffer, char *v
static int LoadParamFromCmdLine(void) static int LoadParamFromCmdLine(void)
{ {
int ret;
static const char *cmdLines[] = { static const char *cmdLines[] = {
OHOS_BOOT"hardware", OHOS_BOOT"hardware",
OHOS_BOOT"bootgroup", OHOS_BOOT"bootgroup",
...@@ -611,7 +613,14 @@ static int LoadParamFromCmdLine(void) ...@@ -611,7 +613,14 @@ static int LoadParamFromCmdLine(void)
return -1, "Failed to read file %s", PARAM_CMD_LINE); return -1, "Failed to read file %s", PARAM_CMD_LINE);
for (size_t i = 0; i < ARRAY_LENGTH(cmdLines); i++) { for (size_t i = 0; i < ARRAY_LENGTH(cmdLines); i++) {
int ret = GetParamValueFromBuffer(cmdLines[i], data, value, PARAM_CONST_VALUE_LEN_MAX); #ifdef BOOT_EXTENDED_CMDLINE
ret = GetParamValueFromBuffer(cmdLines[i], BOOT_EXTENDED_CMDLINE, value, PARAM_CONST_VALUE_LEN_MAX);
if (ret != 0) {
ret = GetParamValueFromBuffer(cmdLines[i], data, value, PARAM_CONST_VALUE_LEN_MAX);
}
#else
ret = GetParamValueFromBuffer(cmdLines[i], data, value, PARAM_CONST_VALUE_LEN_MAX);
#endif
if (ret == 0) { if (ret == 0) {
PARAM_LOGV("Add param from cmdline %s %s", cmdLines[i], value); PARAM_LOGV("Add param from cmdline %s %s", cmdLines[i], value);
ret = CheckParamName(cmdLines[i], 0); ret = CheckParamName(cmdLines[i], 0);
...@@ -744,4 +753,4 @@ void DumpParametersAndTriggers(void) ...@@ -744,4 +753,4 @@ void DumpParametersAndTriggers(void)
if (GetTriggerWorkSpace() != NULL) { if (GetTriggerWorkSpace() != NULL) {
DumpTrigger(GetTriggerWorkSpace()); DumpTrigger(GetTriggerWorkSpace());
} }
} }
\ No newline at end of file
...@@ -107,7 +107,7 @@ static void ExecuteQueueWork(uint32_t maxCount) ...@@ -107,7 +107,7 @@ static void ExecuteQueueWork(uint32_t maxCount)
PARAM_STATIC void ProcessBeforeEvent(const ParamTaskPtr stream, PARAM_STATIC void ProcessBeforeEvent(const ParamTaskPtr stream,
uint64_t eventId, const uint8_t *content, uint32_t size) uint64_t eventId, const uint8_t *content, uint32_t size)
{ {
PARAM_LOGV("ProcessBeforeEvent %s eventId %lu ", (char *)content, eventId); PARAM_LOGV("ProcessBeforeEvent %s ", (char *)content);
switch (eventId) { switch (eventId) {
case EVENT_TRIGGER_PARAM: { case EVENT_TRIGGER_PARAM: {
CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM, CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM,
...@@ -228,7 +228,7 @@ static int GetTriggerType(const char *type) ...@@ -228,7 +228,7 @@ static int GetTriggerType(const char *type)
} }
const char *triggerTypeStr[] = { const char *triggerTypeStr[] = {
"pre-init", "boot", "early-init", "init", "early-init", "late-init", "post-init", "pre-init", "boot", "early-init", "init", "early-init", "late-init", "post-init",
"early-fs", "post-fs", "late-fs", "post-fs-data" "fs", "early-fs", "post-fs", "late-fs", "early-boot", "post-fs-data", "reboot"
}; };
for (size_t i = 0; i < ARRAY_LENGTH(triggerTypeStr); i++) { for (size_t i = 0; i < ARRAY_LENGTH(triggerTypeStr); i++) {
if (strcmp(triggerTypeStr[i], type) == 0) { if (strcmp(triggerTypeStr[i], type) == 0) {
...@@ -260,14 +260,14 @@ static int ParseTrigger_(const TriggerWorkSpace *workSpace, ...@@ -260,14 +260,14 @@ static int ParseTrigger_(const TriggerWorkSpace *workSpace,
PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list"); PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list");
char *name = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "name")); char *name = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "name"));
PARAM_CHECK(name != NULL, return -1, "Can not get name from cfg"); PARAM_CHECK(name != NULL, return -1, "Can not get name from cfg");
if (checkJobValid != NULL && checkJobValid(name) != 0) {
PARAM_LOGI("ParseTrigger trigger %s is not valid", name);
return 0;
}
char *condition = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "condition")); char *condition = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "condition"));
int type = GetTriggerType(name); int type = GetTriggerType(name);
PARAM_CHECK(type <= TRIGGER_UNKNOW, return -1, "Failed to get trigger index"); PARAM_CHECK(type <= TRIGGER_UNKNOW, return -1, "Failed to get trigger index");
if (type != TRIGGER_BOOT && checkJobValid != NULL && checkJobValid(name) != 0) {
PARAM_LOGI("Trigger %s not exist in group", name);
return 0;
}
TriggerHeader *header = GetTriggerHeader(workSpace, type); TriggerHeader *header = GetTriggerHeader(workSpace, type);
PARAM_CHECK(header != NULL, return -1, "Failed to get header %d", type); PARAM_CHECK(header != NULL, return -1, "Failed to get header %d", type);
JobNode *trigger = UpdateJobTrigger(workSpace, type, condition, name); JobNode *trigger = UpdateJobTrigger(workSpace, type, condition, name);
...@@ -376,6 +376,8 @@ void DoTriggerExec(const char *triggerName) ...@@ -376,6 +376,8 @@ void DoTriggerExec(const char *triggerName)
PARAM_LOGI("DoTriggerExec trigger %s", trigger->name); PARAM_LOGI("DoTriggerExec trigger %s", trigger->name);
TRIGGER_SET_FLAG((TriggerNode *)trigger, TRIGGER_FLAGS_QUEUE); TRIGGER_SET_FLAG((TriggerNode *)trigger, TRIGGER_FLAGS_QUEUE);
ExecuteQueuePush(&g_triggerWorkSpace, (TriggerNode *)trigger); ExecuteQueuePush(&g_triggerWorkSpace, (TriggerNode *)trigger);
} else {
PARAM_LOGE("Can not find trigger %s", triggerName);
} }
} }
......
...@@ -149,9 +149,16 @@ int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix) ...@@ -149,9 +149,16 @@ int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix)
WATCHER_CHECK(watcher != nullptr, return 0, "Can not find watcher for keyPrefix %s", keyPrefix.c_str()); WATCHER_CHECK(watcher != nullptr, return 0, "Can not find watcher for keyPrefix %s", keyPrefix.c_str());
auto watcherManager = GetService(); auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
WATCHER_LOGV("DelWatcher keyPrefix_ %s ", keyPrefix.c_str());
int ret = watcherManager->DelWatcher(keyPrefix, watcher->GetWatcherId()); int ret = watcherManager->DelWatcher(keyPrefix, watcher->GetWatcherId());
WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str()); WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str());
SetParamWatcher(keyPrefix, nullptr); {
std::lock_guard<std::mutex> lock(mutex_);
auto iter = watchers_.find(keyPrefix);
if (iter != watchers_.end()) {
watchers_.erase(iter);
}
}
return 0; return 0;
} }
......
{ {
"jobs" : [{
"name" : "boot",
"cmds" : [
"start param_watcher"
]
}
],
"services" : [{ "services" : [{
"name" : "param_watcher", "name" : "param_watcher",
"path" : ["/system/bin/sa_main", "/system/profile/param_watcher.xml"], "path" : ["/system/bin/sa_main", "/system/profile/param_watcher.xml"],
......
...@@ -114,7 +114,7 @@ void HashMapRemove(HashMapHandle handle, const void *key) ...@@ -114,7 +114,7 @@ void HashMapRemove(HashMapHandle handle, const void *key)
int ret = tab->keyCompare(node, key); int ret = tab->keyCompare(node, key);
if (ret == 0) { if (ret == 0) {
INIT_LOGV("HashMapRemove tableId %d hashCode %d node %p", tab->tableId, hashCode, node); INIT_LOGV("HashMapRemove tableId %d hashCode %d node %p", tab->tableId, hashCode, node);
if (preNode == tab->buckets[hashCode]) { if (node == tab->buckets[hashCode]) {
tab->buckets[hashCode] = node->next; tab->buckets[hashCode] = node->next;
} else { } else {
preNode->next = node->next; preNode->next = node->next;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "init_log.h" #include "init_log.h"
#include "securec.h" #include "securec.h"
#include "service_control.h"
#define MAX_BUF_SIZE 1024 #define MAX_BUF_SIZE 1024
#define MAX_DATA_BUFFER 2048 #define MAX_DATA_BUFFER 2048
...@@ -425,10 +426,34 @@ int StringReplaceChr(char *strl, char oldChr, char newChr) ...@@ -425,10 +426,34 @@ int StringReplaceChr(char *strl, char oldChr, char newChr)
int GetMapValue(const char *name, const InitArgInfo *infos, int argNum, int defValue) int GetMapValue(const char *name, const InitArgInfo *infos, int argNum, int defValue)
{ {
if ((argNum == 0) || (infos == NULL) || (name == NULL)) {
return defValue;
}
for (int i = 0; i < argNum; i++) { for (int i = 0; i < argNum; i++) {
if (strcmp(infos[i].name, name) == 0) { if (strcmp(infos[i].name, name) == 0) {
return infos[i].value; return infos[i].value;
} }
} }
return defValue; return defValue;
} }
\ No newline at end of file
const static InitArgInfo g_servieStatusMap[] = {
{"created", SERVICE_IDLE},
{"starting", SERVICE_STARTING},
{"running", SERVICE_STARTED},
{"ready", SERVICE_READY},
{"stopping", SERVICE_STOPPING},
{"stopped", SERVICE_STOPPED},
{"suspended", SERVICE_SUSPENDED},
{"freezed", SERVICE_FREEZED},
{"disabled", SERVICE_DISABLED},
{"critial", SERVICE_CRITIAL}
};
const InitArgInfo *GetServieStatusMap(int *size)
{
if (size != 0) {
*size = ARRAY_LENGTH(g_servieStatusMap);
}
return g_servieStatusMap;
}
...@@ -40,6 +40,8 @@ ohos_unittest("init_ut") { ...@@ -40,6 +40,8 @@ ohos_unittest("init_ut") {
"//base/startup/init_lite/interfaces/innerkits/reboot/init_reboot_innerkits.c", "//base/startup/init_lite/interfaces/innerkits/reboot/init_reboot_innerkits.c",
"//base/startup/init_lite/interfaces/innerkits/socket/init_socket.c", "//base/startup/init_lite/interfaces/innerkits/socket/init_socket.c",
"//base/startup/init_lite/services/begetctl/param_cmd.c", "//base/startup/init_lite/services/begetctl/param_cmd.c",
"//base/startup/init_lite/services/begetctl/shell/shell_bas.c",
"//base/startup/init_lite/services/begetctl/shell/shell_main.c",
"//base/startup/init_lite/services/init/adapter/init_adapter.c", "//base/startup/init_lite/services/init/adapter/init_adapter.c",
"//base/startup/init_lite/services/init/init_capability.c", "//base/startup/init_lite/services/init/init_capability.c",
"//base/startup/init_lite/services/init/init_common_cmds.c", "//base/startup/init_lite/services/init/init_common_cmds.c",
...@@ -86,6 +88,7 @@ ohos_unittest("init_ut") { ...@@ -86,6 +88,7 @@ ohos_unittest("init_ut") {
"//base/startup/init_lite/services/utils/init_hashmap.c", "//base/startup/init_lite/services/utils/init_hashmap.c",
"//base/startup/init_lite/services/utils/init_utils.c", "//base/startup/init_lite/services/utils/init_utils.c",
"//base/startup/init_lite/services/utils/list.c", "//base/startup/init_lite/services/utils/list.c",
"//base/startup/init_lite/ueventd/standard/ueventd_parameter.c",
"//base/startup/init_lite/ueventd/ueventd.c", "//base/startup/init_lite/ueventd/ueventd.c",
"//base/startup/init_lite/ueventd/ueventd_device_handler.c", "//base/startup/init_lite/ueventd/ueventd_device_handler.c",
"//base/startup/init_lite/ueventd/ueventd_firmware_handler.c", "//base/startup/init_lite/ueventd/ueventd_firmware_handler.c",
...@@ -108,6 +111,7 @@ ohos_unittest("init_ut") { ...@@ -108,6 +111,7 @@ ohos_unittest("init_ut") {
} }
sources += [ sources += [
"begetctl/begetctl_unittest.cpp",
"init/cmds_unittest.cpp", "init/cmds_unittest.cpp",
"init/group_unittest.cpp", "init/group_unittest.cpp",
"init/init_reboot_unittest.cpp", "init/init_reboot_unittest.cpp",
...@@ -131,6 +135,7 @@ ohos_unittest("init_ut") { ...@@ -131,6 +135,7 @@ ohos_unittest("init_ut") {
"//base/startup/init_lite/services/init/standard", "//base/startup/init_lite/services/init/standard",
"//base/startup/init_lite/interfaces/innerkits/include", "//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/init_lite/interfaces/innerkits/fd_holder", "//base/startup/init_lite/interfaces/innerkits/fd_holder",
"//base/startup/init_lite/services/begetctl",
"//base/startup/init_lite/services/begetctl/shell", "//base/startup/init_lite/services/begetctl/shell",
"//base/startup/init_lite/services/include", "//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/init/include", "//base/startup/init_lite/services/init/include",
...@@ -160,7 +165,6 @@ ohos_unittest("init_ut") { ...@@ -160,7 +165,6 @@ ohos_unittest("init_ut") {
"//utils/native/base/include", "//utils/native/base/include",
"//utils/system/safwk/native/include", "//utils/system/safwk/native/include",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
"//third_party/libuv/include",
"//third_party/cJSON", "//third_party/cJSON",
"//base/security/access_token/interfaces/innerkits/token_setproc/include", "//base/security/access_token/interfaces/innerkits/token_setproc/include",
"//base/security/access_token/interfaces/innerkits/nativetoken/include", "//base/security/access_token/interfaces/innerkits/nativetoken/include",
...@@ -174,7 +178,6 @@ ohos_unittest("init_ut") { ...@@ -174,7 +178,6 @@ ohos_unittest("init_ut") {
"//third_party/cJSON:cjson_static", "//third_party/cJSON:cjson_static",
"//third_party/googletest:gmock", "//third_party/googletest:gmock",
"//third_party/googletest:gtest", "//third_party/googletest:gtest",
"//third_party/libuv:uv_static",
"//utils/native/base:utils", "//utils/native/base:utils",
] ]
......
/*
* 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.h"
#include "init_unittest.h"
#include "securec.h"
#include "shell.h"
using namespace std;
using namespace testing::ext;
namespace init_ut {
class BegetctlUnitTest : public testing::Test {
public:
static void SetUpTestCase(void) {};
static void TearDownTestCase(void) {};
void SetUp(void) {};
void TearDown(void) {};
};
HWTEST_F(BegetctlUnitTest, TestShellInit, TestSize.Level0)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param"
};
BShellEnvDirectExecute(GetShellHandle(), 1, (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellLs, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "ls"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellLsWithR, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "ls", "-r"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellLsGet, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "get"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellSet, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "set", "aaaaa", "1234567"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellGetWithKey, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "get", "aaaaa"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellWait, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "wait", "aaaaa"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
HWTEST_F(BegetctlUnitTest, TestShellWaitWithKey, TestSize.Level1)
{
BShellParamCmdRegister(GetShellHandle(), 0);
const char *args[] = {
"param", "wait", "aaaaa", "12*", "30"
};
BShellEnvDirectExecute(GetShellHandle(), sizeof(args) / sizeof(args[0]), (char **)args);
}
} // namespace init_ut
...@@ -958,7 +958,7 @@ HWTEST_F(StartupInitUTest, cmdJobTest_001, TestSize.Level0) ...@@ -958,7 +958,7 @@ HWTEST_F(StartupInitUTest, cmdJobTest_001, TestSize.Level0)
DoJob("job name does not exist"); DoJob("job name does not exist");
ReleaseAllJobs(); ReleaseAllJobs();
StartServiceByName("service name does not exist", false); StartServiceByName("service name does not exist", false);
StopAllServices(0); StopAllServices(0, nullptr, 0, nullptr);
ServiceReap(nullptr); ServiceReap(nullptr);
EXPECT_NE(0, ServiceStart(nullptr)); EXPECT_NE(0, ServiceStart(nullptr));
EXPECT_NE(0, ServiceStop(nullptr)); EXPECT_NE(0, ServiceStop(nullptr));
......
...@@ -194,9 +194,6 @@ HWTEST_F(CmdsUnitTest, TestGetCmdKey, TestSize.Level1) ...@@ -194,9 +194,6 @@ HWTEST_F(CmdsUnitTest, TestGetCmdKey, TestSize.Level1)
{ {
const char *cmd1 = GetCmdKey(0); const char *cmd1 = GetCmdKey(0);
EXPECT_STREQ(cmd1, "start "); EXPECT_STREQ(cmd1, "start ");
const int execPos = 17;
cmd1 = GetCmdKey(execPos);
EXPECT_STREQ(cmd1, "exec ");
} }
HWTEST_F(CmdsUnitTest, TestDoCmdByIndex, TestSize.Level1) HWTEST_F(CmdsUnitTest, TestDoCmdByIndex, TestSize.Level1)
......
...@@ -103,18 +103,19 @@ public: ...@@ -103,18 +103,19 @@ public:
void TearDown(void) {}; void TearDown(void) {};
}; };
HashInfo g_info = {
TestHashNodeCompare,
TestHashKeyCompare,
TestHashNodeFunction,
TestHashKeyFunction,
TestHashNodeFree,
2
};
HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1) HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
{ {
HashMapHandle handle; HashMapHandle handle;
HashInfo info = { HashMapCreate(&handle, &g_info);
TestHashNodeCompare,
TestHashKeyCompare,
TestHashNodeFunction,
TestHashKeyFunction,
TestHashNodeFree,
2
};
HashMapCreate(&handle, &info);
const char *str1 = "Test hash map node 1"; const char *str1 = "Test hash map node 1";
const char *str2 = "Test hash map node 2"; const char *str2 = "Test hash map node 2";
const char *str3 = "Test hash map node 3"; const char *str3 = "Test hash map node 3";
...@@ -126,14 +127,12 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1) ...@@ -126,14 +127,12 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
EXPECT_NE(node != NULL, 0); EXPECT_NE(node != NULL, 0);
if (node) { if (node) {
TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node); TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
printf("HashMapGet str1 %s\n", tmp->name);
EXPECT_EQ(strcmp(tmp->name, str1), 0); EXPECT_EQ(strcmp(tmp->name, str1), 0);
} }
node = HashMapGet(handle, (const void *)str2); node = HashMapGet(handle, (const void *)str2);
EXPECT_NE(node != NULL, 0); EXPECT_NE(node != NULL, 0);
if (node) { if (node) {
TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node); TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
printf("HashMapGet str2 %s\n", tmp->name);
EXPECT_EQ(strcmp(tmp->name, str2), 0); EXPECT_EQ(strcmp(tmp->name, str2), 0);
} }
TestHashNode *node3 = TestCreateHashNode(str3); TestHashNode *node3 = TestCreateHashNode(str3);
...@@ -146,9 +145,21 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1) ...@@ -146,9 +145,21 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
EXPECT_NE(node != NULL, 0); EXPECT_NE(node != NULL, 0);
if (node) { if (node) {
TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node); TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
printf("HashMapGet str3 %s\n", tmp->name);
EXPECT_EQ(strcmp(tmp->name, str3), 0); EXPECT_EQ(strcmp(tmp->name, str3), 0);
} }
TestHashNode *node4 = TestCreateHashNode("pre-init");
HashMapAdd(handle, &node4->node);
const char *act = "load_persist_props_action";
TestHashNode *node5 = TestCreateHashNode(act);
HashMapAdd(handle, &node5->node);
HashMapRemove(handle, "pre-init");
node = HashMapGet(handle, (const void *)act);
EXPECT_NE(node != NULL, 0);
if (node) {
TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
EXPECT_EQ(strcmp(tmp->name, act), 0);
}
HashMapDestory(handle); HashMapDestory(handle);
} }
...@@ -174,7 +185,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestInitGroupMgrInit, TestSize.Level1) ...@@ -174,7 +185,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestInitGroupMgrInit, TestSize.Level1)
const char *xxx14 = "{" const char *xxx14 = "{"
"\"groups\": [\"subsystem.xxx11.group\"" "\"groups\": [\"subsystem.xxx11.group\""
"}"; "}";
const char *cmdLine = "BOOT_IMAGE=/kernel init=/init bootgroup=device.boot.group"; const char *cmdLine = "BOOT_IMAGE=/kernel init=/init bootgroup=device.charing.group";
CreateTestFile(GROUP_DEFAULT_PATH "/device.boot.group.cfg", data); CreateTestFile(GROUP_DEFAULT_PATH "/device.boot.group.cfg", data);
CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx1.group.cfg", xxx1); CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx1.group.cfg", xxx1);
CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx11.group.cfg", xxx11); CreateTestFile(GROUP_DEFAULT_PATH "/subsystem.xxx11.group.cfg", xxx11);
...@@ -184,6 +195,9 @@ HWTEST_F(InitGroupManagerUnitTest, TestInitGroupMgrInit, TestSize.Level1) ...@@ -184,6 +195,9 @@ HWTEST_F(InitGroupManagerUnitTest, TestInitGroupMgrInit, TestSize.Level1)
CreateTestFile(BOOT_CMD_LINE, cmdLine); CreateTestFile(BOOT_CMD_LINE, cmdLine);
InitServiceSpace(); InitServiceSpace();
InitWorkspace *workspace = GetInitWorkspace();
EXPECT_EQ(workspace->groupMode, GROUP_CHARING);
workspace->groupMode = GROUP_BOOT;
int ret = InitParseGroupCfg(); int ret = InitParseGroupCfg();
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
} }
...@@ -208,6 +222,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1) ...@@ -208,6 +222,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1)
"\"name\" : \"test-service2\"," "\"name\" : \"test-service2\","
"\"path\" : [\"/dev/test_service\"]," "\"path\" : [\"/dev/test_service\"],"
"\"console\":1," "\"console\":1,"
"\"start-mode\" : \"boot\","
"\"writepid\":[\"/dev/test_service\"]," "\"writepid\":[\"/dev/test_service\"],"
"\"jobs\" : {" "\"jobs\" : {"
"\"on-boot\" : \"boot:bootjob1\"," "\"on-boot\" : \"boot:bootjob1\","
...@@ -225,9 +240,11 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1) ...@@ -225,9 +240,11 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1)
Service *service = GetServiceByName("test-service"); Service *service = GetServiceByName("test-service");
ASSERT_NE(service != nullptr, 0); ASSERT_NE(service != nullptr, 0);
EXPECT_EQ(service->startMode, START_MODE_CONDITION);
ReleaseService(service); ReleaseService(service);
service = GetServiceByName("test-service2"); service = GetServiceByName("test-service2");
ASSERT_NE(service != nullptr, 0); ASSERT_NE(service != nullptr, 0);
EXPECT_EQ(service->startMode, START_MODE_BOOT);
ReleaseService(service); ReleaseService(service);
} }
...@@ -314,4 +331,22 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1) ...@@ -314,4 +331,22 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1)
ASSERT_NE(service, nullptr); ASSERT_NE(service, nullptr);
workspace->groupMode = GROUP_BOOT; workspace->groupMode = GROUP_BOOT;
} }
HWTEST_F(InitGroupManagerUnitTest, TestParseServiceCpucore, TestSize.Level1)
{
const char *jsonStr = "{\"services\":{\"name\":\"test_service22\",\"path\":[\"/data/init_ut/test_service\"],"
"\"importance\":-20,\"uid\":\"root\",\"writepid\":[\"/dev/test_service\"],\"console\":1,\"dynamic\":true,"
"\"gid\":[\"root\"], \"cpucore\":[5, 2, 4, 1, 2, 0, 1]}}";
cJSON* jobItem = cJSON_Parse(jsonStr);
ASSERT_NE(nullptr, jobItem);
cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
ASSERT_NE(nullptr, serviceItem);
Service *service = AddService("test_service22");
if (service != NULL) {
int ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0);
ReleaseService(service);
}
cJSON_Delete(jobItem);
}
} // namespace init_ut } // namespace init_ut
...@@ -44,6 +44,7 @@ void TestCmdExecutor(int id, const char *name, int argc, const char **argv) ...@@ -44,6 +44,7 @@ void TestCmdExecutor(int id, const char *name, int argc, const char **argv)
HWTEST_F(PluginUnitTest, PluginAddCmd, TestSize.Level1) HWTEST_F(PluginUnitTest, PluginAddCmd, TestSize.Level1)
{ {
InitServiceSpace(); InitServiceSpace();
SetPluginInterface();
PluginManagerInit(); PluginManagerInit();
PluginInterface *pluginInterface = GetPluginInterface(); PluginInterface *pluginInterface = GetPluginInterface();
ASSERT_NE(pluginInterface, nullptr); ASSERT_NE(pluginInterface, nullptr);
......
...@@ -33,9 +33,10 @@ public: ...@@ -33,9 +33,10 @@ public:
}; };
HWTEST_F(ServiceSocketUnitTest, TestCreateSocket, TestSize.Level0) HWTEST_F(ServiceSocketUnitTest, TestCreateSocket, TestSize.Level0)
{ {
Service *service = (Service *)calloc(1, sizeof(Service)); const char *testSocName = "test_socket";
Service *service = (Service *)AddService("TestCreateSocket");
ASSERT_NE(service, nullptr); ASSERT_NE(service, nullptr);
ServiceSocket *sockopt = (ServiceSocket *)calloc(1, sizeof(ServiceSocket)); ServiceSocket *sockopt = (ServiceSocket *)calloc(1, sizeof(ServiceSocket) + strlen(testSocName) + 1);
ASSERT_NE(sockopt, nullptr); ASSERT_NE(sockopt, nullptr);
sockopt->type = SOCK_SEQPACKET; sockopt->type = SOCK_SEQPACKET;
sockopt->sockFd = -1; sockopt->sockFd = -1;
...@@ -43,7 +44,6 @@ HWTEST_F(ServiceSocketUnitTest, TestCreateSocket, TestSize.Level0) ...@@ -43,7 +44,6 @@ HWTEST_F(ServiceSocketUnitTest, TestCreateSocket, TestSize.Level0)
sockopt->gid = 1000; sockopt->gid = 1000;
sockopt->perm = 0660; sockopt->perm = 0660;
sockopt->option = SOCKET_OPTION_PASSCRED; sockopt->option = SOCKET_OPTION_PASSCRED;
const char *testSocName = "test_socket";
errno_t ret = strncpy_s(sockopt->name, strlen(testSocName) + 1, testSocName, strlen(testSocName)); errno_t ret = strncpy_s(sockopt->name, strlen(testSocName) + 1, testSocName, strlen(testSocName));
sockopt->next = NULL; sockopt->next = NULL;
EXPECT_EQ(ret, EOK); EXPECT_EQ(ret, EOK);
......
...@@ -54,7 +54,7 @@ HWTEST_F(ServiceUnitTest, case01, TestSize.Level1) ...@@ -54,7 +54,7 @@ HWTEST_F(ServiceUnitTest, case01, TestSize.Level1)
ASSERT_NE(nullptr, jobItem); ASSERT_NE(nullptr, jobItem);
cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services"); cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
ASSERT_NE(nullptr, serviceItem); ASSERT_NE(nullptr, serviceItem);
Service *service = (Service *)calloc(1, sizeof(Service)); Service *service = AddService("test_service");
int ret = ParseOneService(serviceItem, service); int ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
...@@ -64,22 +64,19 @@ HWTEST_F(ServiceUnitTest, case01, TestSize.Level1) ...@@ -64,22 +64,19 @@ HWTEST_F(ServiceUnitTest, case01, TestSize.Level1)
ret = ServiceStop(service); ret = ServiceStop(service);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
if (service != nullptr) { ReleaseService(service);
free(service);
service = nullptr;
}
} }
HWTEST_F(ServiceUnitTest, TestServiceStartAbnormal, TestSize.Level1) HWTEST_F(ServiceUnitTest, TestServiceStartAbnormal, TestSize.Level1)
{ {
const char *jsonStr = "{\"services\":{\"name\":\"test_service\",\"path\":[\"/data/init_ut/test_service\"]," const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/data/init_ut/test_service\"],"
"\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,\"dynamic\":true," "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,\"dynamic\":true,"
"\"gid\":[\"system\"]}}"; "\"gid\":[\"system\"]}}";
cJSON* jobItem = cJSON_Parse(jsonStr); cJSON* jobItem = cJSON_Parse(jsonStr);
ASSERT_NE(nullptr, jobItem); ASSERT_NE(nullptr, jobItem);
cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services"); cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
ASSERT_NE(nullptr, serviceItem); ASSERT_NE(nullptr, serviceItem);
Service *service = (Service *)calloc(1, sizeof(Service)); Service *service = AddService("test_service1");
ASSERT_NE(nullptr, service); ASSERT_NE(nullptr, service);
int ret = ParseOneService(serviceItem, service); int ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
...@@ -98,15 +95,12 @@ HWTEST_F(ServiceUnitTest, TestServiceStartAbnormal, TestSize.Level1) ...@@ -98,15 +95,12 @@ HWTEST_F(ServiceUnitTest, TestServiceStartAbnormal, TestSize.Level1)
service->pid = -1; service->pid = -1;
ret = ServiceStop(service); ret = ServiceStop(service);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
if (service != nullptr) { ReleaseService(service);
free(service);
service = nullptr;
}
} }
HWTEST_F(ServiceUnitTest, TestServiceReap, TestSize.Level1) HWTEST_F(ServiceUnitTest, TestServiceReap, TestSize.Level1)
{ {
Service *service = (Service *)calloc(1, sizeof(Service)); Service *service = AddService("test_service2");
ASSERT_NE(nullptr, service); ASSERT_NE(nullptr, service);
ServiceReap(service); ServiceReap(service);
EXPECT_EQ(service->attribute, 0); EXPECT_EQ(service->attribute, 0);
...@@ -125,31 +119,21 @@ HWTEST_F(ServiceUnitTest, TestServiceReap, TestSize.Level1) ...@@ -125,31 +119,21 @@ HWTEST_F(ServiceUnitTest, TestServiceReap, TestSize.Level1)
ServiceReap(service); ServiceReap(service);
EXPECT_EQ(service->attribute, SERVICE_ATTR_ONCE); EXPECT_EQ(service->attribute, SERVICE_ATTR_ONCE);
if (service->restartArg != nullptr) { ReleaseService(service);
free(service);
service = nullptr;
}
if (service != nullptr) {
free(service);
service = nullptr;
}
} }
HWTEST_F(ServiceUnitTest, TestServiceReapOther, TestSize.Level1) HWTEST_F(ServiceUnitTest, TestServiceReapOther, TestSize.Level1)
{ {
const char *serviceStr = "{\"services\":{\"name\":\"test_service\",\"path\":[\"/data/init_ut/test_service\"]," const char *serviceStr = "{\"services\":{\"name\":\"test_service4\",\"path\":[\"/data/init_ut/test_service\"],"
"\"onrestart\":[\"sleep 1\"],\"console\":1,\"writepid\":[\"/dev/test_service\"]}}"; "\"onrestart\":[\"sleep 1\"],\"console\":1,\"writepid\":[\"/dev/test_service\"]}}";
cJSON* jobItem = cJSON_Parse(serviceStr); cJSON* jobItem = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, jobItem); ASSERT_NE(nullptr, jobItem);
cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services"); cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
ASSERT_NE(nullptr, serviceItem); ASSERT_NE(nullptr, serviceItem);
Service *service = AddService("test_service4");
Service *service = (Service *)calloc(1, sizeof(Service));
ASSERT_NE(nullptr, service); ASSERT_NE(nullptr, service);
int ret = GetCmdLinesFromJson(cJSON_GetObjectItem(serviceItem, "onrestart"), &service->restartArg); int ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0);
ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ServiceReap(service); ServiceReap(service);
...@@ -169,10 +153,7 @@ HWTEST_F(ServiceUnitTest, TestServiceReapOther, TestSize.Level1) ...@@ -169,10 +153,7 @@ HWTEST_F(ServiceUnitTest, TestServiceReapOther, TestSize.Level1)
ret = ServiceStop(service); ret = ServiceStop(service);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
if (service != nullptr) { ReleaseService(service);
free(service);
service = nullptr;
}
} }
HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1) HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1)
...@@ -180,7 +161,8 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1) ...@@ -180,7 +161,8 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1)
Service *service = nullptr; Service *service = nullptr;
ReleaseService(service); ReleaseService(service);
EXPECT_TRUE(service == nullptr); EXPECT_TRUE(service == nullptr);
service = (Service *)malloc(sizeof(Service)); service = AddService("test_service5");
ASSERT_NE(nullptr, service);
service->pathArgs.argv = (char **)malloc(sizeof(char *)); service->pathArgs.argv = (char **)malloc(sizeof(char *));
service->pathArgs.count = 1; service->pathArgs.count = 1;
const char *path = "/data/init_ut/test_service_release"; const char *path = "/data/init_ut/test_service_release";
...@@ -205,14 +187,15 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1) ...@@ -205,14 +187,15 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1)
HWTEST_F(ServiceUnitTest, TestServiceManagerGetService, TestSize.Level1) HWTEST_F(ServiceUnitTest, TestServiceManagerGetService, TestSize.Level1)
{ {
Service *service = GetServiceByPid(1); Service *service = GetServiceByPid(1);
StopAllServices(1); StopAllServices(1, nullptr, 0, nullptr);
EXPECT_TRUE(service == nullptr); EXPECT_TRUE(service == nullptr);
} }
HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1) HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1)
{ {
Service *service = (Service *)malloc(sizeof(Service)); Service *service = AddService("test_service7");
ASSERT_NE(service, nullptr); ASSERT_NE(nullptr, service);
service->pathArgs.argv = (char **)malloc(sizeof(char *)); service->pathArgs.argv = (char **)malloc(sizeof(char *));
ASSERT_NE(service->pathArgs.argv, nullptr); ASSERT_NE(service->pathArgs.argv, nullptr);
service->pathArgs.count = 1; service->pathArgs.count = 1;
...@@ -226,10 +209,6 @@ HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1) ...@@ -226,10 +209,6 @@ HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1)
const int invalidImportantValue = 20; const int invalidImportantValue = 20;
ret = SetImportantValue(service, "", invalidImportantValue, 1); ret = SetImportantValue(service, "", invalidImportantValue, 1);
EXPECT_EQ(ret, -1); EXPECT_EQ(ret, -1);
if (service != nullptr) { ReleaseService(service);
FreeStringVector(service->pathArgs.argv, service->pathArgs.count);
free(service);
service = nullptr;
}
} }
} // namespace init_ut } // namespace init_ut
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "sys_param.h" #include "sys_param.h"
using namespace std; using namespace std;
using namespace testing::ext;
static int g_testPermissionResult = DAC_RESULT_PERMISSION; static int g_testPermissionResult = DAC_RESULT_PERMISSION;
static void ClientCheckParamValue(const char *name, const char *expectValue) static void ClientCheckParamValue(const char *name, const char *expectValue)
...@@ -166,56 +167,6 @@ void TestClientApi(char testBuffer[], uint32_t size, const char *name, const cha ...@@ -166,56 +167,6 @@ void TestClientApi(char testBuffer[], uint32_t size, const char *name, const cha
EXPECT_EQ(strcmp(testBuffer, value), 0); EXPECT_EQ(strcmp(testBuffer, value), 0);
} }
void TestClient(int index)
{
PARAM_LOGI("TestClient %d \n", index);
char testBuffer[PARAM_BUFFER_SIZE] = { 0 };
const std::string value = "test.add.client.value.001";
std::string name = "test.add.client.001";
name += std::to_string(index);
switch (index) {
case 0: {
ParamWorkSpace *space = GetClientParamWorkSpace();
if (space != nullptr && space->securityLabel != nullptr) {
space->securityLabel->cred.uid = 1000; // 1000 test uid
space->securityLabel->cred.gid = 1000; // 1000 test gid
}
}
case 1: { // 1 set test
SystemSetParameter(name.c_str(), value.c_str());
ClientCheckParamValue(name.c_str(), value.c_str());
SystemWaitParameter(name.c_str(), value.c_str(), 1);
TestPersistParam();
// wait
SystemWaitParameter(name.c_str(), value.c_str(), 1);
SystemWaitParameter(name.c_str(), nullptr, 0);
break;
}
case 2: { // 2 api test
TestClientApi(testBuffer, PARAM_BUFFER_SIZE, name.c_str(), value.c_str());
break;
}
case 3: // 3 Traversal test
TestParamTraversal();
SystemDumpParameters(1);
break;
case 4: { // 4 watcher test
int ret = WatchParamCheck(name.c_str());
EXPECT_EQ(ret, 0);
ret = WatchParamCheck("&&&&&.test.tttt");
EXPECT_NE(ret, 0);
// test permission
TestPermission();
break;
}
case 5: // 5 multi thread test
TestForMultiThread();
break;
default:
break;
}
}
int TestEncodeSecurityLabel(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize) int TestEncodeSecurityLabel(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize)
{ {
PARAM_CHECK(bufferSize != nullptr, return -1, "Invalid param"); PARAM_CHECK(bufferSize != nullptr, return -1, "Invalid param");
...@@ -246,3 +197,66 @@ int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel) ...@@ -246,3 +197,66 @@ int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
{ {
return 0; return 0;
} }
namespace init_ut {
class ClientUnitTest : public ::testing::Test {
public:
ClientUnitTest() {}
virtual ~ClientUnitTest() {}
void SetUp(void)
{
ParamWorkSpace *space = GetClientParamWorkSpace();
if (space != nullptr && space->securityLabel != nullptr) {
space->securityLabel->cred.uid = 1000; // 1000 test uid
space->securityLabel->cred.gid = 1000; // 1000 test gid
}
}
void TearDown(void) {}
void TestBody(void) {}
};
HWTEST_F(ClientUnitTest, TestClient_01, TestSize.Level0)
{
const std::string name = "test.add.client.001.001";
const std::string value = "test.add.client.value.001.001";
SystemSetParameter(name.c_str(), value.c_str());
ClientCheckParamValue(name.c_str(), value.c_str());
SystemWaitParameter(name.c_str(), value.c_str(), 1);
TestPersistParam();
// wait
SystemWaitParameter(name.c_str(), value.c_str(), 1);
SystemWaitParameter(name.c_str(), nullptr, 0);
}
HWTEST_F(ClientUnitTest, TestClient_02, TestSize.Level0)
{
char testBuffer[PARAM_BUFFER_SIZE] = { 0 };
const std::string value = "test.add.client.value.001";
const std::string name = "test.add.client.001.003";
TestClientApi(testBuffer, PARAM_BUFFER_SIZE, name.c_str(), value.c_str());
}
HWTEST_F(ClientUnitTest, TestClient_03, TestSize.Level0)
{
// 3 Traversal test
TestParamTraversal();
SystemDumpParameters(1);
}
HWTEST_F(ClientUnitTest, TestClient_04, TestSize.Level0)
{
const std::string name = "test.add.client.001.004";
int ret = WatchParamCheck(name.c_str());
EXPECT_EQ(ret, 0);
ret = WatchParamCheck("&&&&&.test.tttt");
EXPECT_NE(ret, 0);
// test permission
TestPermission();
}
HWTEST_F(ClientUnitTest, TestClient_05, TestSize.Level0)
{
TestForMultiThread();
}
} // namespace init_ut
\ No newline at end of file
...@@ -28,18 +28,6 @@ ...@@ -28,18 +28,6 @@
using namespace testing::ext; using namespace testing::ext;
using namespace std; using namespace std;
const static int32_t g_maxCount = 6;
static int32_t g_repeatCount = 0;
static void TimerCallback(ParamTaskPtr timer, void *context)
{
TestClient(g_repeatCount);
g_repeatCount = g_repeatCount + 1;
if (g_repeatCount >= g_maxCount) {
ParamTaskClose(timer);
StopParamService();
}
}
static const int triggerBuffer = 512; static const int triggerBuffer = 512;
static uint32_t g_execCmdId = 0; static uint32_t g_execCmdId = 0;
static int g_matchTrigger = 0; static int g_matchTrigger = 0;
...@@ -78,16 +66,6 @@ public: ...@@ -78,16 +66,6 @@ public:
void TearDown() {} void TearDown() {}
void TestBody() {} void TestBody() {}
int TestRunClient()
{
TestClient(0);
ParamTaskPtr timer = nullptr;
ParamTimerCreate(&timer, TimerCallback, nullptr);
ParamTimerStart(timer, 500, g_maxCount); // 500ms
StartParamService();
return 0;
}
int ParseInitCfg(const char *configFile) int ParseInitCfg(const char *configFile)
{ {
char *fileBuf = ReadFileToBuf(configFile); char *fileBuf = ReadFileToBuf(configFile);
...@@ -587,10 +565,3 @@ HWTEST_F(TriggerUnitTest, TestExecuteParamTrigger5, TestSize.Level0) ...@@ -587,10 +565,3 @@ HWTEST_F(TriggerUnitTest, TestExecuteParamTrigger5, TestSize.Level0)
TriggerUnitTest test; TriggerUnitTest test;
test.TestExecuteParamTrigger5(); test.TestExecuteParamTrigger5();
} }
HWTEST_F(TriggerUnitTest, TestRunClient, TestSize.Level0)
{
TriggerUnitTest test;
int ret = test.TestRunClient();
EXPECT_EQ(ret, 0);
}
...@@ -22,10 +22,12 @@ ...@@ -22,10 +22,12 @@
#include "init_unittest.h" #include "init_unittest.h"
#include "init_utils.h" #include "init_utils.h"
#include "ueventd_read_cfg.h" #include "ueventd_read_cfg.h"
#include "ueventd_parameter.h"
using namespace std; using namespace std;
using namespace testing::ext; using namespace testing::ext;
#define TEST_PATH "/data/ueventd_ut"
namespace ueventd_ut { namespace ueventd_ut {
static bool FileExists(const std::string &file) static bool FileExists(const std::string &file)
{ {
...@@ -130,19 +132,19 @@ class UeventdConfigUnitTest : public testing::Test { ...@@ -130,19 +132,19 @@ class UeventdConfigUnitTest : public testing::Test {
public: public:
static void SetUpTestCase(void) static void SetUpTestCase(void)
{ {
int rc = mkdir("/data/ueventd_ut", S_IRWXU | S_IRWXG | S_IRWXO); int rc = mkdir(TEST_PATH, S_IRWXU | S_IRWXG | S_IRWXO);
if (rc < 0) { if (rc < 0) {
if (errno != ENOENT) { if (errno != ENOENT) {
cout << "Failed to prepare test directory." << errno << endl; cout << "Failed to prepare test directory." << errno << endl;
} else { } else {
cout << "\"/data/ueventd_ut\" already exists." << endl; cout << " " << TEST_PATH << " already exists." << endl;
} }
} }
} }
static void TearDownTestCase(void) static void TearDownTestCase(void)
{ {
DeleteDir("/data/ueventd_ut"); DeleteDir(TEST_PATH);
} }
void SetUp() {}; void SetUp() {};
...@@ -153,11 +155,11 @@ HWTEST_F(UeventdConfigUnitTest, TestSectionConfigParse, TestSize.Level0) ...@@ -153,11 +155,11 @@ HWTEST_F(UeventdConfigUnitTest, TestSectionConfigParse, TestSize.Level0)
{ {
GenerateConfigFiles("[device]\n", "/dev/test 0666 1000 1000\n", "/data/ueventd_ut/valid.config"); GenerateConfigFiles("[device]\n", "/dev/test 0666 1000 1000\n", "/data/ueventd_ut/valid.config");
GenerateConfigFiles("[device]\n", "/dev/test1 0666 1000\n", "/data/ueventd_ut/valid.config"); GenerateConfigFiles("[device]\n", "/dev/test1 0666 1000\n", "/data/ueventd_ut/valid.config");
GenerateConfigFiles("[device]\n", "/dev/test2 0666 1000 1000 1000\n", "/data/ueventd_ut/valid.config"); GenerateConfigFiles("[device]\n", "/dev/test2 0666 1000 1000 1000 1000\n", "/data/ueventd_ut/valid.config");
GenerateConfigFiles("[sysfs]\n", "/dir/to/nothing attr_nowhere 0666 1000 1000\n", GenerateConfigFiles("[sysfs]\n", "/dir/to/nothing attr_nowhere 0666 1000 1000\n",
"/data/ueventd_ut/valid.config"); TEST_PATH "/valid.config");
GenerateConfigFiles("[firmware]\n", "/etc\n", "/data/ueventd_ut/valid.config"); GenerateConfigFiles("[firmware]\n", "/etc\n", TEST_PATH"/valid.config");
ParseUeventdConfigFile("/data/ueventd_ut/valid.config"); ParseUeventdConfigFile(TEST_PATH"/valid.config");
uid_t uid = 0; uid_t uid = 0;
gid_t gid = 0; gid_t gid = 0;
mode_t mode = 0; mode_t mode = 0;
...@@ -195,4 +197,17 @@ HWTEST_F(UeventdConfigUnitTest, TestConfigEntry, TestSize.Level0) ...@@ -195,4 +197,17 @@ HWTEST_F(UeventdConfigUnitTest, TestConfigEntry, TestSize.Level0)
rc = ParseUeventConfig(const_cast<char*>(file.c_str())); // valid section rc = ParseUeventConfig(const_cast<char*>(file.c_str())); // valid section
EXPECT_EQ(rc, 0); EXPECT_EQ(rc, 0);
} }
HWTEST_F(UeventdConfigUnitTest, TestParameter, TestSize.Level0)
{
GenerateConfigFiles("[device]\n", "/dev/testbinder1 0666 1000 1000 ohos.dev.binder\n", TEST_PATH"/valid.config");
ParseUeventdConfigFile(TEST_PATH"/valid.config");
GenerateConfigFiles("[device]\n", "/dev/testbinder2 0666 1000 1000 ohos.dev.binder\n", TEST_PATH"/valid.config");
ParseUeventdConfigFile(TEST_PATH"/valid.config");
GenerateConfigFiles("[device]\n", "/dev/testbinder3 0666 1000 1000 ohos.dev.binder\n", TEST_PATH"/valid.config");
ParseUeventdConfigFile(TEST_PATH"/valid.config");
SetUeventDeviceParameter("/dev/testbinder1", 0);
SetUeventDeviceParameter("/dev/testbinder2", 0);
SetUeventDeviceParameter("/dev/testbinder3", 0);
}
} // namespace ueventd_ut } // namespace ueventd_ut
...@@ -15,7 +15,17 @@ ...@@ -15,7 +15,17 @@
#ifndef BASE_STARTUP_INITLITE_UEVENTD_PARAMETER_H #ifndef BASE_STARTUP_INITLITE_UEVENTD_PARAMETER_H
#define BASE_STARTUP_INITLITE_UEVENTD_PARAMETER_H #define BASE_STARTUP_INITLITE_UEVENTD_PARAMETER_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int SetUeventDeviceParameter(const char *devNode, int action); int SetUeventDeviceParameter(const char *devNode, int action);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif #endif
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
#include "ueventd_parameter.h"
// lite release not support set parameter. // lite release not support set parameter.
int SetUeventDeviceParameter(const char *devNode, int action) int SetUeventDeviceParameter(const char *devNode, int action)
{ {
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include "ueventd_parameter.h"
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <sys/time.h> #include <sys/time.h>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册