提交 665ab179 编写于 作者: S sun_fan

init: code Refactoring, watchdog, hdc_flashed, ramdisk

Signed-off-by: Nsun_fan <sun_fan1@hoperun.com>
上级 2e42812b
...@@ -62,7 +62,8 @@ ...@@ -62,7 +62,8 @@
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/--> <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/--> <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
<filteritem type="filname" name="*.jpg|*.png|*.gif|*.pdf" desc="already checked"/> <filteritem type="filname" name="*.jpg|*.png|*.gif|*.pdf" desc="already checked"/>
<filteritem type="filepath" name="services/test/unittest/test_data/proc/*" desc="启动功能UT测试的资源文件"/>
</filefilter> </filefilter>
</filefilterlist> </filefilterlist>
......
...@@ -31,7 +31,7 @@ int32_t StartDynamicProcess(const char *name) ...@@ -31,7 +31,7 @@ int32_t StartDynamicProcess(const char *name)
return -1; return -1;
} }
if (SetParameter("ohos.ctl.start", name) != 0) { if (SetParameter("ohos.ctl.start", name) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for {public}%s failed.\n", name); HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name);
return -1; return -1;
} }
return 0; return 0;
...@@ -44,7 +44,7 @@ int32_t StopDynamicProcess(const char *name) ...@@ -44,7 +44,7 @@ int32_t StopDynamicProcess(const char *name)
return -1; return -1;
} }
if (SetParameter("ohos.ctl.stop", name) != 0) { if (SetParameter("ohos.ctl.stop", name) != 0) {
HILOG_ERROR(LOG_CORE, "Set param for {public}%s failed.\n", name); HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name);
return -1; return -1;
} }
return 0; return 0;
......
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
fs_manager_sources = [
"fstab.c",
"fstab_mount.c",
]
fs_manager_include_dirs = [
"//base/startup/init_lite/interfaces/innerkits/include",
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/services/log",
"//base/startup/init_lite/services/include",
]
fs_manager_deps = [
"//base/startup/init_lite/services/log:init_log",
"//base/startup/init_lite/services/utils:libinit_utils",
"//third_party/bounds_checking_function:libsec_static",
]
ohos_shared_library("libfsmanager_shared") {
sources = fs_manager_sources
deps = fs_manager_deps
include_dirs = fs_manager_include_dirs
part_name = "init"
install_images = [
"system",
]
}
ohos_static_library("libfsmanager_static") {
sources = fs_manager_sources
deps = fs_manager_deps
include_dirs = fs_manager_include_dirs
part_name = "init"
}
/*
* 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.
*/
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <libgen.h>
#include <string.h>
#include <stdbool.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "fs_manager/fs_manager.h"
#include "init_utils.h"
#include "securec.h"
struct FsManagerFlags {
char *name;
unsigned int flags;
};
struct MountFlags {
char *name;
unsigned long flags;
};
unsigned int ConvertFlags(char *flagBuffer)
{
static struct FsManagerFlags fsFlags[] = {
{"check", FS_MANAGER_CHECK},
{"wait", FS_MANAGER_WAIT},
{"required", FS_MANAGER_REQUIRED},
};
if (flagBuffer == NULL || *flagBuffer == '\0') {
// No valid flags.
return 0;
}
printf("[fs_manager][debug], fstab flags string: %s\n", flagBuffer);
int flagCount = 0;
unsigned int flags = 0;
const int maxCount = 3;
char **vector = SplitStringExt(flagBuffer, ",", &flagCount, maxCount);
if (vector == NULL || flagCount == 0) {
return 0;
}
for (size_t i = 0; i < ARRAY_LENGTH(fsFlags); i++) {
for (int j = 0; j < flagCount; j++) {
printf("[fs_manager][debug], flag: %s\n", vector[j]);
if (strcmp(fsFlags[i].name, vector[j]) == 0) {
flags |= fsFlags[i].flags;
}
}
}
FreeStringVector(vector, flagCount);
return flags;
}
static void AddToFstab(Fstab *fstab, FstabItem *item)
{
if (fstab == NULL || item == NULL) {
return;
}
if (fstab->head != NULL) {
item->next = fstab->head->next;
fstab->head->next = item;
} else {
fstab->head = item;
}
}
void ReleaseFstabItem(FstabItem *item)
{
if (item != NULL) {
if (item->deviceName != NULL) {
free(item->deviceName);
item->deviceName = NULL;
}
if (item->mountPoint != NULL) {
free(item->mountPoint);
item->mountPoint = NULL;
}
if (item->fsType != NULL) {
free(item->fsType);
item->fsType = NULL;
}
if (item->mountOptions != NULL) {
free(item->mountOptions);
item->mountOptions = NULL;
}
free(item);
item = NULL;
}
}
void ReleaseFstab(Fstab *fstab)
{
if (fstab != NULL) {
FstabItem *item = fstab->head;
while (item != NULL) {
FstabItem *tmp = item->next;
ReleaseFstabItem(item);
item = tmp;
}
free(fstab);
fstab = NULL;
}
}
static int ParseFstabPerLine(char *str, Fstab *fstab, bool procMounts)
{
if (str == NULL || fstab == NULL) {
return -1;
}
const char *separator = " \t";
char *rest = NULL;
FstabItem *item = NULL;
char *p = NULL;
if ((item = (FstabItem *)calloc(1, sizeof(FstabItem))) == NULL) {
errno = ENOMEM;
printf("[fs_manager] Allocate memory for FS table item failed, err = %d\n", errno);
return -1;
}
do {
if ((p = strtok_r(str, separator, &rest)) == NULL) {
fprintf(stderr, "Failed to parse block device.\n");
break;
}
item->deviceName = strdup(p);
if ((p = strtok_r(NULL, separator, &rest)) == NULL) {
fprintf(stderr, "Failed to parse mount point.\n");
break;
}
item->mountPoint = strdup(p);
if ((p = strtok_r(NULL, separator, &rest)) == NULL) {
fprintf(stderr, "Failed to parse fs type.\n");
break;
}
item->fsType = strdup(p);
if ((p = strtok_r(NULL, separator, &rest)) == NULL) {
fprintf(stderr, "Failed to parse mount options.\n");
break;
}
item->mountOptions = strdup(p);
if ((p = strtok_r(NULL, separator, &rest)) == NULL) {
fprintf(stderr, "Failed to parse fs manager flags.\n");
break;
}
// @fsManagerFlags only for fstab
// Ignore it if we read from /proc/mounts
if (!procMounts) {
item->fsManagerFlags = ConvertFlags(p);
} else {
item->fsManagerFlags = 0;
}
AddToFstab(fstab, item);
return 0;
} while (0);
free(item);
item = NULL;
return -1;
}
Fstab *ReadFstabFromFile(const char *file, bool procMounts)
{
char *line = NULL;
size_t allocn = 0;
ssize_t readn = 0;
Fstab *fstab = NULL;
if (file == NULL) {
printf("[fs_manager], invalid file\n");
return NULL;
}
FILE *fp = fopen(file, "r");
if (fp == NULL) {
printf("[fs_manager] Open %s failed, err = %d", file, errno);
return NULL;
}
if ((fstab = (Fstab *)calloc(1, sizeof(Fstab))) == NULL) {
printf("[fs_manager] Allocate memory for FS table failed, err = %d\n", errno);
return NULL;
}
// Record line number of fstab file
size_t ln = 0;
while ((readn = getline(&line, &allocn, fp)) != -1) {
char *p = NULL;
ln++;
if (line[readn - 1] == '\n') {
line[readn - 1] = '\0';
}
p = line;
while (isspace(*p)) {
p++;
}
if (*p == '\0' || *p == '#') {
continue;
}
if (ParseFstabPerLine(p, fstab, procMounts) < 0) {
if (errno == ENOMEM) {
// Ran out of memory, there is no reason to continue.
break;
}
// If one line in fstab file parsed with a failure. just give a warning
// and skip it.
printf("[fs_manager][warning] Cannot parse file \" %s \" at line %u. skip it\n", file, ln);
continue;
}
}
if (line != NULL) {
free(line);
}
return fstab;
}
FstabItem *FindFstabItemForMountPoint(Fstab fstab, const char *mp)
{
FstabItem *item = NULL;
if (mp != NULL) {
for (item = fstab.head; item != NULL; item = item->next) {
if (strcmp(item->mountPoint, mp) == 0) {
break;
}
}
}
return item;
}
FstabItem *FindFstabItemForPath(Fstab fstab, const char *path)
{
FstabItem *item = NULL;
if (path == NULL) {
return NULL;
}
char tmp[PATH_MAX] = {0};
char *dir = NULL;
if (strncpy_s(tmp, PATH_MAX -1, path, strlen(path)) != EOK) {
printf("[fs_manager][error], Failed to copy path\n");
return NULL;
}
dir = tmp;
while (true) {
item = FindFstabItemForMountPoint(fstab, dir);
if (item != NULL) {
break;
}
dir = dirname(dir);
// Reverse walk through path and met "/", just quit.
if (dir == NULL || strcmp(dir, "/") == 0) {
break;
}
}
return item;
}
static const struct MountFlags mountFlags[] = {
{ "noatime", MS_NOATIME },
{ "noexec", MS_NOEXEC },
{ "nosuid", MS_NOSUID },
{ "nodev", MS_NODEV },
{ "nodiratime", MS_NODIRATIME },
{ "ro", MS_RDONLY },
{ "rw", 0 },
{ "sync", MS_SYNCHRONOUS },
{ "remount", MS_REMOUNT },
{ "bind", MS_BIND },
{ "rec", MS_REC },
{ "unbindable", MS_UNBINDABLE },
{ "private", MS_PRIVATE },
{ "slave", MS_SLAVE },
{ "shared", MS_SHARED },
{ "defaults", 0 },
};
static bool IsDefaultMountFlags(const char *str) {
bool isDefault = false;
if (str != NULL) {
for (size_t i = 0; i < ARRAY_LENGTH(mountFlags); i++) {
if (strcmp(str, mountFlags[i].name) == 0) {
isDefault = true;
}
}
}
return isDefault;
}
static unsigned long ParseDefaultMountFlag(const char *str)
{
unsigned long flags = 0;
if (str != NULL) {
for (size_t i = 0; i < ARRAY_LENGTH(mountFlags); i++) {
if (strcmp(str, mountFlags[i].name) == 0) {
flags = mountFlags[i].flags;
break;
}
}
}
return flags;
}
unsigned long GetMountFlags(char *mountFlags, char *fsSpecificData, size_t fsSpecificDataSize)
{
unsigned long flags = 0;
if (mountFlags == NULL || fsSpecificData == NULL) {
return 0;
}
int flagCount = 0;
// Why max count of mount flags is 15?
// There are lots for mount flags defined in sys/mount.h
// But we only support to parse 15 in @ParseDefaultMountFlags() function
// So set default mount flag number to 15.
// If the item configured in fstab contains flag over than 15,
// @SplitStringExt can handle it and parse them all. but the parse function will drop it.
const int maxCount = 15;
char **flagsVector = SplitStringExt(mountFlags, ",", &flagCount, maxCount);
if (flagsVector == NULL || flagCount == 0) {
// No flags or something wrong in SplitStringExt,just return.
return 0;
}
for (int i = 0; i < flagCount; i++) {
char *p = flagsVector[i];
if (IsDefaultMountFlags(p)) {
flags |= ParseDefaultMountFlag(p);
} else {
if (strncat_s(fsSpecificData, fsSpecificDataSize - 1, p, strlen(p)) != EOK) {
printf("[fs_manager][warning], Failed to append mount flag \" %s \", ignore it\n", p);
continue;
}
if (i == flagCount - 1) { // last flags, do not need to append ','
break;
}
// Combined each mount flag with ','
if (strncat_s(fsSpecificData, fsSpecificDataSize - 1, ",", 1) != EOK) {
printf("[fs_manager][warning], Failed to append comma\n");
break; // If cannot add ',' to the end of flags, there is not reason to continue.
}
}
}
FreeStringVector(flagsVector, flagCount);
return flags;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
\ No newline at end of file
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include "fs_manager/fs_manager.h"
#include "init_log.h"
#include "init_utils.h"
#include "securec.h"
#define FS_MANAGER_BUFFER_SIZE 512
bool IsSupportedFilesystem(const char *fsType)
{
static const char *supportedFilesystem[] = {"ext4", "f2fs", NULL};
bool supported = false;
int index = 0;
if (fsType != NULL) {
while (supportedFilesystem[index] != NULL) {
if (strcmp(supportedFilesystem[index++], fsType) == 0) {
supported = true;
break;
}
}
}
return supported;
}
static int ExecCommand(int argc, char **argv)
{
if (argc == 0 || argv == NULL || argv[0] == NULL) {
return -1;
}
pid_t pid = fork();
if (pid < 0) {
INIT_LOGE("Fork new process to format failed: %d", errno);
return -1;
}
if (pid == 0) {
execv(argv[0], argv);
exit(-1);
}
int status;
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
printf("Command %s failed with status %d", argv[0], WEXITSTATUS(status));
}
return WEXITSTATUS(status);
}
int DoFormat(const char *devPath, const char *fsType)
{
if (devPath == NULL || fsType == NULL) {
return -1;
}
if (!IsSupportedFilesystem(fsType)) {
printf("[fs_manager][error] Do not support filesystem \" %s \"\n", fsType);
return -1;
}
int ret = 0;
#define BLOCK_SIZE_BUFFER (64)
char blockSizeBuffer[BLOCK_SIZE_BUFFER] = {0};
if (strcmp(fsType, "ext4") == 0) {
const unsigned int blockSize = 4096;
if (snprintf_s(blockSizeBuffer, BLOCK_SIZE_BUFFER, BLOCK_SIZE_BUFFER - 1, "%u", blockSize) == -1) {
printf("[fs_manager][error] Failed to build block size buffer\n");
return -1;
}
char *formatCmds[] = {
"/bin/mke2fs", "-F", "-t", (char *)fsType, "-b", blockSizeBuffer, (char *)devPath, NULL
};
int argc = ARRAY_LENGTH(formatCmds);
char **argv = (char **)formatCmds;
ret = ExecCommand(argc, argv);
} else if (strcmp(fsType, "f2fs") == 0) {
char *formatCmds[] = {
"/bin/make_f2fs", (char *)devPath, NULL
};
int argc = ARRAY_LENGTH(formatCmds);
char **argv = (char **)formatCmds;
ret = ExecCommand(argc, argv);
}
#undef BLOCK_SIZE_BUFFER
return ret;
}
MountStatus GetMountStatusForMountPoint(const char *mp)
{
if (mp == NULL) {
return MOUNT_ERROR;
}
char buffer[FS_MANAGER_BUFFER_SIZE] = {0};
size_t n = 0;
const int expectedItems = 6;
int count = 0;
char **mountItems = NULL;
MountStatus status = MOUNT_ERROR;
bool found = false;
FILE *fp = fopen("/proc/mounts", "r");
if (fp == NULL) {
return status;
}
while (fgets(buffer, sizeof(buffer) - 1, fp) != NULL) {
n = strlen(buffer);
if (buffer[n - 1] == '\n') {
buffer[n - 1] = '\0';
}
mountItems = SplitStringExt(buffer, " ", &count, expectedItems);
if (mountItems != NULL && count == expectedItems) {
// Second item in /proc/mounts is mount point
if (strcmp(mountItems[1], mp) == 0) {
FreeStringVector(mountItems, count);
found = true;
break;
}
FreeStringVector(mountItems, count);
}
}
if (found == true) {
status = MOUNT_MOUNTED;
} else if (feof(fp) > 0) {
status = MOUNT_UMOUNTED;
}
fclose(fp);
fp = NULL;
return status;
}
static int Mount(const char *source, const char *target, const char *fsType,
unsigned long flags, const char *data)
{
struct stat st = {};
int rc = -1;
if (source == NULL || target == NULL || fsType == NULL) {
printf("[fs_manager][error] Invalid argment for mount\n");
return -1;
}
if (stat(target, &st) != 0 && errno != ENOENT) {
printf("[fs_manager][error] Cannot get stat of \" %s \", err = %d\n", target, errno);
return -1;
}
if ((st.st_mode & S_IFMT) == S_IFLNK) { // link, delete it.
unlink(target);
}
if (mkdir(target, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
if (errno != EEXIST) {
printf("[fs_manager][error] Failed to create dir \" %s \", err = %d\n", target, errno);
return -1;
}
}
errno = 0;
while ((rc = mount(source, target, fsType, flags, data) != 0)) {
if (errno == EAGAIN) {
printf("[fs_manager][warning] Mount %s to %s failed. try again", source, target);
continue;
} else {
break;
}
}
return rc;
}
int MountOneItem(FstabItem *item)
{
if (item == NULL) {
return -1;
}
unsigned long mountFlags;
char fsSpecificData[FS_MANAGER_BUFFER_SIZE] = {0};
mountFlags = GetMountFlags(item->mountOptions, fsSpecificData, sizeof(fsSpecificData));
if (!IsSupportedFilesystem(item->fsType)) {
printf("[fs_manager][error]Unsupported file system \" %s \"", item->fsType);
return -1;
}
if (FM_MANAGER_WAIT_ENABLED(item->fsManagerFlags)) {
WaitForFile(item->deviceName, WAIT_MAX_COUNT);
}
int rc = Mount(item->deviceName, item->mountPoint, item->fsType, mountFlags, fsSpecificData);
if (rc != 0) {
INIT_LOGE("Mount %s to %s failed %d", item->deviceName, item->mountPoint, errno);
} else {
INIT_LOGI("Mount %s to %s successful", item->deviceName, item->mountPoint);
}
return rc;
}
int CheckRequiredAndMount(FstabItem *item, bool required)
{
int rc = -1;
if (item == NULL) {
return rc;
}
if (required) { // Mount partition during first startup.
if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
rc = MountOneItem(item);
}
} else { // Mount partition during second startup.
if (!FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
rc = MountOneItem(item);
}
}
return rc;
}
int MountAllWithFstabFile(const char *fstabFile, bool required)
{
if (fstabFile == NULL || *fstabFile == '\0') {
return -1;
}
Fstab *fstab = NULL;
if ((fstab = ReadFstabFromFile(fstabFile, false)) == NULL) {
printf("[fs_manager][error] Read fstab file \" %s \" failed\n", fstabFile);
return -1;
}
FstabItem *item = NULL;
int rc = -1;
for (item = fstab->head; item != NULL; item = item->next) {
rc = CheckRequiredAndMount(item, required);
}
ReleaseFstab(fstab);
fstab = NULL;
return rc;
}
int UmountAllWithFstabFile(const char *fstabFile)
{
if (fstabFile == NULL || *fstabFile == '\0') {
return -1;
}
Fstab *fstab = NULL;
if ((fstab = ReadFstabFromFile(fstabFile, false)) == NULL) {
printf("[fs_manager][error] Read fstab file \" %s \" failed\n", fstabFile);
return -1;;
}
FstabItem *item = NULL;
int rc = -1;
for (item = fstab->head; item != NULL; item = item->next) {
printf("[fs_manager][info]Umount %s\n", item->mountPoint);
MountStatus status = GetMountStatusForMountPoint(item->mountPoint);
if (status == MOUNT_ERROR) {
printf("[fs_manager][warning] Cannot get mount status of mount point \" %s \"\n", item->mountPoint);
continue; // Cannot get mount status, just ignore it and try next one.
} else if (status == MOUNT_UMOUNTED) {
printf("[fs_manager][info] Mount point \" %s \" already unmounted. device path: %s, fs type: %s\n",
item->mountPoint, item->deviceName, item->fsType);
continue;
} else {
rc = umount(item->mountPoint);
if (rc == -1) {
printf("[fs_manager][error] Umount %s failed, device path: %s, fs type: %s, err = %d",
item->mountPoint, item->deviceName, item->fsType, errno);
} else {
printf("[fs_manager][info] Umount %s successfully\n",
item->mountPoint);
}
}
}
ReleaseFstab(fstab);
fstab = NULL;
return rc;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef STARTUP_FS_MANAGER_H
#define STARTUP_FS_MANAGER_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#include <stdbool.h>
/* Fs manager flags definition */
#define FS_MANAGER_CHECK 0x00000001
#define FS_MANAGER_WAIT 0x00000002
#define FS_MANAGER_REQUIRED 0x00000004
#define VALID_FS_MANAGER_FLAGS (FS_MANAGER_CHECK | FS_MANAGER_WAIT | FS_MANAGER_REQUIRED)
#define FS_MANAGER_FLAGS_ENABLED(fsMgrFlags, flag) (((fsMgrFlags) & FS_MANAGER_##flag) != 0)
#define FM_MANAGER_CHECK_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), CHECK)
#define FM_MANAGER_WAIT_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), WAIT)
#define FM_MANAGER_REQUIRED_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), REQUIRED)
typedef enum MountStatus {
MOUNT_ERROR = -1,
MOUNT_UMOUNTED = 0,
MOUNT_MOUNTED = 1,
} MountStatus;
typedef struct FstabItem {
char *deviceName; // Block device name
char *mountPoint; // Mount point
char *fsType; // File system type
char * mountOptions; // File system mount options. readonly, rw, remount etc.
unsigned int fsManagerFlags; // flags defined by fs manager.
struct FstabItem *next;
} FstabItem;
typedef struct {
struct FstabItem *head;
} Fstab;
void ReleaseFstab(Fstab *fstab);
Fstab *ReadFstabFromFile(const char *file, bool procMounts);
FstabItem *FindFstabItemForPath(Fstab fstab, const char *path);
FstabItem* FindFstabItemForMountPoint(Fstab fstab, const char *mp);
bool IsSupportedFilesystem(const char *fsType);
int DoFormat(const char *devPath, const char *fsType);
int MountOneItem(FstabItem *item);
MountStatus GetMountStatusForMountPoint(const char *mp);
int MountAllWithFstabFile(const char *file, bool required);
int UmountAllWithFstabFile(const char *file);
unsigned long GetMountFlags(char *mountFlags, char *fsSpecificFlags, size_t fsSpecificFlagSize);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // STARTUP_FS_MANAGER_H
\ No newline at end of file
文件模式从 100644 更改为 100755
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "init_log.h" #include "init_log.h"
#include "param.h" #include "param.h"
#include "securec.h" #include "securec.h"
...@@ -45,7 +46,7 @@ int DoReboot(const char *option) ...@@ -45,7 +46,7 @@ int DoReboot(const char *option)
} }
return 0; return 0;
} }
size_t length = strlen(option); int length = strlen(option);
if (length > MAX_REBOOT_OPTION_SIZE) { if (length > MAX_REBOOT_OPTION_SIZE) {
INIT_LOGE("Reboot option \" %s \" is too large, overflow", option); INIT_LOGE("Reboot option \" %s \" is too large, overflow", option);
return -1; return -1;
......
文件模式从 100644 更改为 100755
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
*/ */
#include "init_socket.h" #include "init_socket.h"
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
......
文件模式从 100644 更改为 100755
...@@ -5,7 +5,11 @@ ...@@ -5,7 +5,11 @@
"module_list": [ "module_list": [
"//base/startup/init_lite/services:startup_init", "//base/startup/init_lite/services:startup_init",
"//base/startup/init_lite/ueventd:ueventd", "//base/startup/init_lite/ueventd:ueventd",
"//base/startup/init_lite/ueventd:ueventd.config" "//base/startup/init_lite/ueventd:ueventd.config",
"//base/startup/init_lite/watchdog:watchdog"
],
"test_list": [
"//base/startup/init_lite/services/test/unittest:init_test"
] ]
} }
} }
......
...@@ -10,6 +10,20 @@ ...@@ -10,6 +10,20 @@
# 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.
init_common_sources = [
"init/init_capability.c",
"init/init_common_cmds.c",
"init/init_config.c",
"init/init_common_service.c",
"init/init_service_manager.c",
"init/init_service_socket.c",
"init/main.c",
"log/init_log.c",
"utils/init_utils.c",
"utils/list.c",
]
if (defined(ohos_lite)) { if (defined(ohos_lite)) {
# feature: init # feature: init
executable("init_lite") { executable("init_lite") {
...@@ -19,27 +33,21 @@ if (defined(ohos_lite)) { ...@@ -19,27 +33,21 @@ if (defined(ohos_lite)) {
"OHOS_LITE", "OHOS_LITE",
] ]
sources = [ sources = [
"log/init_log.c", "init/adapter/init_adapter.c",
"src/init_adapter.c", "init/lite/init.c",
"src/init_capability.c", "init/lite/init_cmds.c",
"src/init_cmds.c", "init/lite/init_jobs.c",
"src/init_import.c", "init/lite/init_reboot.c",
"src/init_jobs.c", "init/lite/init_service.c",
"src/init_read_cfg.c", "init/lite/init_signal_handler.c",
"src/init_reboot.c",
"src/init_service.c",
"src/init_service_manager.c",
"src/init_service_socket.c",
"src/init_signal_handler.c",
"src/main.c",
"utils/init_utils.c",
] ]
sources += init_common_sources
include_dirs = [ include_dirs = [
"//base/startup/init_lite/services/include", "//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/param/include", "//base/startup/init_lite/services/init/include",
"//base/startup/init_lite/services/log", "//base/startup/init_lite/services/log",
"//base/startup/init_lite/services/utils",
"//third_party/cJSON", "//third_party/cJSON",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
"//base/startup/syspara_lite/interfaces/kits", "//base/startup/syspara_lite/interfaces/kits",
...@@ -88,33 +96,34 @@ if (defined(ohos_lite)) { ...@@ -88,33 +96,34 @@ if (defined(ohos_lite)) {
ohos_executable("init") { ohos_executable("init") {
sources = [ sources = [
"src/device.c", "init/adapter/init_adapter.c",
"src/init_adapter.c", "init/standard/device.c",
"src/init_capability.c", "init/standard/init.c",
"src/init_cmds.c", "init/standard/init_cmds.c",
"src/init_import.c", "init/standard/init_jobs.c",
"src/init_jobs.c", "init/standard/init_reboot.c",
"src/init_read_cfg.c", "init/standard/init_service.c",
"src/init_reboot.c", "init/standard/init_signal_handler.c",
"src/init_service.c", "init/standard/switch_root.c",
"src/init_service_manager.c", "init/standard/init_mount.c",
"src/init_service_socket.c",
"src/init_signal_handler.c",
"src/main.c",
] ]
sources += init_common_sources
include_dirs = [ include_dirs = [
"//base/startup/init_lite/services/include/param", "//base/startup/init_lite/services/include/param",
"//base/startup/init_lite/services/include", "//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/init/include",
"//base/startup/init_lite/services/log", "//base/startup/init_lite/services/log",
"//base/startup/init_lite/services/utils", "//base/startup/init_lite/interfaces/innerkits/include",
"//third_party/cJSON", "//third_party/cJSON",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
"//third_party/libuv/include", "//third_party/libuv/include",
] ]
deps = [ deps = [
"//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static",
"//base/startup/init_lite/services/log:init_log", "//base/startup/init_lite/services/log:init_log",
"//base/startup/init_lite/services/param:param_service", "//base/startup/init_lite/services/param:param_service",
"//base/startup/init_lite/services/utils:libinit_utils",
"//third_party/bounds_checking_function:libsec_static", "//third_party/bounds_checking_function:libsec_static",
"//third_party/cJSON:cjson_static", "//third_party/cJSON:cjson_static",
] ]
...@@ -138,6 +147,7 @@ if (defined(ohos_lite)) { ...@@ -138,6 +147,7 @@ if (defined(ohos_lite)) {
":init_etc", ":init_etc",
"//base/startup/init_lite/interfaces/innerkits/dynamic_service:dynamic_service", "//base/startup/init_lite/interfaces/innerkits/dynamic_service:dynamic_service",
"//base/startup/init_lite/interfaces/innerkits/socket:libsocket", "//base/startup/init_lite/interfaces/innerkits/socket:libsocket",
"//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_shared",
"//base/startup/init_lite/services/cmds/reboot:reboot", "//base/startup/init_lite/services/cmds/reboot:reboot",
"//base/startup/init_lite/services/cmds/service_control:service_control", "//base/startup/init_lite/services/cmds/service_control:service_control",
"//base/startup/init_lite/services/param:param", "//base/startup/init_lite/services/param:param",
......
...@@ -32,9 +32,7 @@ int main(int argc, char* argv[]) ...@@ -32,9 +32,7 @@ int main(int argc, char* argv[])
printf("%s", USAGE_INFO); printf("%s", USAGE_INFO);
return 0; return 0;
} }
if (argv[1] == NULL) {
return -1;
}
if (argc == REBOOT_CMD_NUMBER && strcmp(argv[1], "shutdown") != 0 && if (argc == REBOOT_CMD_NUMBER && strcmp(argv[1], "shutdown") != 0 &&
strcmp(argv[1], "updater") != 0 && strcmp(argv[1], "updater") != 0 &&
strcmp(argv[1], "flash") != 0 && strcmp(argv[1], "flash") != 0 &&
...@@ -43,7 +41,7 @@ int main(int argc, char* argv[]) ...@@ -43,7 +41,7 @@ int main(int argc, char* argv[])
printf("%s", USAGE_INFO); printf("%s", USAGE_INFO);
return 0; return 0;
} }
int ret; int ret = 0;
if (argc == REBOOT_CMD_NUMBER) { if (argc == REBOOT_CMD_NUMBER) {
ret = DoReboot(argv[1]); ret = DoReboot(argv[1]);
} else { } else {
......
...@@ -67,9 +67,7 @@ int main(int argc, char** argv) ...@@ -67,9 +67,7 @@ int main(int argc, char** argv)
ServiceControlUsage(); ServiceControlUsage();
return -1; return -1;
} }
if (argv[0] == NULL) {
return -1;
}
char serviceCtl[SERVICE_CONTROL_MAX_SIZE]; char serviceCtl[SERVICE_CONTROL_MAX_SIZE];
if (strcmp(argv[0], "start_service") == 0) { if (strcmp(argv[0], "start_service") == 0) {
if (strncpy_s(serviceCtl, sizeof(serviceCtl), "ohos.ctl.start", sizeof(serviceCtl) - 1) != EOK) { if (strncpy_s(serviceCtl, sizeof(serviceCtl), "ohos.ctl.start", sizeof(serviceCtl) - 1) != EOK) {
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
"/etc/init.usb.cfg", "/etc/init.usb.cfg",
"/etc/init.usb.configfs.cfg", "/etc/init.usb.configfs.cfg",
"/etc/init.usb.cfg", "/etc/init.usb.cfg",
"/etc/init.Hi3516DV300.usb.cfg", "/vendor/etc/init.${ohos.boot.hardware}.cfg"
"/etc/init.Hi3516DV300.cfg"
], ],
"jobs" : [{ "jobs" : [{
"name" : "pre-init", "name" : "pre-init",
...@@ -16,10 +15,9 @@ ...@@ -16,10 +15,9 @@
"mkdir /dev/memcg/apps/ 0755 system system", "mkdir /dev/memcg/apps/ 0755 system system",
"mkdir /dev/memcg/system 0550 system system", "mkdir /dev/memcg/system 0550 system system",
"start ueventd", "start ueventd",
"mkdir /vendor", "start watchdog_service",
"mkdir /data", "mkdir /data",
"mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor wait rdonly barrier=1", "mount_fstab /vendor/etc/fstab.${ohos.boot.hardware}"
"mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data wait nosuid nodev noatime barrier=1,data=ordered,noauto_da_alloc"
] ]
}, { }, {
"name" : "init", "name" : "init",
...@@ -386,8 +384,8 @@ ...@@ -386,8 +384,8 @@
"write /proc/sys/kernel/perf_event_paranoid 3" "write /proc/sys/kernel/perf_event_paranoid 3"
] ]
}, { }, {
"name" : "boot && param:ro.debuggable=1", "name" : "boot && param:const.debuggable=1",
"condition" : "boot && ro.debuggable=1", "condition" : "boot && const.debuggable=1",
"cmds" : [ "cmds" : [
"chmod 0773 /data/misc/trace", "chmod 0773 /data/misc/trace",
"chmod 0775 /data/misc/wmtrace", "chmod 0775 /data/misc/wmtrace",
...@@ -406,6 +404,13 @@ ...@@ -406,6 +404,13 @@
"console" : 1, "console" : 1,
"uid" : "root", "uid" : "root",
"gid" : ["shell", "log", "readproc"] "gid" : ["shell", "log", "readproc"]
}, {
"name" : "watchdog_service",
"path" : ["/system/bin/watchdog_service", "10", "2"],
"disabled" : 1,
"uid" : "root",
"gid" : ["shell", "log", "readproc"]
} }
] ]
} }
{ {
"import" : [
"/vendor/etc/init.${ohos.boot.hardware}.usb.cfg"
],
"jobs" : [{ "jobs" : [{
"name" : "boot", "name" : "boot",
"cmds" : [ "cmds" : [
......
...@@ -27,13 +27,13 @@ hw_sc.build.os.version=2.2.0 ...@@ -27,13 +27,13 @@ hw_sc.build.os.version=2.2.0
# ohos release type # ohos release type
hw_sc.build.os.releasetype=Canary1 hw_sc.build.os.releasetype=Canary1
ro.actionable_compatible_property.enabled=false const.actionable_compatible_property.enabled=false
ro.postinstall.fstab.prefix=/system const.postinstall.fstab.prefix=/system
ro.secure=1 const.secure=1
security.perf_harden=1 security.perf_harden=1
ro.allow.mock.location=0 const.allow.mock.location=0
ro.debuggable=1 const.debuggable=1
ro.build.characteristics="default" const.build.characteristics="default"
ro.product.model="ohos" const.product.model="ohos"
ro.product.name="OpenHarmony 2.0 Canary" const.product.name="OpenHarmony 2.0 Canary"
persist.sys.usb.config=hdc persist.sys.usb.config=hdc
...@@ -28,18 +28,23 @@ extern "C" { ...@@ -28,18 +28,23 @@ extern "C" {
#define BINARY_BASE 2 #define BINARY_BASE 2
#define OCTAL_BASE 8 #define OCTAL_BASE 8
#define DECIMAL_BASE 10 #define DECIMAL_BASE 10
#define WAIT_MAX_COUNT 10
#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0])) #define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0]))
uid_t DecodeUid(const char *name); uid_t DecodeUid(const char *name);
char *ReadFileToBuf(const char *configFile); char *ReadFileToBuf(const char *configFile);
int SplitString(char *srcPtr, char **dstPtr, int maxNum); int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum);
void WaitForFile(const char *source, unsigned int maxCount); void WaitForFile(const char *source, unsigned int maxCount);
size_t WriteAll(int fd, const char *buffer, size_t size); size_t WriteAll(int fd, const char *buffer, size_t size);
char *Realpath(const char *source, char *resolvedPath, size_t resolvedPathSize); char *GetRealPath(const char *source);
int StringToInt(const char *str, int defaultValue); int StringToInt(const char *str, int defaultValue);
int MakeDirRecursive(const char *dir, mode_t mode); int MakeDirRecursive(const char *dir, mode_t mode);
int MakeDir(const char *dir, mode_t mode); int MakeDir(const char *dir, mode_t mode);
int ReadFileInDir(const char *dirPath, const char *includeExt,
int (*processFile)(const char *fileName, void *context), void *context);
char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxItemCount);
void FreeStringVector(char **vector, int count);
int InUpdaterMode(void);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -97,10 +97,10 @@ void DoTriggerExec(const char *triggerName); ...@@ -97,10 +97,10 @@ void DoTriggerExec(const char *triggerName);
/** /**
* 对Init接口 * 对Init接口
* 按名字执行对应的trigger。 * dump 参数和trigger信息
* *
*/ */
int SystemTraversalParam(void (*traversalParameter)(ParamHandle handle, void* cookie), void* cookie); void DumpParametersAndTriggers(void);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
文件模式从 100644 更改为 100755
...@@ -13,13 +13,7 @@ ...@@ -13,13 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef INIT_CAPABILITY_H #ifndef INIT_SWITCH_ROOT_H
#define INIT_CAPABILITY_H #define INIT_SWITCH_ROOT_H
int SwitchRoot(const char *newRoot);
#include "cJSON.h" #endif // INIT_SWITCH_ROOT_H
#include "init_service.h" \ No newline at end of file
int GetServiceCaps(const cJSON* curArrItem, Service* curServ);
#endif
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,23 +12,26 @@ ...@@ -12,23 +12,26 @@
* 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 "init_adapter.h" #include "init_adapter.h"
#include <errno.h> #include <errno.h>
#include <semaphore.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/reboot.h> #include <sys/reboot.h>
#include <unistd.h>
#if defined OHOS_LITE && !defined __LINUX__
#include <sys/capability.h>
#else
#include <linux/capability.h>
#endif
#if ((defined __LINUX__) || (!defined OHOS_LITE)) #if ((defined __LINUX__) || (!defined OHOS_LITE))
#include <linux/securebits.h> #include <linux/securebits.h>
#endif #endif
#ifdef __LINUX__
#include "init_signal_handler.h"
#endif
#include "init_log.h" #include "init_log.h"
void RebootSystem() void RebootSystem(void)
{ {
int ret = reboot(RB_AUTOBOOT); int ret = reboot(RB_AUTOBOOT);
if (ret != 0) { if (ret != 0) {
...@@ -36,7 +39,7 @@ void RebootSystem() ...@@ -36,7 +39,7 @@ void RebootSystem()
} }
} }
int KeepCapability() int KeepCapability(void)
{ {
#if ((defined __LINUX__) || (!defined OHOS_LITE)) #if ((defined __LINUX__) || (!defined OHOS_LITE))
if (prctl(PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP | SECBIT_NO_SETUID_FIXUP_LOCKED)) { if (prctl(PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP | SECBIT_NO_SETUID_FIXUP_LOCKED)) {
...@@ -58,7 +61,33 @@ int SetAmbientCapability(int cap) ...@@ -58,7 +61,33 @@ int SetAmbientCapability(int cap)
return 0; return 0;
} }
void ExecuteRcs() #ifdef __LINUX__
static pid_t g_waitPid = -1;
static sem_t *g_waitSem = NULL;
static void SignalRegWaitSem(pid_t waitPid, sem_t *waitSem)
{
g_waitPid = waitPid;
g_waitSem = waitSem;
}
void CheckWaitPid(pid_t sigPID)
{
if (g_waitPid == sigPID && g_waitSem != NULL) {
if (sem_post(g_waitSem) != 0) {
INIT_LOGE("CheckWaitPid, sem_post failed, errno %d.", errno);
}
g_waitPid = -1;
g_waitSem = NULL;
}
}
#else
void CheckWaitPid(pid_t sigPID)
{
(void)(sigPID);
}
#endif
void SystemExecuteRcs(void)
{ {
#if (defined __LINUX__) && (defined NEED_EXEC_RCS_LINUX) #if (defined __LINUX__) && (defined NEED_EXEC_RCS_LINUX)
pid_t retPid = fork(); pid_t retPid = fork();
...@@ -90,4 +119,3 @@ void ExecuteRcs() ...@@ -90,4 +119,3 @@ void ExecuteRcs()
} }
#endif #endif
} }
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,10 +12,8 @@ ...@@ -12,10 +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.
*/ */
#ifndef BASE_STARTUP_INITLITE_DEVICE_H #ifndef BASE_STARTUP_INITLITE_DEVICE_H
#define BASE_STARTUP_INITLITE_DEVICE_H #define BASE_STARTUP_INITLITE_DEVICE_H
#include <sys/types.h> #include <sys/types.h>
#ifdef __cplusplus #ifdef __cplusplus
......
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,14 +12,8 @@ ...@@ -12,14 +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.
*/ */
#ifndef BASE_STARTUP_INIT_H
#ifndef BASE_STARTUP_INITLITE_SIGNAL_HANDLE_H #define BASE_STARTUP_INIT_H
#define BASE_STARTUP_INITLITE_SIGNAL_HANDLE_H
#ifdef __LINUX__
#include <semaphore.h>
#include <sys/types.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
...@@ -27,16 +21,31 @@ extern "C" { ...@@ -27,16 +21,31 @@ extern "C" {
#endif #endif
#endif #endif
void SignalInitModule(); #ifndef PARAM_VALUE_LEN_MAX
#define PARAM_VALUE_LEN_MAX 96
#ifdef __LINUX__
void SignalRegWaitSem(pid_t waitPid, sem_t* waitSem);
#endif #endif
#define PROCESS_EXIT_CODE 0x7f // 0x7f: user specified
// kit framework
#define DEFAULT_UID_KIT_FRAMEWORK 3
// max length of one param/path
#define MAX_ONE_ARG_LEN 200
#define UNUSED(x) (void)(x)
void SystemInit(void);
void LogInit(void);
void SystemPrepare(void);
void SystemConfig(void);
void SystemRun(void);
void SystemExecuteRcs(void);
void ReadConfig(void);
void SignalInit(void);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
#endif #endif
#endif #endif
#endif // BASE_STARTUP_INIT_H
#endif // BASE_STARTUP_INITLITE_SIGNAL_HANDLE_H
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,16 +12,9 @@ ...@@ -12,16 +12,9 @@
* 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.
*/ */
#ifndef BASE_STARTUP_INITLITE_ADAPTER_H #ifndef BASE_STARTUP_INITLITE_ADAPTER_H
#define BASE_STARTUP_INITLITE_ADAPTER_H #define BASE_STARTUP_INITLITE_ADAPTER_H
#include <sys/types.h>
#if defined OHOS_LITE && !defined __LINUX__
#include <sys/capability.h>
#else
#include <linux/capability.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
...@@ -31,27 +24,27 @@ extern "C" { ...@@ -31,27 +24,27 @@ extern "C" {
#ifndef OHOS_LITE #ifndef OHOS_LITE
/* Control the ambient capability set */ /* Control the ambient capability set */
#ifndef PR_CAP_AMBIENT #ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47 #define PR_CAP_AMBIENT 47
#endif #endif
#ifndef PR_CAP_AMBIENT_IS_SET #ifndef PR_CAP_AMBIENT_IS_SET
#define PR_CAP_AMBIENT_IS_SET 1 #define PR_CAP_AMBIENT_IS_SET 1
#endif #endif
#ifndef PR_CAP_AMBIENT_RAISE #ifndef PR_CAP_AMBIENT_RAISE
#define PR_CAP_AMBIENT_RAISE 2 #define PR_CAP_AMBIENT_RAISE 2
#endif #endif
#ifndef PR_CAP_AMBIENT_LOWER #ifndef PR_CAP_AMBIENT_LOWER
#define PR_CAP_AMBIENT_LOWER 3 #define PR_CAP_AMBIENT_LOWER 3
#endif #endif
#ifndef PR_CAP_AMBIENT_CLEAR_ALL #ifndef PR_CAP_AMBIENT_CLEAR_ALL
#define PR_CAP_AMBIENT_CLEAR_ALL 4 #define PR_CAP_AMBIENT_CLEAR_ALL 4
#endif #endif
extern int capset(void *a, void *b);
#endif #endif
void RebootSystem(); void RebootSystem(void);
int KeepCapability(); int KeepCapability(void);
int SetAmbientCapability(int cap); int SetAmbientCapability(int cap);
void ExecuteRcs(); void ExecuteRcs(void);
void CheckWaitPid(pid_t sigPID);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
...@@ -59,4 +52,4 @@ void ExecuteRcs(); ...@@ -59,4 +52,4 @@ void ExecuteRcs();
#endif #endif
#endif #endif
#endif // BASE_STARTUP_INITLITE_ADAPTER_H #endif // BASE_STARTUP_INITLITE_ADAPTER_H
\ No newline at end of file \ No newline at end of file
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,55 +12,74 @@ ...@@ -12,55 +12,74 @@
* 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.
*/ */
#ifndef BASE_STARTUP_INIT_CMDS_H
#ifndef BASE_STARTUP_INITLITE_CMDS_H #define BASE_STARTUP_INIT_CMDS_H
#define BASE_STARTUP_INITLITE_CMDS_H #include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "cJSON.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
#endif #endif
#endif #endif
#define DEFAULT_DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH) // mkdir, default mode
#define SPACES_CNT_IN_CMD_MAX 10 // mount, max number of spaces in cmdline
#define SPACES_CNT_IN_CMD_MIN 2 // mount, min number of spaces in cmdline
#define LOADCFG_BUF_SIZE 128 // loadcfg, max buffer for one cmdline
#define LOADCFG_MAX_FILE_LEN 51200 // loadcfg, max file size is 50K
#define LOADCFG_MAX_LOOP 20 // loadcfg, to prevent to be trapped in infite loop
#define OCTAL_TYPE 8 // 8 means octal to decimal
#define MAX_BUFFER 256UL
#define AUTHORITY_MAX_SIZE 128
#define MAX_CMD_NAME_LEN 32 #define MAX_CMD_NAME_LEN 32
#define MAX_CMD_CONTENT_LEN 256 #define MAX_CMD_CONTENT_LEN 256
#define MAX_CMD_CNT_IN_ONE_JOB 200 #define MAX_CMD_CNT_IN_ONE_JOB 200
#define MAX_COPY_BUF_SIZE 256 #define MAX_COPY_BUF_SIZE 256
#define DEFAULT_COPY_ARGS_CNT 2 #define DEFAULT_COPY_ARGS_CNT 2
#ifndef OHOS_LITE #define OPTIONS_SIZE 128
// Limit max length of parameter value to 96
#define MAX_PARAM_VALUE_LEN 96
// Limit max length of parameter name to 96
#define MAX_PARAM_NAME_LEN 96
#else
// For lite ohos, do not support parameter operation
#define MAX_PARAM_VALUE_LEN 0
#define MAX_PARAM_NAME_LEN 0
#endif
#define SUPPORT_MAX_ARG_FOR_EXEC 10
// one cmd line // one cmd line
typedef struct { typedef struct {
char name[MAX_CMD_NAME_LEN + 1]; int cmdIndex;
char cmdContent[MAX_CMD_CONTENT_LEN + 1]; char cmdContent[MAX_CMD_CONTENT_LEN + 1];
} CmdLine; } CmdLine;
typedef struct {
int cmdNum;
CmdLine cmds[0];
} CmdLines;
struct CmdArgs { struct CmdArgs {
int argc; int argc;
char **argv; char *argv[0];
}; };
int GetParamValue(const char *symValue, char *paramValue, unsigned int paramLen); struct CmdTable {
struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount); char name[MAX_CMD_NAME_LEN];
void FreeCmd(struct CmdArgs *cmd); unsigned char minArg;
unsigned char maxArg;
void ParseCmdLine(const char* cmdStr, CmdLine* resCmd); void (*DoFuncion)(const struct CmdArgs *ctx, const char *cmdContent);
void DoCmd(const CmdLine* curCmd); };
int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen);
const struct CmdArgs *GetCmdArg(const char *cmdContent, const char *delim, int argsCount);
void FreeCmdArg(struct CmdArgs *cmd);
void DoCmdByName(const char *name, const char *cmdContent); void DoCmdByName(const char *name, const char *cmdContent);
const char *GetMatchCmd(const char *cmdStr, unsigned int *index); void DoCmdByIndex(int index, const char *cmdContent);
const char *GetCmdKey(unsigned int index); const char *GetMatchCmd(const char *cmdStr, int *index);
const char *GetCmdKey(int index);
const struct CmdTable *GetCmdTable(int *number);
int GetCmdLinesFromJson(const cJSON *root, CmdLines **cmdLines);
const struct CmdTable *GetCmdByName(const char *name);
void ExecReboot(const char *value);
char *BuildStringFromCmdArg(const struct CmdArgs *ctx, int startIndex);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,12 +12,10 @@ ...@@ -12,12 +12,10 @@
* 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.
*/ */
#ifndef BASE_STARTUP_INITLITE_JOBS_H #ifndef BASE_STARTUP_INITLITE_JOBS_H
#define BASE_STARTUP_INITLITE_JOBS_H #define BASE_STARTUP_INITLITE_JOBS_H
#include "init_cmds.h"
#include "cJSON.h" #include "cJSON.h"
#include "init_cmds.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
...@@ -30,14 +28,20 @@ extern "C" { ...@@ -30,14 +28,20 @@ extern "C" {
// one job, could have many cmd lines // one job, could have many cmd lines
typedef struct { typedef struct {
char name[MAX_JOB_NAME_LEN + 1]; char name[MAX_JOB_NAME_LEN + 1];
int cmdLinesCnt; CmdLines *cmdLines;
CmdLine* cmdLines;
} Job; } Job;
void ParseAllJobs(const cJSON* fileRoot); void ParseAllJobs(const cJSON *fileRoot);
void DoJob(const char* jobName); void DoJob(const char *jobName);
void ReleaseAllJobs(void); void ReleaseAllJobs(void);
void DumpAllJobs(void); void DumpAllJobs(void);
#define INIT_CONFIGURATION_FILE "/etc/init.cfg"
#define OTHER_CFG_PATH "/system/etc/init"
#define MAX_PATH_ARGS_CNT 20
void ReadConfig(void);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
* 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.
*/ */
#ifndef BASE_STARTUP_INITLITE_SERVICE_H #ifndef BASE_STARTUP_INITLITE_SERVICE_H
#define BASE_STARTUP_INITLITE_SERVICE_H #define BASE_STARTUP_INITLITE_SERVICE_H
#include <sys/types.h> #include <sys/types.h>
#include "cJSON.h"
#include "init_cmds.h" #include "init_cmds.h"
#include "init_service_socket.h" #include "init_service_socket.h"
#include "list.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
...@@ -31,19 +31,23 @@ extern "C" { ...@@ -31,19 +31,23 @@ extern "C" {
#define SERVICE_SUCCESS 0 #define SERVICE_SUCCESS 0
// service attributes // service attributes
#define SERVICE_ATTR_INVALID 0x001 // option invalid #define SERVICE_ATTR_INVALID 0x001 // option invalid
#define SERVICE_ATTR_ONCE 0x002 // do not restart when it exits #define SERVICE_ATTR_ONCE 0x002 // do not restart when it exits
#define SERVICE_ATTR_NEED_RESTART 0x004 // will restart in the near future #define SERVICE_ATTR_NEED_RESTART 0x004 // will restart in the near future
#define SERVICE_ATTR_NEED_STOP 0x008 // will stop in reap #define SERVICE_ATTR_NEED_STOP 0x008 // will stop in reap
#define SERVICE_ATTR_IMPORTANT 0x010 // will reboot if it crash #define SERVICE_ATTR_IMPORTANT 0x010 // will reboot if it crash
#define SERVICE_ATTR_CRITICAL 0x020 // critical, will reboot if it crash 4 times in 4 minutes #define SERVICE_ATTR_CRITICAL 0x020 // critical, will reboot if it crash 4 times in 4 minutes
#define SERVICE_ATTR_DISABLED 0x040 // disabled #define SERVICE_ATTR_DISABLED 0x040 // disabled
#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 MAX_SERVICE_NAME 32 #define MAX_SERVICE_NAME 32
#define MAX_WRITEPID_FILES 100 #define MAX_WRITEPID_FILES 100
#define FULL_CAP 0xFFFFFFFF
// init
#define DEFAULT_UMASK_INIT 022
#define CAP_NUM 2 #define CAP_NUM 2
#define SERVICES_ARR_NAME_IN_JSON "services" #define SERVICES_ARR_NAME_IN_JSON "services"
...@@ -56,29 +60,36 @@ typedef struct { ...@@ -56,29 +60,36 @@ typedef struct {
unsigned int capsCnt; unsigned int capsCnt;
} Perms; } Perms;
struct OnRestartCmd { typedef struct {
CmdLine *cmdLine; int count;
int cmdNum; char **argv;
}; } ServiceArgs;
typedef struct { typedef struct {
char name[MAX_SERVICE_NAME + 1]; ListNode node;
char** pathArgs; char name[MAX_SERVICE_NAME + 1];
int pathArgsCnt; int pid;
int pid; int crashCnt;
int crashCnt;
time_t firstCrashTime; time_t firstCrashTime;
char *writepidFiles[MAX_WRITEPID_FILES];
unsigned int attribute; unsigned int attribute;
int importance; int importance;
Perms servPerm; Perms servPerm;
struct OnRestartCmd *onRestart; ServiceArgs pathArgs;
struct ServiceSocket *socketCfg; ServiceArgs writePidArgs;
CmdLines *restartArg;
ServiceSocket *socketCfg;
} Service; } Service;
int ServiceStart(Service *service); int ServiceStart(Service *service);
int ServiceStop(Service *service); int ServiceStop(Service *service);
void ServiceReap(Service *service); void ServiceReap(Service *service);
void ReapService(Service *service);
void NotifyServiceChange(const char *serviceName, const char *change);
int IsForbidden(const char *fieldStr);
int SetImportantValue(Service *curServ, const char *attrName, int value, int flag);
int GetServiceCaps(const cJSON *curArrItem, Service *curServ);
int ServiceExec(const Service *service);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,12 +12,12 @@ ...@@ -12,12 +12,12 @@
* 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.
*/ */
#ifndef BASE_STARTUP_INITLITE_SERVICEMANAGER_H #ifndef BASE_STARTUP_INITLITE_SERVICEMANAGER_H
#define BASE_STARTUP_INITLITE_SERVICEMANAGER_H #define BASE_STARTUP_INITLITE_SERVICEMANAGER_H
#include "init_service.h" #include "init_service.h"
#include "cJSON.h" #include "cJSON.h"
#include "list.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
...@@ -25,26 +25,37 @@ extern "C" { ...@@ -25,26 +25,37 @@ extern "C" {
#endif #endif
#endif #endif
#define UID_STR_IN_CFG "uid" #define UID_STR_IN_CFG "uid"
#define GID_STR_IN_CFG "gid" #define GID_STR_IN_CFG "gid"
#define ONCE_STR_IN_CFG "once" #define ONCE_STR_IN_CFG "once"
#define IMPORTANT_STR_IN_CFG "importance" #define IMPORTANT_STR_IN_CFG "importance"
#define BIN_SH_NOT_ALLOWED "/bin/sh" #define BIN_SH_NOT_ALLOWED "/bin/sh"
#define CRITICAL_STR_IN_CFG "critical" #define CRITICAL_STR_IN_CFG "critical"
#define DISABLED_STR_IN_CFG "disabled" #define DISABLED_STR_IN_CFG "disabled"
#define CONSOLE_STR_IN_CFG "console" #define CONSOLE_STR_IN_CFG "console"
#define MAX_SERVICES_CNT_IN_FILE 100 #define MAX_SERVICES_CNT_IN_FILE 100
void RegisterServices(Service *services, int servicesCnt); typedef struct {
char *capStr;
unsigned int CapNum;
} CapStrCapNum;
typedef struct {
ListNode services;
int serviceCount;
} ServiceSpace;
Service *GetServiceByPid(pid_t pid);
Service *GetServiceByName(const char *servName);
cJSON *GetArrayItem(const cJSON *fileRoot, int *arrSize, const char *arrName);
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(void); void StopAllServices(int flags);
void StopAllServicesBeforeReboot(void);
void ReapServiceByPID(int pid);
void ParseAllServices(const cJSON *fileRoot); void ParseAllServices(const cJSON *fileRoot);
#ifdef OHOS_SERVICE_DUMP #ifdef OHOS_SERVICE_DUMP
void DumpAllServices(void); void DumpAllServices();
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
/* /*
* Copyright (c) 2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
...@@ -12,17 +12,21 @@ ...@@ -12,17 +12,21 @@
* 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.
*/ */
#ifndef INIT_SERVICE_SOCKET_ #ifndef INIT_SERVICE_SOCKET_
#define INIT_SERVICE_SOCKET_ #define INIT_SERVICE_SOCKET_
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define MAX_SOCK_NAME_LEN 16 #define MAX_SOCK_NAME_LEN 16
#define SOCK_OPT_NUMS 6 #define SOCK_OPT_NUMS 6
enum SockOptionTab { enum SockOptionTab {
SERVICE_SOCK_NAME = 0, SERVICE_SOCK_NAME = 0,
SERVICE_SOCK_TYPE, SERVICE_SOCK_TYPE,
...@@ -32,18 +36,23 @@ enum SockOptionTab { ...@@ -32,18 +36,23 @@ enum SockOptionTab {
SERVICE_SOCK_SETOPT SERVICE_SOCK_SETOPT
}; };
struct ServiceSocket; typedef struct ServiceSocket_ {
struct ServiceSocket { struct ServiceSocket_ *next;
char *name; // service name int type; // socket type
int type; // socket type uid_t uid; // uid
uid_t uid; // uid gid_t gid; // gid
gid_t gid; // gid bool passcred; // setsocketopt
bool passcred; // setsocketopt mode_t perm; // Setting permissions
mode_t perm; // Setting permissions
int sockFd; int sockFd;
struct ServiceSocket *next; char name[0]; // service name
}; } ServiceSocket;
int DoCreateSocket(struct ServiceSocket *sockopt); int CreateServiceSocket(ServiceSocket *sockopt);
void CloseServiceSocket(ServiceSocket *sockopt);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif #endif
/*
* Copyright (c) 2020-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 <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined OHOS_LITE && !defined __LINUX__
#include <sys/capability.h>
#else
#include <linux/capability.h>
#endif
#include <sys/types.h>
#include <unistd.h>
#include "init_log.h"
#include "init_service.h"
#include "init_service_manager.h"
#include "init_utils.h"
#define MAX_CAPS_CNT_FOR_ONE_SERVICE 100
static unsigned int GetCapByString(const char *capStr)
{
static const CapStrCapNum capStrCapNum[] = {
{ "CHOWN", CAP_CHOWN },
{ "DAC_OVERRIDE", CAP_DAC_OVERRIDE },
{ "DAC_READ_SEARCH", CAP_DAC_READ_SEARCH },
{ "FOWNER", CAP_FOWNER },
{ "FSETID", CAP_FSETID },
{ "KILL", CAP_KILL },
{ "SETGID", CAP_SETGID },
{ "SETUID", CAP_SETUID },
{ "SETPCAP", CAP_SETPCAP },
{ "LINUX_IMMUTABLE", CAP_LINUX_IMMUTABLE },
{ "NET_BIND_SERVICE", CAP_NET_BIND_SERVICE },
{ "NET_BROADCAST", CAP_NET_BROADCAST },
{ "NET_ADMIN", CAP_NET_ADMIN },
{ "NET_RAW", CAP_NET_RAW },
{ "IPC_LOCK", CAP_IPC_LOCK },
{ "IPC_OWNER", CAP_IPC_OWNER },
{ "SYS_MODULE", CAP_SYS_MODULE },
{ "SYS_RAWIO", CAP_SYS_RAWIO },
{ "SYS_CHROOT", CAP_SYS_CHROOT },
{ "SYS_PTRACE", CAP_SYS_PTRACE },
{ "SYS_PACCT", CAP_SYS_PACCT },
{ "SYS_ADMIN", CAP_SYS_ADMIN },
{ "SYS_BOOT", CAP_SYS_BOOT },
{ "SYS_NICE", CAP_SYS_NICE },
{ "SYS_RESOURCE", CAP_SYS_RESOURCE },
{ "SYS_TIME", CAP_SYS_TIME },
{ "SYS_TTY_CONFIG", CAP_SYS_TTY_CONFIG },
{ "MKNOD", CAP_MKNOD },
{ "LEASE", CAP_LEASE },
{ "AUDIT_WRITE", CAP_AUDIT_WRITE },
{ "AUDIT_CONTROL", CAP_AUDIT_CONTROL },
{ "SETFCAP", CAP_SETFCAP },
{ "MAC_OVERRIDE", CAP_MAC_OVERRIDE },
{ "MAC_ADMIN", CAP_MAC_ADMIN },
{ "SYSLOG", CAP_SYSLOG },
{ "WAKE_ALARM", CAP_WAKE_ALARM },
{ "BLOCK_SUSPEND", CAP_BLOCK_SUSPEND },
{ "AUDIT_READ", CAP_AUDIT_READ },
};
int mapSize = (int)ARRAY_LENGTH(capStrCapNum);
for (int j = 0; j < mapSize; j++) {
if (strcmp(capStr, capStrCapNum[j].capStr) == 0) {
return capStrCapNum[j].CapNum;
}
}
return -1;
}
int GetServiceCaps(const cJSON *curArrItem, Service *service)
{
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "service is null ptr.");
INIT_ERROR_CHECK(curArrItem != NULL, return SERVICE_FAILURE, "json is null ptr.");
service->servPerm.capsCnt = 0;
service->servPerm.caps = NULL;
int capsCnt = 0;
cJSON *filedJ = GetArrayItem(curArrItem, &capsCnt, "caps");
if (filedJ == NULL) {
return SERVICE_SUCCESS;
}
if (capsCnt > MAX_CAPS_CNT_FOR_ONE_SERVICE) {
INIT_LOGE("service=%s, too many caps[cnt %d] for one service", service->name, capsCnt);
return SERVICE_FAILURE;
}
service->servPerm.caps = (unsigned int *)calloc(1, sizeof(unsigned int) * capsCnt);
if (service->servPerm.caps == NULL) {
INIT_LOGE("Failed to malloc for service %s", service->name);
return SERVICE_FAILURE;
}
service->servPerm.capsCnt = capsCnt;
unsigned int caps = FULL_CAP;
for (int i = 0; i < capsCnt; ++i) { // number form
cJSON *capJson = cJSON_GetArrayItem(filedJ, i);
if (cJSON_IsNumber(capJson)) { // for number
caps = (unsigned int)cJSON_GetNumberValue(capJson);
} else if (cJSON_IsString(capJson)) {
char *capStr = cJSON_GetStringValue(capJson);
if (capStr == NULL || strlen(capStr) <= 0) { // check all errors
INIT_LOGE("service=%s, parse item[%d] as string, error.", service->name, i);
break;
}
caps = GetCapByString(capStr);
}
if (caps < 0) {
return SERVICE_FAILURE;
}
if ((caps > CAP_LAST_CAP) && (caps != (unsigned int)FULL_CAP)) {
INIT_LOGE("service=%s, caps = %d, error.", service->name, caps);
return SERVICE_FAILURE;
}
service->servPerm.caps[i] = (unsigned int)caps;
}
return 0;
}
此差异已折叠。
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,12 +12,10 @@ ...@@ -12,12 +12,10 @@
* 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 "init_service.h" #include "init_service.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -25,46 +23,32 @@ ...@@ -25,46 +23,32 @@
#ifdef __MUSL__ #ifdef __MUSL__
#include <stropts.h> #include <stropts.h>
#endif #endif
#include <sys/capability.h>
#include <sys/param.h> #include <sys/param.h>
#ifndef OHOS_LITE
#include <sys/resource.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "init.h"
#include "init_adapter.h" #include "init_adapter.h"
#include "init_cmds.h" #include "init_cmds.h"
#include "init_log.h" #include "init_log.h"
#ifndef OHOS_LITE
#include "init_param.h"
#endif
#include "init_perms.h"
#include "init_reboot.h"
#include "init_service_socket.h" #include "init_service_socket.h"
#include "init_utils.h" #include "init_utils.h"
#include "securec.h" #include "securec.h"
#ifndef OHOS_LITE
#include "sys_param.h"
#endif
#define CAP_NUM 2
#define WAIT_MAX_COUNT 10
#ifndef TIOCSCTTY #ifndef TIOCSCTTY
#define TIOCSCTTY 0x540E #define TIOCSCTTY 0x540E
#endif #endif
// 240 seconds, 4 minutes // 240 seconds, 4 minutes
static const int CRASH_TIME_LIMIT = 240; static const int CRASH_TIME_LIMIT = 240;
// maximum number of crashes within time CRASH_TIME_LIMIT for one service // maximum number of crashes within time CRASH_TIME_LIMIT for one service
static const int CRASH_COUNT_LIMIT = 4; static const int CRASH_COUNT_LIMIT = 4;
// 240 seconds, 4 minutes // 240 seconds, 4 minutes
static const int CRITICAL_CRASH_TIME_LIMIT = 240; static const int CRITICAL_CRASH_TIME_LIMIT = 240;
// maximum number of crashes within time CRITICAL_CRASH_TIME_LIMIT for one service // maximum number of crashes within time CRITICAL_CRASH_TIME_LIMIT for one service
static const int CRITICAL_CRASH_COUNT_LIMIT = 4; static const int CRITICAL_CRASH_COUNT_LIMIT = 4;
static const int MAX_PID_STRING_LENGTH = 50;
static int SetAllAmbientCapability(void) static int SetAllAmbientCapability(void)
{ {
...@@ -101,14 +85,13 @@ static int SetPerms(const Service *service) ...@@ -101,14 +85,13 @@ static int SetPerms(const Service *service)
struct __user_cap_header_struct capHeader; struct __user_cap_header_struct capHeader;
capHeader.version = _LINUX_CAPABILITY_VERSION_3; capHeader.version = _LINUX_CAPABILITY_VERSION_3;
capHeader.pid = 0; capHeader.pid = 0;
struct __user_cap_data_struct capData[CAP_NUM] = {}; struct __user_cap_data_struct capData[CAP_NUM] = {};
for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) { for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
if (service->servPerm.caps[i] == FULL_CAP) { if (service->servPerm.caps[i] == FULL_CAP) {
for (int i = 0; i < CAP_NUM; ++i) { for (int j = 0; j < CAP_NUM; ++j) {
capData[i].effective = FULL_CAP; capData[j].effective = FULL_CAP;
capData[i].permitted = FULL_CAP; capData[j].permitted = FULL_CAP;
capData[i].inheritable = FULL_CAP; capData[j].inheritable = FULL_CAP;
} }
break; break;
} }
...@@ -135,6 +118,7 @@ static int SetPerms(const Service *service) ...@@ -135,6 +118,7 @@ static int SetPerms(const Service *service)
static void OpenConsole(void) static void OpenConsole(void)
{ {
const int stdError = 2;
setsid(); setsid();
WaitForFile("/dev/console", WAIT_MAX_COUNT); WaitForFile("/dev/console", WAIT_MAX_COUNT);
int fd = open("/dev/console", O_RDWR); int fd = open("/dev/console", O_RDWR);
...@@ -142,7 +126,7 @@ static void OpenConsole(void) ...@@ -142,7 +126,7 @@ static void OpenConsole(void)
ioctl(fd, TIOCSCTTY, 0); ioctl(fd, TIOCSCTTY, 0);
dup2(fd, 0); dup2(fd, 0);
dup2(fd, 1); dup2(fd, 1);
dup2(fd, 2); // Redirect fd to 0, 1, 2 dup2(fd, stdError); // Redirect fd to 0, 1, 2
close(fd); close(fd);
} else { } else {
INIT_LOGE("Open /dev/console failed. err = %d", errno); INIT_LOGE("Open /dev/console failed. err = %d", errno);
...@@ -150,107 +134,106 @@ static void OpenConsole(void) ...@@ -150,107 +134,106 @@ static void OpenConsole(void)
return; return;
} }
static void WriteServicePid(const Service *service, pid_t pid) static int WritePid(const Service *service)
{ {
char pidString[MAX_PID_STRING_LENGTH]; const int maxPidStrLen = 50;
INIT_ERROR_CHECK(snprintf_s(pidString, MAX_PID_STRING_LENGTH, MAX_PID_STRING_LENGTH - 1, "%d", pid) >= 0, char pidString[maxPidStrLen];
_exit(0x7f), "Build pid string failed"); pid_t childPid = getpid();
int len = snprintf_s(pidString, maxPidStrLen, maxPidStrLen - 1, "%d", childPid);
for (int i = 0; i < MAX_WRITEPID_FILES; i++) { if (len <= 0) {
if (service->writepidFiles[i] == NULL) { INIT_LOGE("Failed to format pid for service %s", service->name);
break; return SERVICE_FAILURE;
} }
char *realPath = realpath(service->writepidFiles[i], NULL); for (int i = 0; i < service->writePidArgs.count; i++) {
if (realPath == NULL) { if (service->writePidArgs.argv[i] == NULL) {
continue; continue;
} }
FILE *fd = fopen(realPath, "wb"); FILE *fd = NULL;
free(realPath); char *realPath = GetRealPath(service->writePidArgs.argv[i]);
realPath = NULL; if (realPath != NULL) {
INIT_ERROR_CHECK(fd != NULL, continue, "Open file %s failed, err = %d", service->writepidFiles[i], errno); fd = fopen(realPath, "wb");
INIT_CHECK_ONLY_ELOG(fwrite(pidString, 1, strlen(pidString), fd) == strlen(pidString), } else {
"write pid %s to file %s failed, err = %d", pidString, service->writepidFiles[i], errno); fd = fopen(service->writePidArgs.argv[i], "wb");
fclose(fd); }
if (fd != NULL) {
if ((int)fwrite(pidString, 1, len, fd) != len) {
INIT_LOGE("Failed to write %s pid:%s", service->writePidArgs.argv[i], pidString);
}
(void)fclose(fd);
} else {
INIT_LOGE("Failed to open %s.", service->writePidArgs.argv[i]);
}
if (realPath != NULL) {
free(realPath);
}
INIT_LOGD("ServiceStart writepid filename=%s, childPid=%s, ok", service->writePidArgs.argv[i], pidString);
} }
return SERVICE_SUCCESS;
} }
int ServiceStart(Service *service) int ServiceStart(Service *service)
{ {
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr."); INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
INIT_INFO_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name); INIT_ERROR_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name);
INIT_ERROR_CHECK(service->pathArgs.count > 0,
return SERVICE_FAILURE, "start service %s pathArgs is NULL.", service->name);
if (service->attribute & SERVICE_ATTR_INVALID) { if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("start service %s invalid.", service->name); INIT_LOGE("start service %s invalid.", service->name);
return SERVICE_FAILURE; return SERVICE_FAILURE;
} }
INIT_ERROR_CHECK(service->pathArgs != NULL, return SERVICE_FAILURE, "start service pathArgs is NULL."); struct stat pathStat = { 0 };
struct stat pathStat = {0};
service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP)); service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
INIT_ERROR_CHECK(stat(service->pathArgs[0], &pathStat) == 0, service->attribute |= SERVICE_ATTR_INVALID; if (stat(service->pathArgs.argv[0], &pathStat) != 0) {
return SERVICE_FAILURE, "start service %s invalid, please check %s.", service->name, service->pathArgs[0]); service->attribute |= SERVICE_ATTR_INVALID;
pid_t pid = fork(); INIT_LOGE("start service %s invalid, please check %s.", service->name, service->pathArgs.argv[0]);
return SERVICE_FAILURE;
}
int pid = fork();
if (pid == 0) { if (pid == 0) {
if (service->socketCfg != NULL) { // start socket service int ret = CreateServiceSocket(service->socketCfg);
INIT_ERROR_CHECK(DoCreateSocket(service->socketCfg) >= 0, _exit(0x7f), "Create Socket failed. "); if (ret < 0) {
INIT_LOGE("service %s exit! create socket failed!", service->name);
_exit(PROCESS_EXIT_CODE);
} }
if (service->attribute & SERVICE_ATTR_CONSOLE) { if (service->attribute & SERVICE_ATTR_CONSOLE) {
OpenConsole(); OpenConsole();
} }
INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(0x7f), // permissions
"service %s exit! set perms failed! err %d.", service->name, errno); if (SetPerms(service) != SERVICE_SUCCESS) {
WriteServicePid(service, getpid()); INIT_LOGE("service %s exit! set perms failed! err %d.", service->name, errno);
INIT_LOGI("service->name is %s ", service->name); _exit(PROCESS_EXIT_CODE);
#ifndef OHOS_LITE
if (service->importance != 0) {
INIT_ERROR_CHECK(setpriority(PRIO_PROCESS, 0, service->importance) == 0, _exit(0x7f),
"setpriority failed for %s, importance = %d", service->name, service->importance);
} }
// L2 Can not be reset env // write pid
INIT_CHECK_ONLY_ELOG(execv(service->pathArgs[0], service->pathArgs) == 0, if (WritePid(service) != SERVICE_SUCCESS) {
"service %s execve failed! err %d.", service->name, errno); INIT_LOGE("service %s exit! write pid failed!", service->name);
#else _exit(PROCESS_EXIT_CODE);
char* env[] = {"LD_LIBRARY_PATH=/storage/app/libs", NULL}; }
INIT_CHECK_ONLY_ELOG(execve(service->pathArgs[0], service->pathArgs, env) == 0, ServiceExec(service);
"service %s execve failed! err %d.", service->name, errno); _exit(PROCESS_EXIT_CODE);
#endif
_exit(0x7f); // 0x7f: user specified
} else if (pid < 0) { } else if (pid < 0) {
INIT_LOGE("start service %s fork failed!", service->name); INIT_LOGE("start service %s fork failed!", service->name);
return SERVICE_FAILURE; return SERVICE_FAILURE;
} }
INIT_LOGI("service %s starting pid %d", service->name, pid);
service->pid = pid; service->pid = pid;
#ifndef OHOS_LITE NotifyServiceChange(service->name, "running");
char paramName[PARAM_NAME_LEN_MAX] = {0};
int ret = snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", service->name);
INIT_CHECK_ONLY_ELOG(ret >= 0, "snprintf_s paramName error %d ", errno);
SystemWriteParam(paramName, "running");
#endif
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
int ServiceStop(Service *service) int ServiceStop(Service *service)
{ {
if (service == NULL) { INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "stop service failed! null ptr.");
INIT_LOGE("stop service failed! null ptr.");
return SERVICE_FAILURE;
}
service->attribute &= ~SERVICE_ATTR_NEED_RESTART; service->attribute &= ~SERVICE_ATTR_NEED_RESTART;
service->attribute |= SERVICE_ATTR_NEED_STOP; service->attribute |= SERVICE_ATTR_NEED_STOP;
if (service->pid <= 0) { if (service->pid <= 0) {
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
CloseServiceSocket(service->socketCfg);
if (kill(service->pid, SIGKILL) != 0) { if (kill(service->pid, SIGKILL) != 0) {
INIT_LOGE("stop service %s pid %d failed! err %d.", service->name, service->pid, errno); INIT_LOGE("stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
return SERVICE_FAILURE; return SERVICE_FAILURE;
} }
#ifndef OHOS_LITE NotifyServiceChange(service->name, "stopping");
char paramName[PARAM_NAME_LEN_MAX] = {0};
if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", service->name) < 0) {
INIT_LOGE("snprintf_s paramName error %d ", errno);
}
SystemWriteParam(paramName, "stopping");
#endif
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;
} }
...@@ -277,46 +260,37 @@ static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCo ...@@ -277,46 +260,37 @@ static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCo
static int ExecRestartCmd(const Service *service) static int ExecRestartCmd(const Service *service)
{ {
INIT_LOGI("ExecRestartCmd "); INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
if ((service == NULL) || (service->onRestart == NULL) || (service->onRestart->cmdLine == NULL)) { INIT_ERROR_CHECK(service->restartArg != NULL, return SERVICE_FAILURE, "restartArg is null");
return SERVICE_FAILURE;
}
for (int i = 0; i < service->onRestart->cmdNum; i++) { for (int i = 0; i < service->restartArg->cmdNum; i++) {
INIT_LOGI("SetOnRestart cmdLine->name %s cmdLine->cmdContent %s ", service->onRestart->cmdLine[i].name, INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
service->onRestart->cmdLine[i].cmdContent); DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent);
DoCmd(&service->onRestart->cmdLine[i]);
} }
free(service->onRestart->cmdLine); free(service->restartArg);
service->onRestart->cmdLine = NULL;
free(service->onRestart);
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
void ServiceReap(Service *service) void ServiceReap(Service *service)
{ {
if (service == NULL) { INIT_CHECK(service != NULL, return);
INIT_LOGE("reap service failed! null ptr."); INIT_LOGI("Reap service %s, pid %d.", service->name, service->pid);
return;
}
service->pid = -1; service->pid = -1;
#ifndef OHOS_LITE NotifyServiceChange(service->name, "stopped");
char paramName[PARAM_NAME_LEN_MAX] = {0};
if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", service->name) < 0) {
INIT_LOGE("snprintf_s paramName error %d ", errno);
}
SystemWriteParam(paramName, "stopped");
#endif
if (service->attribute & SERVICE_ATTR_INVALID) { if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("ServiceReap service %s invalid.", service->name); INIT_LOGE("Reap service %s invalid.", service->name);
return; return;
} }
CloseServiceSocket(service->socketCfg);
// stopped by system-init itself, no need to restart even if it is not one-shot service // stopped by system-init itself, no need to restart even if it is not one-shot service
if (service->attribute & SERVICE_ATTR_NEED_STOP) { if (service->attribute & SERVICE_ATTR_NEED_STOP) {
service->attribute &= (~SERVICE_ATTR_NEED_STOP); service->attribute &= (~SERVICE_ATTR_NEED_STOP);
service->crashCnt = 0; service->crashCnt = 0;
return; return;
} }
// for one-shot service // for one-shot service
if (service->attribute & SERVICE_ATTR_ONCE) { if (service->attribute & SERVICE_ATTR_ONCE) {
// no need to restart // no need to restart
...@@ -324,12 +298,14 @@ void ServiceReap(Service *service) ...@@ -324,12 +298,14 @@ void ServiceReap(Service *service)
service->attribute &= (~SERVICE_ATTR_NEED_STOP); service->attribute &= (~SERVICE_ATTR_NEED_STOP);
return; return;
} }
// the service could be restart even if it is one-shot service
} }
if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
if (CalculateCrashTime(service, CRITICAL_CRASH_TIME_LIMIT, CRITICAL_CRASH_COUNT_LIMIT) == false) { if (CalculateCrashTime(service, CRITICAL_CRASH_TIME_LIMIT, CRITICAL_CRASH_COUNT_LIMIT) == false) {
INIT_LOGE("Critical service \" %s \" crashed %d times, rebooting system", INIT_LOGE("Critical service \" %s \" crashed %d times, rebooting system",
service->name, CRITICAL_CRASH_COUNT_LIMIT); service->name, CRITICAL_CRASH_COUNT_LIMIT);
DoReboot("reboot"); ExecReboot("reboot");
} }
} else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) { } else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
if (CalculateCrashTime(service, CRASH_TIME_LIMIT, CRASH_COUNT_LIMIT) == false) { if (CalculateCrashTime(service, CRASH_TIME_LIMIT, CRASH_COUNT_LIMIT) == false) {
...@@ -337,10 +313,17 @@ void ServiceReap(Service *service) ...@@ -337,10 +313,17 @@ void ServiceReap(Service *service)
return; return;
} }
} }
if (service->onRestart != NULL) {
INIT_CHECK_ONLY_ELOG(ExecRestartCmd(service) == SERVICE_SUCCESS, "SetOnRestart fail "); int ret = 0;
if (service->restartArg != NULL) {
ret = ExecRestartCmd(service);
if (ret != SERVICE_SUCCESS) {
INIT_LOGE("Failed to exec restartArg for %s", service->name);
}
}
ret = ServiceStart(service);
if (ret != SERVICE_SUCCESS) {
INIT_LOGE("reap service %s start failed!", service->name);
} }
INIT_CHECK_ONLY_ELOG(ServiceStart(service) == SERVICE_SUCCESS, "reap service %s start failed!", service->name);
service->attribute &= (~SERVICE_ATTR_NEED_RESTART); service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
} }
/* /*
* Copyright (c) 2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/ */
#include "init.h"
#include "init_import.h" #include "init_jobs.h"
#include "init_log.h"
#include <unistd.h> #include "init_service_manager.h"
#include "cJSON.h" #include "init_utils.h"
#include "init_cmds.h"
#include "init_log.h" static void ParseAllImports(const cJSON *root);
#include "init_read_cfg.h"
#include "securec.h" static void ParseInitCfgContents(const char *cfgName, const cJSON *root)
{
#ifndef OHOS_LITE INIT_ERROR_CHECK(root != NULL, return, "Root is null");
static int ExtractCfgFile(char **cfgFile, const char *content) INIT_LOGI("Parse init cfg %s ", cfgName);
{
if ((!cfgFile) || (!content)) { ParseAllServices(root);
return -1; // parse jobs
} ParseAllJobs(root);
size_t cfgFileLen = strlen(content) + MAX_PARAM_VALUE_LEN + 1; // parse imports
if (cfgFileLen <= 0) { ParseAllImports(root);
return -1; }
}
if ((*cfgFile = malloc(cfgFileLen)) == NULL) { static int ParseInitCfg(const char *configFile, void *context)
INIT_LOGW("Failed to allocate memory to import cfg file. err = %d", errno); {
return -1; UNUSED(context);
} char *fileBuf = ReadFileToBuf(configFile);
return GetParamValue(content, *cfgFile, cfgFileLen); INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", configFile);
}
#endif cJSON *fileRoot = cJSON_Parse(fileBuf);
INIT_ERROR_CHECK(fileRoot != NULL, free(fileBuf);
void ParseAllImports(const cJSON *root) return -1, "Failed to parse json file %s", configFile);
{
cJSON *importAttr = cJSON_GetObjectItemCaseSensitive(root, "import"); ParseInitCfgContents(configFile, fileRoot);
char *cfgFile = NULL; cJSON_Delete(fileRoot);
if (!cJSON_IsArray(importAttr)) { free(fileBuf);
return; return 0;
} }
int importAttrSize = cJSON_GetArraySize(importAttr);
static void ParseAllImports(const cJSON *root)
for (int i = 0; i < importAttrSize; i++) { {
cJSON *importItem = cJSON_GetArrayItem(importAttr, i); char *tmpParamValue = malloc(PARAM_VALUE_LEN_MAX + 1);
if (!cJSON_IsString(importItem)) { INIT_ERROR_CHECK(tmpParamValue != 0, return, "Failed to alloc memory for param");
INIT_LOGE("Invalid type of import item. should be string");
return; cJSON *importAttr = cJSON_GetObjectItemCaseSensitive(root, "import");
} if (!cJSON_IsArray(importAttr)) {
char *importContent = cJSON_GetStringValue(importItem); free(tmpParamValue);
if (importContent == NULL) { return;
INIT_LOGE("cannot get import config file"); }
return; int importAttrSize = cJSON_GetArraySize(importAttr);
} for (int i = 0; i < importAttrSize; i++) {
// Only OHOS L2 support parameter. cJSON *importItem = cJSON_GetArrayItem(importAttr, i);
#ifndef OHOS_LITE if (!cJSON_IsString(importItem)) {
if (ExtractCfgFile(&cfgFile, importContent) < 0) { INIT_LOGE("Invalid type of import item. should be string");
INIT_LOGW("Failed to import from %s", importContent); break;
if (cfgFile != NULL) { }
free(cfgFile); char *importContent = cJSON_GetStringValue(importItem);
cfgFile = NULL; if (importContent == NULL) {
} INIT_LOGE("cannot get import config file");
continue; break;
} }
#else int ret = GetParamValue(importContent, strlen(importContent), tmpParamValue, PARAM_VALUE_LEN_MAX);
cfgFile = importContent; if (ret != 0) {
#endif INIT_LOGE("cannot get value for %s", importContent);
INIT_LOGI("Import %s...", cfgFile); continue;
ParseInitCfg(cfgFile); }
// Do not forget to free memory. INIT_LOGI("Import %s ...", tmpParamValue);
free(cfgFile); ParseInitCfg(tmpParamValue, NULL);
cfgFile = NULL; }
} free(tmpParamValue);
INIT_LOGD("parse import file done"); return;
return; }
}
void ReadConfig(void)
{
// parse cfg
if (InUpdaterMode() == 0) {
ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
ReadFileInDir(OTHER_CFG_PATH, ".cfg", ParseInitCfg, NULL);
} else {
ReadFileInDir("/etc", ".cfg", ParseInitCfg, NULL);
}
}
此差异已折叠。
/* /*
* Copyright (c) 2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* 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 "init_service_socket.h" #include "init_service_socket.h"
#include <ctype.h> #include <ctype.h>
...@@ -24,19 +23,29 @@ ...@@ -24,19 +23,29 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
#include "init_log.h" #include "init_log.h"
#include "init_service.h"
#include "securec.h" #include "securec.h"
#define HOS_SOCKET_DIR "/dev/unix/socket" #define HOS_SOCKET_DIR "/dev/unix/socket"
#define HOS_SOCKET_ENV_PREFIX "OHOS_SOCKET_" #define HOS_SOCKET_ENV_PREFIX "OHOS_SOCKET_"
#define MAX_SOCKET_ENV_PREFIX_LEN 64 #define MAX_SOCKET_ENV_PREFIX_LEN 64
#define MAX_SOCKET_FD_LEN 16 #define MAX_SOCKET_FD_LEN 16
static int CreateSocket(struct ServiceSocket *sockopt) static int GetSocketAddr(struct sockaddr_un *addr, const char *name)
{ {
if (sockopt == NULL || sockopt->name == NULL) { bzero(addr, sizeof(struct sockaddr_un));
return -1; addr->sun_family = AF_UNIX;
} size_t addrLen = sizeof(addr->sun_path);
int ret = snprintf_s(addr->sun_path, addrLen, addrLen - 1, HOS_SOCKET_DIR "/%s", name);
INIT_ERROR_CHECK(ret >= 0, return -1, "Failed to format addr %s", name);
return 0;
}
static int CreateSocket(ServiceSocket *sockopt)
{
INIT_ERROR_CHECK(sockopt != NULL, return SERVICE_FAILURE, "Invalid socket opt");
if (sockopt->sockFd >= 0) { if (sockopt->sockFd >= 0) {
close(sockopt->sockFd); close(sockopt->sockFd);
sockopt->sockFd = -1; sockopt->sockFd = -1;
...@@ -45,63 +54,53 @@ static int CreateSocket(struct ServiceSocket *sockopt) ...@@ -45,63 +54,53 @@ static int CreateSocket(struct ServiceSocket *sockopt)
INIT_ERROR_CHECK(sockopt->sockFd >= 0, return -1, "socket fail %d ", errno); INIT_ERROR_CHECK(sockopt->sockFd >= 0, return -1, "socket fail %d ", errno);
struct sockaddr_un addr; struct sockaddr_un addr;
bzero(&addr, sizeof(addr)); int ret = GetSocketAddr(&addr, sockopt->name);
addr.sun_family = AF_UNIX; INIT_ERROR_CHECK(ret == 0, return -1, "Failed to format addr %s", sockopt->name);
if (snprintf_s(addr.sun_path, sizeof(addr.sun_path), sizeof(addr.sun_path) - 1, HOS_SOCKET_DIR"/%s",
sockopt->name) < 0) { do {
return -1; ret = -1;
} if (access(addr.sun_path, F_OK)) {
if (access(addr.sun_path, F_OK) == 0) { INIT_LOGI("%s already exist, remove it", addr.sun_path);
INIT_LOGE("%s already exist, remove it", addr.sun_path);
if (unlink(addr.sun_path) != 0) {
INIT_LOGE("ulink fail err %d ", errno);
}
}
if (sockopt->passcred) {
int on = 1;
if (setsockopt(sockopt->sockFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
unlink(addr.sun_path); unlink(addr.sun_path);
close(sockopt->sockFd);
return -1;
} }
} if (sockopt->passcred) {
int on = 1;
if (bind(sockopt->sockFd, (struct sockaddr *)&addr, sizeof(addr))) { if (setsockopt(sockopt->sockFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
INIT_LOGE("Create socket for service %s failed: %d", sockopt->name, errno); break;
unlink(addr.sun_path); }
close(sockopt->sockFd); }
return -1; if (bind(sockopt->sockFd, (struct sockaddr *)&addr, sizeof(addr))) {
} INIT_LOGE("Create socket for service %s failed: %d", sockopt->name, errno);
break;
if (lchown(addr.sun_path, sockopt->uid, sockopt->gid)) { }
unlink(addr.sun_path); if (lchown(addr.sun_path, sockopt->uid, sockopt->gid)) {
INIT_LOGE("lchown fail %d ", errno);
break;
}
if (fchmodat(AT_FDCWD, addr.sun_path, sockopt->perm, AT_SYMLINK_NOFOLLOW)) {
INIT_LOGE("fchmodat fail %d ", errno);
break;
}
ret = 0;
} while (0);
if (ret != 0) {
close(sockopt->sockFd); close(sockopt->sockFd);
INIT_LOGE("lchown fail %d ", errno);
return -1;
}
if (fchmodat(AT_FDCWD, addr.sun_path, sockopt->perm, AT_SYMLINK_NOFOLLOW)) {
unlink(addr.sun_path); unlink(addr.sun_path);
close(sockopt->sockFd);
INIT_LOGE("fchmodat fail %d ", errno);
return -1; return -1;
} }
INIT_LOGI("CreateSocket success "); INIT_LOGI("CreateSocket %s success", sockopt->name);
return sockopt->sockFd; return sockopt->sockFd;
} }
static int SetSocketEnv(int fd, const char *name) static int SetSocketEnv(int fd, const char *name)
{ {
if (name == NULL) { INIT_ERROR_CHECK(name != NULL, return SERVICE_FAILURE, "Invalid name");
return -1; char pubName[MAX_SOCKET_ENV_PREFIX_LEN] = { 0 };
} char val[MAX_SOCKET_FD_LEN] = { 0 };
char pubName[MAX_SOCKET_ENV_PREFIX_LEN] = {0}; if (snprintf_s(pubName, sizeof(pubName), sizeof(pubName) - 1, HOS_SOCKET_ENV_PREFIX "%s", name) < 0) {
char val[MAX_SOCKET_FD_LEN] = {0};
if (snprintf_s(pubName, MAX_SOCKET_ENV_PREFIX_LEN, MAX_SOCKET_ENV_PREFIX_LEN - 1,
HOS_SOCKET_ENV_PREFIX"%s", name) < 0) {
return -1; return -1;
} }
if (snprintf_s(val, MAX_SOCKET_FD_LEN, MAX_SOCKET_FD_LEN - 1, "%d", fd) < 0) { if (snprintf_s(val, sizeof(val), sizeof(val) - 1, "%d", fd) < 0) {
return -1; return -1;
} }
int ret = setenv(pubName, val, 1); int ret = setenv(pubName, val, 1);
...@@ -113,20 +112,15 @@ static int SetSocketEnv(int fd, const char *name) ...@@ -113,20 +112,15 @@ static int SetSocketEnv(int fd, const char *name)
return 0; return 0;
} }
int DoCreateSocket(struct ServiceSocket *sockopt) int CreateServiceSocket(ServiceSocket *sockopt)
{ {
if (sockopt == NULL) { INIT_CHECK(sockopt != NULL, return 0);
return -1; ServiceSocket *tmpSock = sockopt;
}
struct ServiceSocket *tmpSock = sockopt;
while (tmpSock != NULL) { while (tmpSock != NULL) {
int fd = CreateSocket(tmpSock); int fd = CreateSocket(tmpSock);
if (fd < 0) { if (fd < 0) {
return -1; return -1;
} }
if (tmpSock->name == NULL) {
return -1;
}
int ret = SetSocketEnv(fd, tmpSock->name); int ret = SetSocketEnv(fd, tmpSock->name);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
...@@ -136,3 +130,20 @@ int DoCreateSocket(struct ServiceSocket *sockopt) ...@@ -136,3 +130,20 @@ int DoCreateSocket(struct ServiceSocket *sockopt)
return 0; return 0;
} }
void CloseServiceSocket(ServiceSocket *sockopt)
{
INIT_CHECK(sockopt != NULL, return);
struct sockaddr_un addr;
ServiceSocket *tmpSock = sockopt;
while (tmpSock != NULL) {
if (sockopt->sockFd >= 0) {
close(sockopt->sockFd);
sockopt->sockFd = -1;
}
if (GetSocketAddr(&addr, sockopt->name) == 0) {
unlink(addr.sun_path);
}
tmpSock = tmpSock->next;
}
return;
}
\ No newline at end of file
/*
* Copyright (c) 2020 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 "init.h"
#include "init_log.h"
#include "init_jobs.h"
#ifndef __LINUX__
#include "init_stage.h"
#endif
#include "parameter.h"
#include "securec.h"
static void PrintSysInfo(void)
{
const char *sysInfo = GetVersionId();
if (sysInfo != NULL) {
INIT_LOGE("%s", sysInfo);
return;
}
}
void SystemInit(void)
{
SignalInit();
}
void LogInit(void)
{
}
void SystemPrepare(void)
{
PrintSysInfo();
}
void SystemConfig(void)
{
// read config
ReadConfig();
// dump config
#ifdef OHOS_SERVICE_DUMP
DumpAllServices();
#endif
// execute init
DoJob("pre-init");
#ifndef __LINUX__
TriggerStage(EVENT1, EVENT1_WAITTIME, QS_STAGE1);
#endif
DoJob("init");
#ifndef __LINUX__
TriggerStage(EVENT2, EVENT2_WAITTIME, QS_STAGE2);
#endif
DoJob("post-init");
#ifndef __LINUX__
TriggerStage(EVENT3, EVENT3_WAITTIME, QS_STAGE3);
InitStageFinished();
#endif
ReleaseAllJobs();
}
void SystemRun(void)
{
while (1) {
// pause only returns when a signal was caught and the signal-catching function returned.
// pause only returns -1, no need to process the return value.
(void)pause();
}
}
\ No newline at end of file
/*
* Copyright (c) 2020-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 <stdlib.h>
#include <string.h>
#include "init.h"
#include "init_cmds.h"
#include "init_log.h"
#include "init_utils.h"
#include "securec.h"
int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen)
{
return (strncpy_s(paramValue, paramLen, symValue, symLen) == EOK) ? 0 : -1;
}
static void DoExec(const struct CmdArgs *ctx, const char *cmdContent)
{
UNUSED(ctx);
// format: exec /xxx/xxx/xxx xxx
pid_t pid = fork();
if (pid < 0) {
INIT_LOGE("DoExec: failed to fork child process to exec \"%s\"", cmdContent);
return;
}
if (pid == 0) {
struct CmdArgs *subCtx = GetCmdArg(cmdContent, " ", SUPPORT_MAX_ARG_FOR_EXEC);
if (subCtx == NULL || subCtx->argv[0] == NULL) {
INIT_LOGE("DoExec: invalid arguments :%s", cmdContent);
_exit(0x7f);
}
int ret = execve(subCtx->argv[0], subCtx->argv, NULL);
if (ret == -1) {
INIT_LOGE("DoExec: execute \"%s\" failed: %d.", cmdContent, errno);
}
FreeCmdArg(subCtx);
_exit(0x7f);
}
return;
}
static const struct CmdTable g_cmdTable[] = { { "exec ", 1, 10, DoExec } };
const struct CmdTable *GetCmdTable(int *number)
{
*number = (int)ARRAY_LENGTH(g_cmdTable);
return g_cmdTable;
}
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* 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 "init_jobs.h" #include "init_jobs.h"
#include <stdio.h> #include <stdio.h>
...@@ -25,28 +24,31 @@ ...@@ -25,28 +24,31 @@
#define JOBS_ARR_NAME_IN_JSON "jobs" #define JOBS_ARR_NAME_IN_JSON "jobs"
#define CMDS_ARR_NAME_IN_JSON "cmds" #define CMDS_ARR_NAME_IN_JSON "cmds"
#define MAX_JOBS_COUNT 100 #define MAX_JOBS_COUNT 100
static Job* g_jobs = NULL; static Job *g_jobs = NULL;
static int g_jobCnt = 0; static int g_jobCnt = 0;
void DumpAllJobs(void) void DumpAllJobs(void)
{ {
INIT_LOGD("Ready to dump all jobs:"); INIT_LOGD("Start to dump all jobs...");
for (int i = 0; i < g_jobCnt; i++) { for (int i = 0; i < g_jobCnt; i++) {
INIT_LOGD("\tjob name: %s", g_jobs[i].name); INIT_LOGD("\tjob name: %s", g_jobs[i].name);
if (g_jobs[i].cmdLines == NULL) {
continue;
}
INIT_LOGD("\tlist all commands:"); INIT_LOGD("\tlist all commands:");
for (int j = 0; j < g_jobs[i].cmdLinesCnt; j++) { for (int j = 0; j < g_jobs[i].cmdLines->cmdNum; j++) {
INIT_LOGD("\t\tcommand name : %s, command options: %s", CmdLine *cmd = &g_jobs[i].cmdLines->cmds[j];
g_jobs[i].cmdLines[j].name, g_jobs[i].cmdLines[j].cmdContent); INIT_LOGD("\t\tcommand: %s %s", GetCmdKey(cmd->cmdIndex), cmd->cmdContent);
} }
} }
INIT_LOGD("To dump all jobs finished"); INIT_LOGD("Finish dump all jobs");
} }
static int GetJobName(const cJSON* jobItem, Job* resJob) static int GetJobName(const cJSON *jobItem, Job *resJob)
{ {
char* jobNameStr = cJSON_GetStringValue(cJSON_GetObjectItem(jobItem, "name")); char *jobNameStr = cJSON_GetStringValue(cJSON_GetObjectItem(jobItem, "name"));
if (jobNameStr == NULL) { if (jobNameStr == NULL) {
return 0; return 0;
} }
...@@ -59,7 +61,7 @@ static int GetJobName(const cJSON* jobItem, Job* resJob) ...@@ -59,7 +61,7 @@ static int GetJobName(const cJSON* jobItem, Job* resJob)
return 1; return 1;
} }
static void ParseJob(const cJSON* jobItem, Job* resJob) static void ParseJob(const cJSON *jobItem, Job *resJob)
{ {
if (!GetJobName(jobItem, resJob)) { if (!GetJobName(jobItem, resJob)) {
INIT_LOGE("get JobName failed"); INIT_LOGE("get JobName failed");
...@@ -67,52 +69,27 @@ static void ParseJob(const cJSON* jobItem, Job* resJob) ...@@ -67,52 +69,27 @@ static void ParseJob(const cJSON* jobItem, Job* resJob)
return; return;
} }
cJSON* cmdsItem = cJSON_GetObjectItem(jobItem, CMDS_ARR_NAME_IN_JSON); cJSON *cmdsItem = cJSON_GetObjectItem(jobItem, CMDS_ARR_NAME_IN_JSON);
if (!cJSON_IsArray(cmdsItem)) { if (!cJSON_IsArray(cmdsItem)) {
INIT_LOGE("job %s is not an arrary", resJob->name); INIT_LOGE("job %s is not an arrary", resJob->name);
return; return;
} }
int ret = GetCmdLinesFromJson(cmdsItem, &resJob->cmdLines);
int cmdLinesCnt = cJSON_GetArraySize(cmdsItem); if (ret != 0) {
if (cmdLinesCnt <= 0) { // empty job, no cmd INIT_LOGE("ParseJob, faild to get cmds for job!");
INIT_LOGE("empty job \"%s\"", resJob->name);
return;
}
INIT_LOGD("job = %s, cmdLineCnt = %d", resJob->name, cmdLinesCnt);
if (cmdLinesCnt > MAX_CMD_CNT_IN_ONE_JOB) {
INIT_LOGE("ParseAllJobs, too many cmds[cnt %d] in one job, it should not exceed %d.",
cmdLinesCnt, MAX_CMD_CNT_IN_ONE_JOB);
return;
}
resJob->cmdLines = (CmdLine*)malloc(cmdLinesCnt * sizeof(CmdLine));
if (resJob->cmdLines == NULL) {
INIT_LOGE("allocate memory for command line failed");
return; return;
} }
return;
if (memset_s(resJob->cmdLines, cmdLinesCnt * sizeof(CmdLine), 0, cmdLinesCnt * sizeof(CmdLine)) != EOK) {
free(resJob->cmdLines);
resJob->cmdLines = NULL;
return;
}
resJob->cmdLinesCnt = cmdLinesCnt;
for (int i = 0; i < cmdLinesCnt; ++i) {
char* cmdLineStr = cJSON_GetStringValue(cJSON_GetArrayItem(cmdsItem, i));
ParseCmdLine(cmdLineStr, &(resJob->cmdLines[i]));
}
} }
void ParseAllJobs(const cJSON* fileRoot) void ParseAllJobs(const cJSON *fileRoot)
{ {
if (fileRoot == NULL) { if (fileRoot == NULL) {
INIT_LOGE("ParseAllJobs, input fileRoot is NULL!"); INIT_LOGE("ParseAllJobs, input fileRoot is NULL!");
return; return;
} }
cJSON* jobArr = cJSON_GetObjectItemCaseSensitive(fileRoot, JOBS_ARR_NAME_IN_JSON); cJSON *jobArr = cJSON_GetObjectItemCaseSensitive(fileRoot, JOBS_ARR_NAME_IN_JSON);
if (!cJSON_IsArray(jobArr)) { if (!cJSON_IsArray(jobArr)) {
INIT_LOGE("ParseAllJobs, job item is not array!"); INIT_LOGE("ParseAllJobs, job item is not array!");
return; return;
...@@ -125,13 +102,13 @@ void ParseAllJobs(const cJSON* fileRoot) ...@@ -125,13 +102,13 @@ void ParseAllJobs(const cJSON* fileRoot)
return; return;
} }
Job* retJobs = (Job*)realloc(g_jobs, sizeof(Job) * (g_jobCnt + jobArrSize)); Job *retJobs = (Job *)realloc(g_jobs, sizeof(Job) * (g_jobCnt + jobArrSize));
if (retJobs == NULL) { if (retJobs == NULL) {
INIT_LOGE("ParseAllJobs, malloc failed! job arrSize %d.", jobArrSize); INIT_LOGE("ParseAllJobs, malloc failed! job arrSize %d.", jobArrSize);
return; return;
} }
Job* tmp = retJobs + g_jobCnt; Job *tmp = retJobs + g_jobCnt;
if (memset_s(tmp, sizeof(Job) * jobArrSize, 0, sizeof(Job) * jobArrSize) != EOK) { if (memset_s(tmp, sizeof(Job) * jobArrSize, 0, sizeof(Job) * jobArrSize) != EOK) {
INIT_LOGE("ParseAllJobs, memset_s failed."); INIT_LOGE("ParseAllJobs, memset_s failed.");
free(retJobs); free(retJobs);
...@@ -140,14 +117,14 @@ void ParseAllJobs(const cJSON* fileRoot) ...@@ -140,14 +117,14 @@ void ParseAllJobs(const cJSON* fileRoot)
} }
for (int i = 0; i < jobArrSize; ++i) { for (int i = 0; i < jobArrSize; ++i) {
cJSON* jobItem = cJSON_GetArrayItem(jobArr, i); cJSON *jobItem = cJSON_GetArrayItem(jobArr, i);
ParseJob(jobItem, &(tmp[i])); ParseJob(jobItem, &(tmp[i]));
} }
g_jobs = retJobs; g_jobs = retJobs;
g_jobCnt += jobArrSize; g_jobCnt += jobArrSize;
} }
void DoJob(const char* jobName) void DoJob(const char *jobName)
{ {
if (jobName == NULL) { if (jobName == NULL) {
INIT_LOGE("DoJob, input jobName NULL!"); INIT_LOGE("DoJob, input jobName NULL!");
...@@ -157,9 +134,12 @@ void DoJob(const char* jobName) ...@@ -157,9 +134,12 @@ void DoJob(const char* jobName)
INIT_LOGD("Call job with name %s", jobName); INIT_LOGD("Call job with name %s", jobName);
for (int i = 0; i < g_jobCnt; ++i) { for (int i = 0; i < g_jobCnt; ++i) {
if (strncmp(jobName, g_jobs[i].name, strlen(g_jobs[i].name)) == 0) { if (strncmp(jobName, g_jobs[i].name, strlen(g_jobs[i].name)) == 0) {
CmdLine* cmdLines = g_jobs[i].cmdLines; CmdLines *cmdLines = g_jobs[i].cmdLines;
for (int j = 0; j < g_jobs[i].cmdLinesCnt; ++j) { if (cmdLines == NULL) {
DoCmd(&(cmdLines[j])); continue;
}
for (int j = 0; j < cmdLines->cmdNum; ++j) {
DoCmdByIndex(cmdLines->cmds[j].cmdIndex, cmdLines->cmds[j].cmdContent);
} }
} }
} }
...@@ -174,13 +154,10 @@ void ReleaseAllJobs(void) ...@@ -174,13 +154,10 @@ void ReleaseAllJobs(void)
for (int i = 0; i < g_jobCnt; ++i) { for (int i = 0; i < g_jobCnt; ++i) {
if (g_jobs[i].cmdLines != NULL) { if (g_jobs[i].cmdLines != NULL) {
free(g_jobs[i].cmdLines); free(g_jobs[i].cmdLines);
g_jobs[i].cmdLines = NULL;
g_jobs[i].cmdLinesCnt = 0;
} }
} }
free(g_jobs); free(g_jobs);
g_jobs = NULL; g_jobs = NULL;
g_jobCnt = 0; g_jobCnt = 0;
} }
\ No newline at end of file
/*
* Copyright (c) 2020-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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/reboot.h>
#include "init.h"
#include "init_log.h"
void ExecReboot(const char *value)
{
UNUSED(value);
int ret = reboot(RB_AUTOBOOT);
if (ret != 0) {
INIT_LOGE("reboot failed! syscall ret %d, err %d.", ret, errno);
}
return;
}
/*
* Copyright (c) 2020-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 "init_service.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include "init.h"
#include "init_log.h"
#include "init_service_manager.h"
#include "securec.h"
void NotifyServiceChange(const char *serviceName, const char *change)
{
UNUSED(serviceName);
UNUSED(change);
}
int IsForbidden(const char *fieldStr)
{
size_t fieldLen = strlen(fieldStr);
size_t forbidStrLen = strlen(BIN_SH_NOT_ALLOWED);
if (fieldLen == forbidStrLen) {
if (strncmp(fieldStr, BIN_SH_NOT_ALLOWED, fieldLen) == 0) {
return 1;
}
return 0;
} else if (fieldLen > forbidStrLen) {
// "/bin/shxxxx" is valid but "/bin/sh xxxx" is invalid
if (strncmp(fieldStr, BIN_SH_NOT_ALLOWED, forbidStrLen) == 0) {
if (fieldStr[forbidStrLen] == ' ') {
return 1;
}
}
return 0;
} else {
return 0;
}
}
int SetImportantValue(Service *service, const char *attrName, int value, int flag)
{
UNUSED(attrName);
UNUSED(flag);
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Set service attr failed! null ptr.");
if (value != 0) {
service->attribute |= SERVICE_ATTR_IMPORTANT;
}
return SERVICE_SUCCESS;
}
int ServiceExec(const Service *service)
{
INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
return SERVICE_FAILURE, "Exec service failed! null ptr.");
INIT_LOGI("service->name is %s ", service->name);
char *env[] = { "LD_LIBRARY_PATH=/storage/app/libs", NULL };
if (execve(service->pathArgs.argv[0], service->pathArgs.argv, env) != 0) {
INIT_LOGE("service %s execve failed! err %d.", service->name, errno);
return errno;
}
return SERVICE_SUCCESS;
}
\ No newline at end of file
/*
* Copyright (c) 2020-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 <signal.h>
#include <stdio.h>
#include <sys/wait.h>
#include "init_adapter.h"
#include "init_log.h"
#include "init_service_manager.h"
void ReapService(Service *service)
{
if (service == NULL) {
return;
}
if (service->attribute & SERVICE_ATTR_IMPORTANT) {
// important process exit, need to reboot system
service->pid = -1;
StopAllServices(0);
RebootSystem();
}
ServiceReap(service);
}
static void SigHandler(int sig)
{
switch (sig) {
case SIGCHLD: {
pid_t sigPID;
int procStat = 0;
while (1) {
sigPID = waitpid(-1, &procStat, WNOHANG);
if (sigPID <= 0) {
break;
}
CheckWaitPid(sigPID);
ReapService(GetServiceByPid(sigPID));
}
break;
}
case SIGTERM: {
StopAllServices(0);
break;
}
default:
break;
}
}
void SignalInit(void)
{
struct sigaction act;
act.sa_handler = SigHandler;
act.sa_flags = SA_RESTART;
(void)sigfillset(&act.sa_mask);
sigaction(SIGCHLD, &act, NULL);
sigaction(SIGTERM, &act, NULL);
}
\ No newline at end of file
...@@ -12,26 +12,28 @@ ...@@ -12,26 +12,28 @@
* 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 <stdio.h>
#include "init.h"
#include "init_log.h"
#ifndef BASE_STARTUP_INITLITE_READ_CFG_H static const pid_t INIT_PROCESS_PID = 1;
#define BASE_STARTUP_INITLITE_READ_CFG_H int main(int argc, char* const argv[])
{
#ifdef __cplusplus int isSecondStage = 0;
#if __cplusplus if (argc == 2 && (strcmp(argv[1], "--second-stage") == 0)) {
extern "C" { isSecondStage = 1;
#endif }
#endif if (getpid() != INIT_PROCESS_PID) {
#define INIT_CONFIGURATION_FILE "/etc/init.cfg" INIT_LOGE("Process id error %d!", getpid());
#define MAX_PATH_ARGS_CNT 20 return 0;
#define MAX_ONE_ARG_LEN 200 // max length of one param/path }
LogInit();
void InitReadCfg(); if (isSecondStage == 0) {
void ParseInitCfg(const char *configFile); SystemPrepare();
}
#ifdef __cplusplus SystemInit();
#if __cplusplus SystemExecuteRcs();
SystemConfig();
SystemRun();
return 0;
} }
#endif
#endif
#endif // BASE_STARTUP_INITLITE_READ_CFG_H
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,14 +12,15 @@ ...@@ -12,14 +12,15 @@
* 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 "device.h" #include "device.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/major.h> #include <linux/major.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include "init_log.h" #include "init_log.h"
#define DEFAULT_RW_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) #define DEFAULT_RW_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
...@@ -62,9 +63,6 @@ void MountBasicFs(void) ...@@ -62,9 +63,6 @@ void MountBasicFs(void)
void CreateDeviceNode(void) void CreateDeviceNode(void)
{ {
if (mknod("/dev/kmsg", S_IFCHR | DEFAULT_NO_AUTHORITY_MODE, makedev(MEM_MAJOR, DEV_KMSG_MINOR)) != 0) {
INIT_LOGE("Create /dev/kmsg device node failed. %s", strerror(errno));
}
if (mknod("/dev/null", S_IFCHR | DEFAULT_RW_MODE, makedev(MEM_MAJOR, DEV_NULL_MINOR)) != 0) { if (mknod("/dev/null", S_IFCHR | DEFAULT_RW_MODE, makedev(MEM_MAJOR, DEV_NULL_MINOR)) != 0) {
INIT_LOGE("Create /dev/null device node failed. %s", strerror(errno)); INIT_LOGE("Create /dev/null device node failed. %s", strerror(errno));
} }
......
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -12,155 +12,132 @@ ...@@ -12,155 +12,132 @@
* 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 "init.h"
#include "init_read_cfg.h"
#include <errno.h> #include <errno.h>
#include <dirent.h>
#include <linux/capability.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <signal.h>
#include <sys/sysmacros.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <sys/types.h>
#include <linux/major.h>
#include "init_import.h" #include "device.h"
#include "init_jobs.h"
#include "init_log.h" #include "init_log.h"
#include "init_perms.h" #include "init_mount.h"
#include "init_service_manager.h"
#include "init_utils.h"
#ifndef OHOS_LITE
#include "init_param.h" #include "init_param.h"
#endif #include "init_utils.h"
#include "securec.h" #include "securec.h"
#ifndef __LINUX__ #include "switch_root.h"
#ifdef OHOS_LITE
#include "init_stage.h"
#endif
#endif
#define FILE_NAME_MAX_SIZE 100 void SystemInit(void)
static void ParseInitCfgContents(const cJSON *root)
{ {
if (root == NULL) { SignalInit();
INIT_LOGE("ParseInitCfgContents root is NULL"); MakeDirRecursive("/dev/unix/socket", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
return;
}
// parse services
ParseAllServices(root);
#ifdef OHOS_LITE
// parse jobs
ParseAllJobs(root);
#else
ParseTriggerConfig(root);
#endif
// parse imports
ParseAllImports(root);
} }
void ParseInitCfg(const char *configFile) void LogInit(void)
{ {
if (configFile == NULL || *configFile == '\0') { CloseStdio();
INIT_LOGE("Invalid config file"); int ret = mknod("/dev/kmsg", S_IFCHR | S_IWUSR | S_IRUSR,
return; makedev(MEM_MAJOR, DEV_KMSG_MINOR));
if (ret == 0) {
OpenLogDevice();
} }
}
char *fileBuf = ReadFileToBuf(configFile); static pid_t StartUeventd(void)
if (fileBuf == NULL) { {
INIT_LOGE("Read %s failed", configFile); char *const argv[] = {
return; "/bin/ueventd",
NULL,
};
pid_t pid = fork();
if (pid < 0) {
INIT_LOGE("Failed to fork child process");
} }
cJSON* fileRoot = cJSON_Parse(fileBuf); if (pid == 0) {
free(fileBuf); if (execv(argv[0], argv) != 0) {
fileBuf = NULL; INIT_LOGE("service %s execve failed! err %d.", argv[0], errno);
}
if (fileRoot == NULL) { _exit(0x7f); // 0x7f: user specified
INIT_LOGE("InitReadCfg, parse failed! please check file %s format.", configFile);
return;
} }
ParseInitCfgContents(fileRoot); return pid;
// Release JSON object
cJSON_Delete(fileRoot);
return;
} }
static void ReadCfgs(const char *dirPath) static void StartInitSecondStage(void)
{ {
DIR *pDir = opendir(dirPath); pid_t ueventPid = StartUeventd();
if (pDir == NULL) { if (ueventPid < 0) {
INIT_LOGE("ParseCfgs open cfg dir :%s failed.%d", dirPath, errno); INIT_LOGE("Failed to start ueventd");
return; abort();
} }
struct dirent *dp; if (MountRequriedPartitions() < 0) {
while ((dp = readdir(pDir)) != NULL) { // If mount required partitions failure.
char fileName[FILE_NAME_MAX_SIZE]; // There is no necessary to continue.
if (snprintf_s(fileName, FILE_NAME_MAX_SIZE, FILE_NAME_MAX_SIZE - 1, "%s/%s", dirPath, dp->d_name) == -1) { // Just abort
INIT_LOGE("ParseCfgs snprintf_s failed."); INIT_LOGE("Mount requried partitions failed");
closedir(pDir); abort();
return; }
} // Kill ueventd, because init second stage will start it again.
struct stat st; (void)kill(ueventPid, SIGKILL);
if (stat(fileName, &st) == 0) { // The init process in ramdisk has done its job.
if (strstr(dp->d_name, ".cfg") == NULL) { // It's ready to switch to system partition.
continue; // The system partition mounted in first stage to /usr
} // Because the directory /system is in use. we cannot use it.
INIT_LOGI("ReadCfgs :%s from %s success.", fileName, dirPath); // After switch root. /usr will become new root.
ParseInitCfg(fileName); SwitchRoot("/usr");
} // Execute init second stage
char *const args[] = {
"/bin/init",
"--second-stage",
NULL,
};
if (execv("/bin/init", args) != 0) {
INIT_LOGE("Failed to exec \"/bin/init\", err = %d", errno);
exit(-1);
} }
closedir(pDir);
return;
} }
static void ParseOtherCfgs() void SystemPrepare(void)
{ {
ReadCfgs("/system/etc/init"); MountBasicFs();
return; // Make sure init log always output to /dev/kmsg.
EnableDevKmsg();
CreateDeviceNode();
// Only ohos normal system support
// two stages of init.
// If we are in updater mode, only one stage of init,
if (InUpdaterMode() == 0) {
StartInitSecondStage();
}
} }
void InitReadCfg() void SystemConfig(void)
{ {
#ifndef OHOS_LITE
InitParamService(); InitParamService();
// parse parameters
LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL); LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_NORMAL); LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_NORMAL);
LoadDefaultParams("/system/etc/param", LOAD_PARAM_ONLY_ADD); LoadDefaultParams("/system/etc/param", LOAD_PARAM_ONLY_ADD);
#endif
ParseInitCfg(INIT_CONFIGURATION_FILE); // read config
ParseOtherCfgs(); ReadConfig();
INIT_LOGI("Parse init config file done."); INIT_LOGI("Parse init config file done.");
// dump config
#ifdef OHOS_SERVICE_DUMP #ifdef OHOS_SERVICE_DUMP
DumpAllServices(); DumpAllServices();
DumpParametersAndTriggers();
#endif #endif
#ifdef OHOS_LITE // execute init
// do jobs
DoJob("pre-init");
#ifndef __LINUX__
TriggerStage(EVENT1, EVENT1_WAITTIME, QS_STAGE1);
#endif
DoJob("init");
#ifndef __LINUX__
TriggerStage(EVENT2, EVENT2_WAITTIME, QS_STAGE2);
#endif
DoJob("post-init");
#ifndef __LINUX__
TriggerStage(EVENT3, EVENT3_WAITTIME, QS_STAGE3);
InitStageFinished();
#endif
ReleaseAllJobs();
#else
PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init")); PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init"));
PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init")); PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init"));
PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init")); PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init"));
#endif
} }
void SystemRun(void)
{
StartParamService();
}
此差异已折叠。
/* /*
* Copyright (c) 2020 Huawei Device Co., Ltd. * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -13,9 +13,10 @@ ...@@ -13,9 +13,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef INIT_REBOOT_H #include "init_jobs.h"
#define INIT_REBOOT_H #include "init_param.h"
void DoReboot(const char *value); void ParseAllJobs(const cJSON *fileRoot)
{
#endif ParseTriggerConfig(fileRoot);
}
\ No newline at end of file
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "device.h"
#include "fs_manager/fs_manager.h"
#include "init.h"
#include "init_cmds.h"
#include "init_log.h"
#include "securec.h"
// This function will malloc memory.
// Do not forget to free it after used.
static char *GetExpandFileName(const char *fileName)
{
if (fileName == NULL) {
return NULL;
}
size_t expandSize = strlen(fileName) + PARAM_VALUE_LEN_MAX + 1;
char *expandName = (char *)calloc(sizeof(char), expandSize);
if (expandName == NULL) {
INIT_LOGE("Failed to allocate memory for file name \" %s \"", fileName);
return NULL;
}
int ret = GetParamValue(fileName, strlen(fileName), expandName, expandSize);
INIT_ERROR_CHECK(ret == 0, free(expandName);
return NULL, "Failed to get value for %s", fileName);
return expandName;
}
int MountRequriedPartitions(void)
{
const char *fstabFiles[] = {"/etc/fstab.required", NULL};
int i = 0;
int rc = -1;
while (fstabFiles[i] != NULL) {
char *fstabFile = GetExpandFileName(fstabFiles[i]);
if (fstabFile != NULL) {
if (access(fstabFile, F_OK) == 0) {
INIT_LOGI("Mount required partition from %s", fstabFile);
rc = MountAllWithFstabFile(fstabFile, 1);
} else {
INIT_LOGE("Cannot access fstab file \" %s \"", fstabFile);
}
free(fstabFile);
fstabFile = NULL;
}
if (rc == 0) {
break;
}
i++;
}
return rc;
}
\ No newline at end of file
...@@ -12,10 +12,8 @@ ...@@ -12,10 +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.
*/ */
#ifndef BASE_STARTUP_INITLITE_IMPORT_H
#define BASE_STARTUP_INITLITE_IMPORT_H
#include "cJSON.h" #ifndef BASE_STARTUP_INITLITE_MOUNT_H
void ParseAllImports(const cJSON *root); #define BASE_STARTUP_INITLITE_MOUNT_H
int MountRequriedPartitions(void);
#endif #endif
\ No newline at end of file
/*
* Copyright (c) 2020-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 "init_service.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>
#include "init.h"
#include "init_log.h"
#include "init_param.h"
#include "securec.h"
#define MIN_IMPORTANT_LEVEL (-20)
#define MAX_IMPORTANT_LEVEL 19
void NotifyServiceChange(const char *serviceName, const char *change)
{
char paramName[PARAM_NAME_LEN_MAX] = { 0 };
if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", serviceName) < 0) {
INIT_LOGE("snprintf_s paramName error %d ", errno);
}
SystemWriteParam(paramName, change);
}
int IsForbidden(const char *fieldStr)
{
UNUSED(fieldStr);
return 0;
}
int SetImportantValue(Service *service, const char *attrName, int value, int flag)
{
UNUSED(attrName);
UNUSED(flag);
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Set service attr failed! null ptr.");
if (value >= MIN_IMPORTANT_LEVEL && value <= MAX_IMPORTANT_LEVEL) { // -20~19
service->attribute |= SERVICE_ATTR_IMPORTANT;
service->importance = value;
} else {
INIT_LOGE("Importance level = %d, is not between -20 and 19, error", value);
return SERVICE_FAILURE;
}
return SERVICE_SUCCESS;
}
int ServiceExec(const Service *service)
{
INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
return SERVICE_FAILURE, "Exec service failed! null ptr.");
if (service->importance != 0) {
if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
INIT_LOGE("setpriority failed for %s, importance = %d", service->name, service->importance);
_exit(0x7f); // 0x7f: user specified
}
}
// L2 Can not be reset env
if (execv(service->pathArgs.argv[0], service->pathArgs.argv) != 0) {
INIT_LOGE("service %s execve failed! err %d.", service->name, errno);
}
return SERVICE_SUCCESS;
}
\ No newline at end of file
此差异已折叠。
文件模式从 100644 更改为 100755
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
*/ */
#include "init_log.h" #include "init_log.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -34,22 +33,15 @@ ...@@ -34,22 +33,15 @@
static InitLogLevel g_logLevel = INIT_INFO; static InitLogLevel g_logLevel = INIT_INFO;
static const char *LOG_LEVEL_STR[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" }; static const char *LOG_LEVEL_STR[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
void SetLogLevel(InitLogLevel logLevel) void SetInitLogLevel(InitLogLevel logLevel)
{ {
g_logLevel = logLevel; g_logLevel = logLevel;
} }
#ifdef OHOS_LITE #ifdef OHOS_LITE
static LogLevel g_hiLogLevel = LOG_INFO; void InitToHiLog(InitLogLevel logLevel, const char *fmt, ...)
void SetHiLogLevel(LogLevel logLevel)
{
g_hiLogLevel = logLevel;
}
void InitToHiLog(LogLevel logLevel, const char *fmt, ...)
{ {
if (logLevel < g_hiLogLevel) { if (logLevel < g_logLevel) {
return; return;
} }
...@@ -84,7 +76,7 @@ void EnableDevKmsg(void) ...@@ -84,7 +76,7 @@ void EnableDevKmsg(void)
if (fd < 0) { if (fd < 0) {
return; return;
} }
const char *kmsgStatus = "on"; char *kmsgStatus = "on";
write(fd, kmsgStatus, strlen(kmsgStatus) + 1); write(fd, kmsgStatus, strlen(kmsgStatus) + 1);
close(fd); close(fd);
fd = -1; fd = -1;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件模式从 100644 更改为 100755
此差异已折叠。
文件模式从 100644 更改为 100755
文件模式从 100644 更改为 100755
文件模式从 100644 更改为 100755
文件模式从 100644 更改为 100755
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册