提交 045ec296 编写于 作者: C cheng_jinsong 提交者: Gitee

Merge branch 'master' of gitee.com:openharmony/startup_init_lite into closeselinux

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
......@@ -50,6 +50,7 @@ static unsigned int ConvertFlags(char *flagBuffer)
{"check", FS_MANAGER_CHECK},
{"wait", FS_MANAGER_WAIT},
{"required", FS_MANAGER_REQUIRED},
{"nofail", FS_MANAGER_NOFAIL},
};
BEGET_CHECK_RETURN_VALUE(flagBuffer != NULL && *flagBuffer != '\0', 0); // No valid flags.
......
......@@ -37,7 +37,7 @@ extern "C" {
#define FS_MANAGER_BUFFER_SIZE 512
#define BLOCK_SIZE_BUFFER (64)
#define RESIZE_BUFFER_SIZE 1024
const off_t MISC_PARTITION_ACTIVE_SLOT_OFFSET = 1400;
const off_t MISC_PARTITION_ACTIVE_SLOT_OFFSET = 4096;
const off_t MISC_PARTITION_ACTIVE_SLOT_SIZE = 4;
bool IsSupportedFilesystem(const char *fsType)
......@@ -406,7 +406,12 @@ int MountOneItem(FstabItem *item)
int rc = Mount(item->deviceName, item->mountPoint, item->fsType, mountFlags, fsSpecificData);
if (rc != 0) {
BEGET_LOGE("Mount %s to %s failed %d", item->deviceName, item->mountPoint, errno);
if (FM_MANAGER_NOFAIL_ENABLED(item->fsManagerFlags)) {
BEGET_LOGE("Mount no fail device %s to %s failed, err = %d", item->deviceName, item->mountPoint, errno);
} else {
BEGET_LOGW("Mount %s to %s failed, err = %d. Ignore failure", item->deviceName, item->mountPoint, errno);
rc = 0;
}
} else {
BEGET_LOGI("Mount %s to %s successful", item->deviceName, item->mountPoint);
}
......
......@@ -51,8 +51,7 @@ typedef void (*InitCommLog)(int logLevel, uint32_t domain, const char *tag, cons
#define FILE_NAME (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__))
INIT_PUBLIC_API void StartupLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...);
INIT_PUBLIC_API void EnableInitLog(void);
INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level);
INIT_PUBLIC_API void EnableInitLog(InitLogLevel level);
INIT_PUBLIC_API void SetInitCommLog(InitCommLog logFunc);
#define STARTUP_LOGV(domain, tag, fmt, ...) \
......
......@@ -29,6 +29,7 @@ extern "C" {
#define FS_MANAGER_CHECK 0x00000001
#define FS_MANAGER_WAIT 0x00000002
#define FS_MANAGER_REQUIRED 0x00000004
#define FS_MANAGER_NOFAIL 0x00000008
#define NAME_SIZE 32
#define MAX_SLOT 2
......@@ -38,6 +39,7 @@ extern "C" {
#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)
#define FM_MANAGER_NOFAIL_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), NOFAIL)
typedef enum MountStatus {
MOUNT_ERROR = -1,
......
......@@ -57,7 +57,11 @@ static int DoReboot_(const char *option)
int DoReboot(const char *option)
{
// check if param set ok
#ifndef STARTUP_INIT_TEST
const int maxCount = 10;
#else
const int maxCount = 1;
#endif
int count = 0;
DoReboot_(option);
while (count < maxCount) {
......
......@@ -163,7 +163,7 @@ std::string GetDeviceType(void)
{"fitnessWatch", "liteWearable"},
};
static const char *productType = nullptr;
const char *type = GetProperty("const.build.devicetype", &productType);
const char *type = GetProperty("const.product.devicetype", &productType);
if (type == nullptr) {
type = GetProperty("const.build.characteristics", &productType);
}
......
......@@ -94,7 +94,7 @@ int SetParameter(const char *key, const char *value)
const char *GetDeviceType(void)
{
static const char *productType = NULL;
const char *deviceType = GetProperty("const.build.devicetype", &productType);
const char *deviceType = GetProperty("const.product.devicetype", &productType);
if (deviceType != NULL) {
return deviceType;
}
......@@ -320,14 +320,14 @@ int32_t GetIntParameter(const char *key, int32_t def)
{
char value[MAX_INT_LEN] = {0};
int ret = GetParameter(key, "0", value, sizeof(value));
if (ret != 0) {
if (ret < 0) {
return def;
}
long long int result = 0;
if (StringToLL(value, &result) != 0) {
return def;
}
if (result <= INT32_MIN && result >= INT32_MAX) {
if (result <= INT32_MIN || result >= INT32_MAX) {
return def;
}
return (int32_t)result;
......@@ -337,7 +337,7 @@ uint32_t GetUintParameter(const char *key, uint32_t def)
{
char value[MAX_INT_LEN] = {0};
int ret = GetParameter(key, "0", value, sizeof(value));
if (ret != 0) {
if (ret < 0) {
return def;
}
unsigned long long int result = 0;
......
......@@ -17,8 +17,8 @@ vpn:x:1016:
keystore:x:1017:
usb:x:1018:
drm:x:1019:
gps:x:1020:
location_host:x:1021:
gps:x:1021:
location_host:x:1022:
media_rw:x:1023:
dsoftbus:x:1024:
nfc:x:1027:
......@@ -88,7 +88,6 @@ quickfixserver:x:5524;
samgr:x:5555:
update:x:6666:
charger:x:6667:
battery_stats:x:6668:
sensor:x:6688:
input:x:6696:
msdp:x:6699:
......
......@@ -141,9 +141,6 @@
"mkdir /storage/media 0711 root root",
"copy /data/system/entropy.dat /dev/urandom",
"mkdir /data/misc 01771 system misc",
"mkdir /data/misc/wifi 0770 wifi wifi",
"mkdir /data/misc/wifi/sockets 0770 wifi wifi",
"mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi",
"mkdir /data/local 0751 root root",
"mkdir /data/vendor 0771 root root",
"mkdir /data/local/tmp 0771 shell shell",
......
......@@ -40,7 +40,10 @@
"ohos.permission.START_ABILITIES_FROM_BACKGROUND",
"ohos.permission.PERMISSION_USED_STATS"
],
"permission_acls" : ["ohos.permission.DUMP"],
"permission_acls" : [
"ohos.permission.DUMP",
"ohos.permission.INSTALL_BUNDLE"
],
"sandbox" : 0,
"start-mode" : "condition",
"secon" : "u:r:hdcd:s0",
......
......@@ -129,9 +129,6 @@
"mkdir /data/app-staging 0750 system system",
"copy /data/system/entropy.dat /dev/urandom",
"mkdir /data/misc 01771 system misc",
"mkdir /data/misc/wifi 0770 wifi wifi",
"mkdir /data/misc/wifi/sockets 0770 wifi wifi",
"mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi",
"mkdir /data/local 0751 root root",
"mkdir /data/preloads 0775 system system",
"mkdir /data/vendor 0771 root root",
......
......@@ -16,8 +16,8 @@ vpn:x:1016:1016:::/bin/false
keystore:x:1017:1017:::/bin/false
usb:x:1018:1018:::/bin/false
drm:x:1019:1019:::/bin/false
gps:x:1020:1020:::/bin/false
location_host:x:1021:1021:::/bin/false
gps:x:1021:1021:::/bin/false
location_host:x:1022:1022:::/bin/false
media_rw:x:1023:1023:::/bin/false
dsoftbus:x:1024:1024:::/bin/false
nfc:x:1027:1027:::/bin/false
......@@ -85,7 +85,6 @@ samgr:x:5555:5555:::/bin/false
dbms:x:6000:6000:::/bin/false
update:x:6666:6666:::/bin/false
charger:x:6667:6667:::/bin/false
battery_stats:x:6668:6668:::/bin/false
sensor:x:6688:6688:::/bin/false
input:x:6696:6696:::/bin/false
msdp:x:6699:6699:::/bin/false
......
......@@ -2,4 +2,6 @@ root:x:0:
bin:x:2:
system:x:1000:
servicectrl:x:1050:root,shell,system,samgr,hdf_devmgr
shell:x:2000:
\ No newline at end of file
shell:x:2000:
watchdog:x:2001:root
ueventd:x:2002:root
......@@ -2,3 +2,5 @@ root:x:0:0:::/bin/false
bin:x:2:2:::/bin/false
system:x:1000:1000:::/bin/false
shell:x:2000:2000:::/bin/false
watchdog:x:2001:2001:::/bin/false
ueventd:x:2002:2002:::/bin/false
......@@ -30,7 +30,7 @@ int main(int argc, char * const argv[])
INIT_LOGE("Process id error %d!", getpid());
return 0;
}
EnableInitLog();
EnableInitLog(INIT_INFO);
if (isSecondStage == 0) {
SystemPrepare();
} else {
......
......@@ -38,13 +38,17 @@ static void ProcessSignal(const struct signalfd_siginfo *siginfo)
Service* service = GetServiceByPid(sigPID);
// check child process exit status
if (WIFSIGNALED(procStat)) {
INIT_LOGE("Child process %d exit with signal: %d", sigPID, WTERMSIG(procStat));
INIT_LOGE("Child process %s(pid %d) exit with code : %d",
service == NULL ? "Unknown" : service->name, sigPID, sigPID, WTERMSIG(procStat));
}
if (WIFEXITED(procStat)) {
INIT_LOGE("Child process %s(pid %d) exit with code : %d",
service == NULL ? "Unknown" : service->name, sigPID, WEXITSTATUS(procStat));
}
CmdServiceProcessDelClient(sigPID);
INIT_LOGI("SigHandler, SIGCHLD received, Service:%s pid:%d uid:%d status:%d.",
service == NULL ? "Unknown" : service->name,
sigPID, siginfo->ssi_uid, procStat);
CheckWaitPid(sigPID);
ServiceReap(service);
}
......@@ -75,4 +79,4 @@ void SignalInit(void)
if (LE_AddSignal(LE_GetDefaultLoop(), g_sigHandle, SIGTERM) != 0) {
INIT_LOGW("start SIGTERM handler failed");
}
}
\ No newline at end of file
}
......@@ -25,6 +25,7 @@
#include "init_log.h"
#include "fs_manager/fs_manager.h"
#include "securec.h"
#include "init_utils.h"
static void FreeOldRoot(DIR *dir, dev_t dev)
{
......@@ -77,21 +78,14 @@ static void FreeOldRoot(DIR *dir, dev_t dev)
// all sub mount tree in the future.
static bool UnderBasicMountPoint(const char *path)
{
unsigned int i;
if (path == NULL || *path == '\0') {
return false;
}
size_t pathSize = strlen(path);
if (strncmp(path, "/dev/", strlen("/dev/")) == 0 && pathSize > strlen("/dev/")) {
return true;
}
if (strncmp(path, "/sys/", strlen("/sys/")) == 0 && pathSize > strlen("/sys/")) {
return true;
}
if (strncmp(path, "/proc/", strlen("/proc/")) == 0 && pathSize > strlen("/proc/")) {
return true;
const char *basicMountPoint[] = {"/dev/", "/sys/", "/proc/"};
for (i = 0; i < ARRAY_LENGTH(basicMountPoint); i++) {
if (strncmp(path, basicMountPoint[i], strlen(basicMountPoint[i])) == 0)
return true;
}
return false;
}
......
......@@ -17,7 +17,6 @@ config("exported_header_files") {
include_dirs = [
"//base/startup/init/interfaces/innerkits/include",
"//base/startup/init/services/log",
"//base/startup/init/services/include",
]
}
......@@ -28,7 +27,6 @@ if (defined(ohos_lite)) {
"_GNU_SOURCE",
"OHOS_LITE",
]
cflags = [ "-fPIC" ]
public_configs = [ ":exported_header_files" ]
if (ohos_kernel_type == "linux") {
......
......@@ -22,7 +22,6 @@
#include <time.h>
#include <sys/time.h>
#include "param/init_param.h"
#include "securec.h"
#ifdef OHOS_LITE
#ifndef INIT_LOG_INIT
......@@ -121,7 +120,7 @@ static void PrintLog(InitLogLevel logLevel, unsigned int domain, const char *tag
INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs)
{
if (g_logLevel > logLevel) {
if ((int)g_logLevel > logLevel) {
return;
}
char tmpFmt[DEF_LOG_SIZE] = {0};
......@@ -129,29 +128,11 @@ INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag,
tmpFmt[sizeof(tmpFmt) - 2] = '\n'; // 2 add \n to tail
tmpFmt[sizeof(tmpFmt) - 1] = '\0';
}
PrintLog(logLevel, domain, tag, tmpFmt);
PrintLog((InitLogLevel)logLevel, domain, tag, tmpFmt);
}
INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level)
{
if ((level >= INIT_DEBUG) && (level <= INIT_FATAL)) {
g_logLevel = level;
}
return;
}
INIT_PUBLIC_API void EnableInitLog(void)
INIT_PUBLIC_API void EnableInitLog(InitLogLevel level)
{
g_logLevel = level;
SetInitCommLog(InitLog);
char logLevel[2] = {0}; // 2 is set param "persist.init.debug.loglevel" value length.
uint32_t len = sizeof(logLevel);
int ret = SystemReadParam("persist.init.debug.loglevel", logLevel, &len);
INIT_INFO_CHECK(ret == 0, return, "Can not get log level from param, keep the original loglevel.");
errno = 0;
unsigned int level = (unsigned int)strtoul(logLevel, 0, 10); // 10 is decimal
INIT_INFO_CHECK(errno == 0, return, "Failed strtoul %s, err=%d", logLevel, errno);
if ((level >= INIT_DEBUG) && (level <= INIT_FATAL)) {
g_logLevel = level;
}
return;
}
......@@ -28,7 +28,7 @@ static LE_STATUS SetTimer_(int tfd, uint64_t timeout)
struct itimerspec timeValue;
time_t sec = timeout / TIMEOUT_BASE;
timeValue.it_interval.tv_sec = sec;
long nsec = (timeout % TIMEOUT_BASE) * TIMEOUT_BASE;
long nsec = (timeout % TIMEOUT_BASE) * TIMEOUT_BASE * TIMEOUT_BASE;
timeValue.it_interval.tv_nsec = nsec;
timeValue.it_value.tv_sec = sec;
timeValue.it_value.tv_nsec = nsec;
......
......@@ -342,7 +342,7 @@ static void SetServiceBootEventFork(SERVICE_INFO_CTX *serviceCtx)
MODULE_CONSTRUCTOR(void)
{
EnableInitLog();
EnableInitLog(INIT_DEBUG);
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_BEFORE);
InitAddServiceHook(ClearServiceBootEvent, INIT_SERVICE_CLEAR);
InitAddServiceHook(DumpServiceBootEvent, INIT_SERVICE_DUMP);
......
......@@ -122,27 +122,9 @@ static int CmdClear(int id, const char *name, int argc, const char **argv)
return 0;
}
static int CmdSetLogLevel(int id, const char *name, int argc, const char **argv)
{
UNUSED(id);
if ((name == NULL) || (argv == NULL) || (argc < 1)) {
PLUGIN_LOGE("Failed get log level from parameter.");
return -1;
}
char *value = strrchr(argv[0], '.');
PLUGIN_CHECK(value != NULL, return -1, "Failed get \'.\' from string %s", argv[0]);
unsigned int level;
int ret = StringToUint(value + 1, &level);
PLUGIN_CHECK(ret == 0, return -1, "Failed make string to unsigned int");
PLUGIN_LOGI("level is %d", level);
SetInitLogLevel(level);
return 0;
}
static int ParamSetInitCmdHook(const HOOK_INFO *hookInfo, void *cookie)
static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie)
{
AddCmdExecutor("clear", CmdClear);
AddCmdExecutor("setinitloglevel", CmdSetLogLevel);
return 0;
}
......@@ -155,7 +137,7 @@ static int DumpTrigger(const char *fmt, ...)
return 0;
}
static void DumpServiceHook(void)
static int DumpServiceHook(const HOOK_INFO *info, void *cookie)
{
// check and dump all jobs
char dump[8] = {0}; // 8 len
......@@ -165,21 +147,12 @@ static void DumpServiceHook(void)
if (ret == 0 && strcmp(dump, "1") == 0) {
SystemDumpTriggers(1, DumpTrigger);
}
return;
}
static int InitDebugHook(const HOOK_INFO *info, void *cookie)
{
UNUSED(info);
UNUSED(cookie);
EnableInitLog();
DumpServiceHook();
return 0;
}
MODULE_CONSTRUCTOR(void)
{
InitAddGlobalInitHook(0, ParamSetInitCmdHook);
InitAddGlobalInitHook(0, ParamSetBootEventHook);
// Depends on parameter service
InitAddPostPersistParamLoadHook(0, InitDebugHook);
InitAddPostPersistParamLoadHook(0, DumpServiceHook);
}
......@@ -62,7 +62,6 @@ const ParamCmdInfo *GetOtherSpecial(size_t *size)
{
static const ParamCmdInfo other[] = {
{"bootevent.", "bootevent.", "bootevent"},
{"persist.init.debug.", "persist.init.debug.", "setinitloglevel"}
};
*size = ARRAY_LENGTH(other);
return other;
......
......@@ -161,6 +161,7 @@ prlimit64
cacheflush
set_tls
sched_setscheduler
mkdir
@allowListWithArgs
getrusage:if arg0 == RUSAGE_SELF || arg0 == RUSAGE_THREAD; return ALLOW; else return KILL_PROCESS;
......
......@@ -20,7 +20,7 @@
#include "param_manager.h"
#include "param_trie.h"
static ParamWorkSpace g_paramWorkSpace = {};
static ParamWorkSpace g_paramWorkSpace = {0};
PARAM_STATIC int WorkSpaceNodeCompare(const HashNode *node1, const HashNode *node2)
{
WorkSpace *workSpace1 = HASHMAP_ENTRY(node1, WorkSpace, hashNode);
......@@ -168,7 +168,7 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
// load user info for dac
LoadGroupUser();
// add default dac policy
ParamAuditData auditData = {};
ParamAuditData auditData = {0};
auditData.name = "#";
auditData.dacData.gid = DAC_DEFAULT_GROUP; // 2000 for shell
auditData.dacData.uid = DAC_DEFAULT_USER; // for root
......
......@@ -41,6 +41,7 @@ __attribute__((constructor)) static void ParameterInit(void)
if (getpid() == 1) {
return;
}
EnableInitLog(INIT_ERROR);
PARAM_WORKSPACE_OPS ops = {0};
ops.updaterMode = 0;
#ifdef PARAM_BASE_LOG
......@@ -50,7 +51,6 @@ __attribute__((constructor)) static void ParameterInit(void)
ops.setfilecon = NULL;
#endif
InitParamWorkSpace(1, &ops);
EnableInitLog();
}
__attribute__((destructor)) static void ParameterDeinit(void)
......
......@@ -108,10 +108,13 @@ static_library("param_init_lite") {
static_library("param_client_lite") {
sources = base_sources
include_dirs = param_include_dirs
cflags = [ "-fPIC" ]
defines = param_build_defines
public_configs = [ ":exported_header_files" ]
if (use_musl) {
defines += [ "PARAM_BASE" ]
}
if (ohos_kernel_type == "liteos_a") {
sources +=
[ "//base/startup/init/services/param/adapter/param_persistadp.c" ]
......
......@@ -19,20 +19,20 @@
static int g_flags = 0;
__attribute__((constructor)) static void ClientInit(void);
__attribute__((destructor)) static void ClientDeinit(void);
static void ClientDeinit(void);
static int InitParamClient(void)
{
if (PARAM_TEST_FLAG(g_flags, WORKSPACE_FLAGS_INIT)) {
return 0;
}
EnableInitLog(INIT_INFO);
PARAM_LOGV("InitParamClient");
int ret = InitParamWorkSpace(1, NULL);
PARAM_CHECK(ret == 0, return -1, "Failed to init param workspace");
PARAM_SET_FLAG(g_flags, WORKSPACE_FLAGS_INIT);
// init persist to save
InitPersistParamWorkSpace();
EnableInitLog();
return 0;
}
......
......@@ -27,7 +27,7 @@
#include "utils_file.h"
// for linux, no mutex
static ParamMutex g_saveMutex = {};
static ParamMutex g_saveMutex = {0};
#ifdef PARAM_SUPPORT_POSIX
#define MODE_READ O_RDONLY
#define MODE_APPEND (O_RDWR | O_CREAT | O_APPEND)
......
......@@ -14,6 +14,7 @@
*/
#include "param_osadp.h"
#include "param_security.h"
#include "securec.h"
static int InitLocalSecurityLabel(ParamSecurityLabel *security, int isInit)
{
......@@ -81,4 +82,4 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
INIT_LOCAL_API void LoadGroupUser(void)
{
}
\ No newline at end of file
}
......@@ -24,6 +24,7 @@
#include <sys/shm.h>
#else
#include "los_task.h"
#include "los_mux.h"
#endif
#include <sys/stat.h>
#include <sys/time.h>
......@@ -318,4 +319,4 @@ INIT_LOCAL_API uint32_t Difftime(time_t curr, time_t base)
(void)base;
return 0;
#endif
}
\ No newline at end of file
}
......@@ -132,11 +132,11 @@ static void ParamServiceTask(int *arg)
void LiteParamService(void)
{
EnableInitLog(INIT_INFO);
PARAM_LOGI("LiteParamService");
InitParamService();
// get persist param
LoadPersistParams();
EnableInitLog();
osThreadAttr_t attr;
attr.name = "ParamServiceTask";
attr.attr_bits = 0U;
......
......@@ -23,7 +23,7 @@
#include "param_osadp.h"
#include "securec.h"
static ParamPersistWorkSpace g_persistWorkSpace = {0, 0, NULL, 0, {}};
static ParamPersistWorkSpace g_persistWorkSpace = {0, 0, NULL, 0, {0}};
static int IsNeedToSave(const char *name)
{
#if defined(__LITEOS_M__) || defined(__LITEOS_A__)
......@@ -241,4 +241,4 @@ int LoadPersistParams(void)
}
#endif
return 0;
}
\ No newline at end of file
}
......@@ -322,10 +322,13 @@ char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxIt
void WaitForFile(const char *source, unsigned int maxSecond)
{
INIT_ERROR_CHECK(maxSecond <= WAIT_MAX_SECOND, maxSecond = WAIT_MAX_SECOND, "WaitForFile max time is 5s");
struct stat sourceInfo = {};
struct stat sourceInfo = {0};
unsigned int waitTime = 500000;
/* 500ms interval, check maxSecond*2 times total */
unsigned int maxCount = maxSecond * 2;
#ifdef STARTUP_INIT_TEST
maxCount = 0;
#endif
unsigned int count = 0;
while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < maxCount)) {
usleep(waitTime);
......@@ -382,7 +385,7 @@ int MakeDir(const char *dir, mode_t mode)
int MakeDirRecursive(const char *dir, mode_t mode)
{
int rc = -1;
char buffer[PATH_MAX] = {};
char buffer[PATH_MAX] = {0};
const char *p = NULL;
if (dir == NULL || *dir == '\0') {
errno = EINVAL;
......
......@@ -49,11 +49,21 @@ ohos_moduletest("InitModuleTest") {
sources = [
"hookmgr_moduletest.cpp",
"modulemgr_moduletest.cpp",
"service_control_test.cpp",
"service_watcher_moduleTest.cpp",
"test_utils.cpp",
]
include_dirs = [ "//base/startup/init/interfaces/innerkits/include" ]
include_dirs = [
"//base/startup/init/interfaces/innerkits/include",
"//base/startup/init/interfaces/innerkits/include/syspara",
"//base/startup/init/interfaces/innerkits/syspara",
"//base/startup/init/services/include/param",
".",
]
deps = [
"//base/startup/init/interfaces/innerkits:libbeget_proxy",
"//base/startup/init/interfaces/innerkits:libbegetutil",
"//third_party/googletest:gtest_main",
]
......
/*
* Copyright (c) 2022 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 <chrono>
#include <thread>
#include <gtest/gtest.h>
#include "service_control.h"
#include "test_utils.h"
using namespace testing::ext;
namespace initModuleTest {
namespace {
// Default wait for service status change time is 10 seconds
constexpr int WAIT_SERVICE_STATUS_TIMEOUT = 10;
}
class ServiceControlTest : public testing::Test {
public:
static void SetUpTestCase() {};
static void TearDownTestCase() {};
void SetUp() {};
void TearDown() {};
};
// Test service start
HWTEST_F(ServiceControlTest, ServiceStartTest, TestSize.Level1)
{
// Pick an unusual service for testing
// Try to start media_service.
// 1) Check if media_service exist
std::string serviceName = "media_service";
auto status = GetServiceStatus(serviceName);
if (status == "running") {
int ret = ServiceControl(serviceName.c_str(), STOP);
ASSERT_EQ(ret, 0);
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
ASSERT_EQ(ret, 0);
} else if (status != "created" && status != "stopped") {
std::cout << serviceName << " in invalid status " << status << std::endl;
std::cout << "Debug " << serviceName << " in unexpected status " << status << std::endl;
ASSERT_TRUE(0);
}
// 2) Now try to start service
int ret = ServiceControl(serviceName.c_str(), START);
EXPECT_EQ(ret, 0);
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STARTED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, 0);
status = GetServiceStatus(serviceName);
std::cout << "Debug " << serviceName << " in status " << status << std::endl;
EXPECT_TRUE(status == "running");
}
HWTEST_F(ServiceControlTest, NonExistServiceStartTest, TestSize.Level1)
{
std::string serviceName = "non_exist_service";
int ret = ServiceControl(serviceName.c_str(), START);
EXPECT_EQ(ret, 0); // No matter if service exist or not, ServiceControl always success.
auto status = GetServiceStatus(serviceName);
EXPECT_TRUE(status == "idle");
}
HWTEST_F(ServiceControlTest, ServiceStopTest, TestSize.Level1)
{
std::string serviceName = "media_service";
auto status = GetServiceStatus(serviceName);
if (status == "stopped" || status == "created") {
int ret = ServiceControl(serviceName.c_str(), START);
ASSERT_EQ(ret, 0); // start must be success
} else if (status != "running") {
std::cout << serviceName << " in invalid status " << status << std::endl;
ASSERT_TRUE(0);
}
int ret = ServiceControl(serviceName.c_str(), STOP);
EXPECT_EQ(ret, 0);
// Sleep for a while, let init handle service starting.
const int64_t ms = 500;
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
status = GetServiceStatus(serviceName);
bool isStopped = status == "stopped";
EXPECT_TRUE(isStopped);
}
HWTEST_F(ServiceControlTest, NonExistServiceStopTest, TestSize.Level1)
{
std::string serviceName = "non_exist_service";
int ret = ServiceControl(serviceName.c_str(), STOP);
EXPECT_EQ(ret, 0); // No matter if service exist or not, ServiceControl always success.
auto status = GetServiceStatus(serviceName);
EXPECT_TRUE(status == "idle");
}
HWTEST_F(ServiceControlTest, ServiceTimerStartTest, TestSize.Level1)
{
uint64_t timeout = 1000; // Start service in 1 second
std::string serviceName = "media_service";
// stop this service first
int ret = ServiceControl(serviceName.c_str(), STOP);
auto oldStatus = GetServiceStatus(serviceName);
bool isRunning = oldStatus == "running";
EXPECT_FALSE(isRunning);
ret = StartServiceByTimer(serviceName.c_str(), timeout);
EXPECT_EQ(ret, 0);
// Service will be started in @timeout seconds
// Now we try to sleep about @timeout / 2 seconds, then check service status.
int64_t ms = 600;
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
// Get service status.
auto newStatus = GetServiceStatus(serviceName);
bool notChange = oldStatus == newStatus;
EXPECT_TRUE(notChange);
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
newStatus = GetServiceStatus(serviceName);
isRunning = newStatus == "running";
EXPECT_TRUE(isRunning);
}
HWTEST_F(ServiceControlTest, ServiceTimerStartContinuouslyTest, TestSize.Level1)
{
uint64_t oldTimeout = 500;
uint64_t newTimeout = 1000;
std::string serviceName = "media_service";
int ret = ServiceControl(serviceName.c_str(), STOP);
EXPECT_EQ(ret, 0);
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, 0);
auto oldStatus = GetServiceStatus(serviceName);
bool isRunning = oldStatus == "running";
EXPECT_FALSE(isRunning);
ret = StartServiceByTimer(serviceName.c_str(), oldTimeout); // Set timer as 500 ms
EXPECT_EQ(ret, 0);
ret = StartServiceByTimer(serviceName.c_str(), newTimeout); // Set timer as 1 second
EXPECT_EQ(ret, 0);
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int64_t>(oldTimeout)));
auto newStatus = GetServiceStatus(serviceName);
bool notChange = oldStatus == newStatus;
EXPECT_TRUE(notChange);
uint64_t margin = 20; // 20 ms margin in case of timer not that precisely
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int64_t>(oldTimeout + margin)));
newStatus = GetServiceStatus(serviceName);
isRunning = newStatus == "running";
EXPECT_TRUE(isRunning);
}
HWTEST_F(ServiceControlTest, ServiceTimerStopTest, TestSize.Level1)
{
uint64_t timeout = 1000; // set timer as 1 second
std::string serviceName = "media_service";
int ret = ServiceControl(serviceName.c_str(), STOP);
EXPECT_EQ(ret, 0);
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, 0);
auto oldStatus = GetServiceStatus(serviceName);
bool isRunning = oldStatus == "running";
EXPECT_FALSE(isRunning);
ret = StartServiceByTimer(serviceName.c_str(), timeout);
EXPECT_EQ(ret, 0);
// Now sleep for a while
int64_t ms = 300;
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
auto newStatus = GetServiceStatus(serviceName);
bool notChange = oldStatus == newStatus;
EXPECT_TRUE(notChange);
ret = StopServiceTimer(serviceName.c_str());
EXPECT_EQ(ret, 0);
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
newStatus = GetServiceStatus(serviceName);
notChange = oldStatus == newStatus;
EXPECT_TRUE(notChange);
}
HWTEST_F(ServiceControlTest, ServiceTimerStopLateTest, TestSize.Level1)
{
uint64_t timeout = 500; // set timer as 5 micro seconds
std::string serviceName = "media_service";
int ret = ServiceControl(serviceName.c_str(), STOP);
auto oldStatus = GetServiceStatus(serviceName);
bool isRunning = oldStatus == "running";
EXPECT_FALSE(isRunning);
ret = StartServiceByTimer(serviceName.c_str(), timeout);
EXPECT_EQ(ret, 0);
int64_t ms = 550;
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
ret = StopServiceTimer(serviceName.c_str());
EXPECT_EQ(ret, 0);
auto newStatus = GetServiceStatus(serviceName);
isRunning = newStatus == "running";
EXPECT_TRUE(isRunning);
}
HWTEST_F(ServiceControlTest, RestartServiceTest, TestSize.Level1)
{
std::string serviceName = "media_service";
auto status = GetServiceStatus(serviceName);
EXPECT_FALSE(status.empty());
int ret = ServiceControl(serviceName.c_str(), RESTART);
EXPECT_EQ(ret, 0);
ret = ServiceControl(serviceName.c_str(), STOP);
EXPECT_EQ(ret, 0);
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, 0);
ret = ServiceControl(serviceName.c_str(), RESTART);
EXPECT_EQ(ret, 0);
status = GetServiceStatus(serviceName);
bool isRunning = status == "running";
EXPECT_TRUE(isRunning);
}
HWTEST_F(ServiceControlTest, WaitForServiceStatusTest, TestSize.Level1)
{
std::string serviceName = "media_service";
int ret = ServiceControl(serviceName.c_str(), STOP);
EXPECT_EQ(ret, 0);
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, 0);
auto status = GetServiceStatus(serviceName);
bool isStopped = status == "stopped";
EXPECT_TRUE(isStopped);
// service is stopped now. try to wait a status which will not be set
std::cout << "Wait for service " << serviceName << " status change to start\n";
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STARTED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, -1);
serviceName = "non-exist-service";
std::cout << "Wait for service " << serviceName << " status change to stop\n";
ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
EXPECT_EQ(ret, -1);
}
} // initModuleTest
/*
* Copyright (c) 2022 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 <thread>
#include <string>
#include <gtest/gtest.h>
#include "service_control.h"
#include "service_watcher.h"
#include "test_utils.h"
using namespace testing::ext;
namespace initModuleTest {
class serviceWatcherModuleTest : public testing::Test {
public:
static void SetUpTestCase(void) {};
static void TearDownTestCase(void) {};
void SetUp(void) {};
void TearDown(void) {};
};
static void ServiceStatusChange(const char *key, ServiceStatus status)
{
std::cout<<"service Name is: "<<key<<", ServiceStatus is: "<<status<<std::endl;
}
HWTEST_F(serviceWatcherModuleTest,serviceWatcher_test_001, TestSize.Level0)
{
GTEST_LOG_(INFO) << "serviceWatcher_test_001 start";
string serviceName = "test.Service";
int ret = ServiceWatchForStatus(serviceName.c_str(), ServiceStatusChange);
EXPECT_EQ(ret, 0); // No matter if service exist or not, ServiceWatchForStatus always success.
auto status = GetServiceStatus(serviceName);
EXPECT_TRUE(status == "idle");
GTEST_LOG_(INFO) << "serviceWatcher_test_001 end";
}
HWTEST_F(serviceWatcherModuleTest,serviceWatcher_test_002, TestSize.Level0)
{
GTEST_LOG_(INFO) << "serviceWatcher_test_002 start";
string serviceName = "media_service";
auto status = GetServiceStatus(serviceName);
if (status == "running") {
int ret = ServiceControl(serviceName.c_str(), STOP);
ASSERT_EQ(ret , 0);
} else if (status != "created" && status != "stopped") {
std::cout << serviceName << " in invalid status " << status << std::endl;
ASSERT_TRUE(0);
}
int ret = ServiceWatchForStatus(serviceName.c_str(), ServiceStatusChange);
EXPECT_EQ(ret, 0);
status = GetServiceStatus(serviceName);
EXPECT_TRUE(status == "stopped");
GTEST_LOG_(INFO) << "serviceWatcher_test_002 end";
}
}
/*
* Copyright (c) 2022 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 "test_utils.h"
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <list>
#include <thread>
#include <memory>
#include <fcntl.h>
#include <cerrno>
#include <sys/stat.h>
#include "parameters.h"
#include "service_control.h"
namespace initModuleTest {
namespace {
constexpr size_t MAX_BUFFER_SIZE = 4096;
}
// File operator
int ReadFileContent(const std::string &fileName, std::string &content)
{
content.clear();
auto fp = std::unique_ptr<FILE, decltype(&fclose)>(fopen(fileName.c_str(), "r"), fclose);
if (fp == nullptr) {
std::cout << "Cannot open file " << fileName << std::endl;
return -1;
}
struct stat st {};
if (stat(fileName.c_str(), &st) < 0) {
std::cout << "Cannot get " << fileName << " stat\n";
return -1;
}
ssize_t n = 0;
char buffer[MAX_BUFFER_SIZE] = {};
while ((n = fread(buffer, 1, MAX_BUFFER_SIZE, fp.get())) > 0) {
content.append(buffer, n);
}
return feof(fp.get()) ? 0 : -1;
}
bool StartsWith(const std::string &str, const std::string &prefix)
{
return ((str.size() > prefix.size()) && (str.substr(0, prefix.size()) == prefix));
}
bool EndsWith(const std::string &str, const std::string &suffix)
{
return ((str.size() > suffix.size()) && (str.substr(str.size() - suffix.size(), suffix.size()) == suffix));
}
std::string Trim(const std::string &str)
{
size_t start = 0;
size_t end = str.size() - 1;
while (start < str.size()) {
if (!isspace(str[start])) {
break;
}
start++;
}
while (start < end) {
if (!isspace(str[end])) {
break;
}
end--;
}
if (end < start) {
return "";
}
return str.substr(start, end - start + 1);
}
std::vector<std::string> Split(const std::string &str, const std::string &pattern)
{
std::vector<std::string> result {};
size_t pos = std::string::npos;
size_t start = 0;
while (true) {
pos = str.find_first_of(pattern, start);
result.push_back(str.substr(start, pos - start));
if (pos == std::string::npos) {
break;
}
start = pos + 1;
}
return result;
}
static std::map<ServiceStatus, std::string> g_serviceStatusMap = {
{ SERVICE_IDLE, "idle"},
{ SERVICE_STARTING, "starting"},
{ SERVICE_STARTED, "running"},
{ SERVICE_READY, "ready"},
{ SERVICE_STOPPING, "stopping"},
{ SERVICE_STOPPED, "stopped"},
{ SERVICE_ERROR, "error" },
{ SERVICE_SUSPENDED, "suspended" },
{ SERVICE_FREEZED, "freezed" },
{ SERVICE_DISABLED, "disabled" },
{ SERVICE_CRITICAL, "critical" },
};
static inline bool ValidStatus(ServiceStatus status)
{
return status >= SERVICE_IDLE && status <= SERVICE_CRITICAL;
}
std::string GetServiceStatus(const std::string &serviceName)
{
if (serviceName.empty()) {
return "";
}
const std::string serviceCtlPrefix = "startup.service.ctl.";
const std::string serviceCtlName = serviceCtlPrefix + serviceName;
uint32_t ret = OHOS::system::GetUintParameter<uint32_t>(serviceCtlName, 0);
ServiceStatus status = static_cast<ServiceStatus>(ret);
if (!ValidStatus(status)) {
return "";
}
return g_serviceStatusMap[status];
}
} // initModuleTest
/*
* Copyright (c) 2022 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 INIT_MODULE_TEST_UTILS_H
#define INIT_MODULE_TEST_UTILS_H
#include <string>
#include <vector>
namespace initModuleTest {
// File operator
int ReadFileContent(const std::string &fileName, std::string &content);
std::string Trim(const std::string &str);
std::vector<std::string> Split(const std::string &str, const std::string &pattern);
std::string GetServiceStatus(const std::string &serviceName);
} // initModuleTest
#endif // INIT_MODULE_TEST_UTILS_H
......@@ -271,10 +271,6 @@ HWTEST_F(CmdsUnitTest, TestGetCmdLinesFromJson, TestSize.Level1)
HWTEST_F(CmdsUnitTest, TestInitCmdFunc, TestSize.Level1)
{
int ret = GetBootModeFromMisc();
#ifdef __MUSL__
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
}
} // namespace init_ut
......@@ -123,10 +123,10 @@ HWTEST_F(ModuleMgrUnitTest, ModuleInstallTest, TestSize.Level1)
ModuleMgrDestroy(moduleMgr);
// Scan all modules
moduleMgr = ModuleMgrScan("init");
moduleMgr = ModuleMgrScan("init/autorun");
ASSERT_NE(moduleMgr, nullptr);
cnt = ModuleMgrGetCnt(moduleMgr);
ASSERT_NE(cnt, 0);
ASSERT_EQ(cnt, 0);
ModuleMgrUninstall(moduleMgr, NULL);
cnt = ModuleMgrGetCnt(moduleMgr);
......
......@@ -124,7 +124,7 @@ public:
}
void SetUp()
{
EnableInitLog();
EnableInitLog(INIT_FATAL);
}
void TearDown() {}
};
......@@ -629,12 +629,12 @@ static void CheckService(const cJSON* curItem)
}
cJSON *filedJ = cJSON_GetObjectItem(curItem, "uid");
EXPECT_TRUE(cJSON_IsNumber(filedJ));
EXPECT_TRUE(cJSON_GetNumberValue(filedJ) >= 0.0);
EXPECT_TRUE(cJSON_IsNumber(filedJ) || cJSON_IsString(filedJ));
EXPECT_TRUE(cJSON_GetNumberValue(filedJ) >= 0.0 || cJSON_GetStringValue(filedJ));
filedJ = cJSON_GetObjectItem(curItem, "gid");
EXPECT_TRUE(cJSON_IsNumber(filedJ));
EXPECT_TRUE(cJSON_GetNumberValue(filedJ) >= 0.0);
EXPECT_TRUE(cJSON_IsNumber(filedJ) || cJSON_IsArray(filedJ));
EXPECT_TRUE(cJSON_GetNumberValue(filedJ) >= 0.0 || cJSON_GetArraySize(filedJ) >= 0);
filedJ = cJSON_GetObjectItem(curItem, "once");
EXPECT_TRUE(cJSON_IsNumber(filedJ));
......@@ -648,8 +648,8 @@ static void CheckService(const cJSON* curItem)
EXPECT_TRUE(capsCnt <= MAX_CAPS_CNT_FOR_ONE_SERVICE);
for (int i = 0; i < capsCnt; ++i) {
cJSON *capJ = cJSON_GetArrayItem(filedJ, i);
EXPECT_TRUE(cJSON_IsNumber(capJ));
EXPECT_TRUE(cJSON_GetNumberValue(capJ) >= 0.0);
EXPECT_TRUE(cJSON_IsNumber(capJ) || cJSON_GetStringValue(capJ));
EXPECT_TRUE(cJSON_GetNumberValue(capJ) >= 0.0 || cJSON_GetStringValue(capJ));
}
}
......
......@@ -434,7 +434,7 @@ int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
static __attribute__((constructor(101))) void ParamTestStubInit(void)
{
EnableInitLog();
EnableInitLog(INIT_DEBUG);
PARAM_LOGI("ParamTestStubInit");
PrepareInitUnitTestEnv();
}
......
......@@ -33,11 +33,12 @@ using namespace std;
using namespace OHOS;
using namespace OHOS::init_param;
void TestParameterChange(const char *key, const char *value, void *context)
static void TestParameterChange(const char *key, const char *value, void *context)
{
printf("TestParameterChange key:%s %s", key, value);
}
void TestWatcherCallBack(const char *key, ServiceStatus status)
static void TestWatcherCallBack(const char *key, ServiceStatus status)
{
printf("TestWatcherCallBack key:%s %d", key, status);
}
......
......@@ -275,8 +275,8 @@ HWTEST_F(SysparaUnitTest, parameterTest0013, TestSize.Level0)
int ret = SetParameter(key1, value1);
EXPECT_EQ(ret, 0);
GetParameter_(nullptr, nullptr, nullptr, 0);
EXPECT_EQ(GetIntParameter(key1, 0), 0);
EXPECT_EQ(GetUintParameter(key1, 0), 0);
EXPECT_EQ(GetIntParameter(key1, 0), 101);
EXPECT_EQ(GetUintParameter(key1, 0), 101);
EXPECT_EQ(IsValidParamValue(nullptr, 0), 0);
EXPECT_EQ(IsValidParamValue("testvalue", strlen("testvalue") + 1), 1);
EXPECT_EQ(StringToLL("0x11", &out), 0);
......
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Copyright (c) 2021-2022 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
......@@ -14,4 +14,7 @@
[device]
# <device name> <mode> <uid> <gid>
/dev/binder 0666 0 0
/dev/random 0666 0 0
/dev/urandom 0666 0 0
/dev/mmz_userdev 0666 0 0
/dev/watchdog 0660 watchdog watchdog
......@@ -50,7 +50,7 @@ static void PollUeventdSocketTimeout(int ueventSockFd, bool ondemand)
int main(int argc, char **argv)
{
// start log
EnableInitLog();
EnableInitLog(INIT_INFO);
char *ueventdConfigs[] = {"/etc/ueventd.config", "/vendor/etc/ueventd.config", NULL};
int i = 0;
while (ueventdConfigs[i] != NULL) {
......
......@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
......@@ -40,34 +40,28 @@
#define PRETIMEOUT_GAP 5
#define PRETIMEOUT_DIV 2
#define WATCHDOG_DEV "/dev/watchdog"
static int WaitForWatchDogDevice(void)
static void WaitAtStartup(const char *source)
{
unsigned int count = 0;
struct stat sourceInfo;
const unsigned int waitTime = 500000;
while ((stat(WATCHDOG_DEV, &sourceInfo) < 0) && (errno == ENOENT) && (count < WAIT_MAX_COUNT)) {
do {
usleep(waitTime);
count++;
}
} while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < WAIT_MAX_COUNT));
if (count == WAIT_MAX_COUNT) {
INIT_LOGE("Wait for watchdog device failed after %u seconds", (WAIT_MAX_COUNT * waitTime) / CONVERSION_BASE);
return 0;
INIT_LOGE("wait for file:%s failed after %u seconds.", source, (WAIT_MAX_COUNT * waitTime) / CONVERSION_BASE);
}
return 1;
return;
}
int main(int argc, const char *argv[])
{
if (WaitForWatchDogDevice() == 0) {
return -1;
}
int fd = open(WATCHDOG_DEV, O_RDWR | O_CLOEXEC);
if (fd < 0) {
INIT_LOGE("Open watchdog device failed, err = %d", errno);
return -1;
WaitAtStartup("/dev/watchdog");
int fd = open("/dev/watchdog", O_RDWR);
if (fd == -1) {
INIT_LOGE("Can't open /dev/watchdog.");
return 1;
}
int interval = 0;
......@@ -82,10 +76,11 @@ int main(int argc, const char *argv[])
}
gap = (gap > 0) ? gap : DEFAULT_GAP;
INIT_LOGI("Watchdog started (interval %d, margin %d), fd = %d\n", interval, gap, fd);
#ifdef OHOS_LITE_WATCHDOG
#ifndef LINUX_WATCHDOG
if (setpriority(PRIO_PROCESS, 0, 14) != 0) { // 14 is process priority
INIT_LOGE("setpriority failed, err=%d", errno);
INIT_LOGE("setpriority failed err=%d\n", errno);
}
#endif
#endif
......@@ -98,16 +93,12 @@ int main(int argc, const char *argv[])
#endif
int ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeoutSet);
if (ret < 0) {
INIT_LOGE("ioctl failed with command WDIOC_SETTIMEOUT, err = %d", errno);
close(fd);
return -1;
if (ret) {
INIT_LOGE("Failed to set timeout to %d\n", timeoutSet);
}
ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeoutGet);
if (ret < 0) {
INIT_LOGE("ioctl failed with command WDIOC_GETTIMEOUT, err = %d", errno);
close(fd);
return -1;
if (ret) {
INIT_LOGE("Failed to get timeout\n");
}
if (timeoutGet > 0) {
......@@ -115,19 +106,15 @@ int main(int argc, const char *argv[])
}
#ifdef WDIOC_SETPRETIMEOUT
preTimeout = timeoutGet - PRETIMEOUT_GAP; // ensure pre timeout smaller then timeout
preTimeout = timeoutGet - PRETIMEOUT_GAP; // ensure pretimeout smaller then timeout
if (preTimeout > 0) {
ret = ioctl(fd, WDIOC_SETPRETIMEOUT, &preTimeout);
if (ret < 0) {
INIT_LOGE("ioctl failed with command WDIOC_SETPRETIMEOUT, err = %d", errno);
close(fd);
return -1;
if (ret) {
INIT_LOGE("Failed to set pretimeout to %d\n", preTimeout);
}
ret = ioctl(fd, WDIOC_GETPRETIMEOUT, &preTimeoutGet);
if (ret < 0) {
INIT_LOGE("ioctl failed with command WDIOC_GETPRETIMEOUT, err = %d", errno);
close(fd);
return -1;
if (ret) {
INIT_LOGE("Failed to get pretimeout\n");
}
}
......@@ -136,14 +123,8 @@ int main(int argc, const char *argv[])
}
#endif
INIT_LOGI("watchdog started (interval %d, margin %d)", interval, gap);
while (1) {
ret = ioctl(fd, WDIOC_KEEPALIVE);
if (ret < 0) {
// Fed watchdog failed, we don't need to quit the process.
// Wait for kernel to trigger panic.
INIT_LOGE("ioctl failed with command WDIOC_KEEPALIVE, err = %d", errno);
}
ioctl(fd, WDIOC_KEEPALIVE);
sleep(interval);
}
close(fd);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册