Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Startup Init Lite
提交
e6d3a83d
S
Startup Init Lite
项目概览
OpenHarmony
/
Startup Init Lite
11 个月 前同步成功
通知
3
Star
37
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Startup Init Lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
e6d3a83d
编写于
8月 09, 2022
作者:
O
openharmony_ci
提交者:
Gitee
8月 09, 2022
浏览文件
操作
浏览文件
下载
差异文件
!1046 开机启动过程投票机制日志分析
Merge pull request !1046 from cheng_jinsong/bootevent
上级
a8b3ccfd
771c12a0
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
376 addition
and
219 deletion
+376
-219
services/begetctl/dump_service.c
services/begetctl/dump_service.c
+22
-5
services/init/include/init_service_manager.h
services/init/include/init_service_manager.h
+2
-2
services/init/init_service_manager.c
services/init/init_service_manager.c
+6
-116
services/init/standard/init_control_fd_service.c
services/init/standard/init_control_fd_service.c
+149
-5
services/modules/bootevent/BUILD.gn
services/modules/bootevent/BUILD.gn
+11
-0
services/modules/bootevent/bootevent.c
services/modules/bootevent/bootevent.c
+145
-87
services/modules/init_hook/init_hook.c
services/modules/init_hook/init_hook.c
+0
-2
services/modules/init_hook/init_hook.h
services/modules/init_hook/init_hook.h
+1
-1
services/modules/plugin_adapter.h
services/modules/plugin_adapter.h
+2
-0
test/unittest/BUILD.gn
test/unittest/BUILD.gn
+2
-0
test/unittest/init/group_unittest.cpp
test/unittest/init/group_unittest.cpp
+3
-1
test/unittest/init/service_unittest.cpp
test/unittest/init/service_unittest.cpp
+33
-0
未找到文件。
services/begetctl/dump_service.c
浏览文件 @
e6d3a83d
...
...
@@ -17,29 +17,46 @@
#include <string.h>
#include "begetctl.h"
#include "beget_ext.h"
#include "control_fd.h"
#include "securec.h"
#include "init_param.h"
#define DUMP_SERVICE_INFO_CMD_ARGS 2
#define DUMP_SERVICE_BOOTEVENT_CMD_ARGS 3
static
int
main_cmd
(
BShellHandle
shell
,
int
argc
,
char
**
argv
)
{
if
(
argc
!=
DUMP_SERVICE_INFO_CMD_ARGS
)
{
BShellCmdHelp
(
shell
,
argc
,
argv
);
return
0
;
}
if
(
strcmp
(
argv
[
0
],
"dump_service"
)
==
0
)
{
if
(
argc
==
DUMP_SERVICE_INFO_CMD_ARGS
)
{
printf
(
"dump service info
\n
"
);
CmdClientInit
(
INIT_CONTROL_FD_SOCKET_PATH
,
ACTION_DUMP
,
argv
[
1
]);
}
else
if
(
argc
==
DUMP_SERVICE_BOOTEVENT_CMD_ARGS
)
{
printf
(
"dump service bootevent info
\n
"
);
int
serviceNameLen
=
strlen
(
argv
[
1
])
+
strlen
(
argv
[
2
])
+
2
;
// 2 is \0 and #
char
*
serviceBootevent
=
(
char
*
)
calloc
(
1
,
serviceNameLen
);
BEGET_ERROR_CHECK
(
sprintf_s
(
serviceBootevent
,
serviceNameLen
,
"%s#%s"
,
argv
[
1
],
argv
[
2
])
>=
0
,
return
0
,
"dumpservice arg create failed"
);
CmdClientInit
(
INIT_CONTROL_FD_SOCKET_PATH
,
ACTION_DUMP
,
serviceBootevent
);
free
(
serviceBootevent
);
}
else
{
BShellCmdHelp
(
shell
,
argc
,
argv
);
}
return
0
;
}
static
int
ClearBootEvent
(
BShellHandle
shell
,
int
argc
,
char
**
argv
)
{
return
SystemSetParameter
(
"ohos.servicectrl.clear"
,
"bootevent"
);
}
MODULE_CONSTRUCTOR
(
void
)
{
const
CmdInfo
infos
[]
=
{
{
"dump_service"
,
main_cmd
,
"dump one service info by serviceName"
,
"dump_service serviceName"
,
NULL
},
{
"dump_service"
,
main_cmd
,
"dump one service bootevent"
,
"dump_service serviceName bootevent"
,
NULL
},
{
"dump_service"
,
main_cmd
,
"dump all services info"
,
"dump_service all"
,
NULL
},
{
"dump_service"
,
main_cmd
,
"dump all services bootevent"
,
"dump_service all bootevent"
,
NULL
},
{
"service"
,
ClearBootEvent
,
"Clear all services bootevent"
,
"service clear bootevent"
,
"service clear bootevent"
},
};
for
(
size_t
i
=
0
;
i
<
sizeof
(
infos
)
/
sizeof
(
infos
[
0
]);
i
++
)
{
BShellEnvRegitsterCmd
(
GetShellHandle
(),
&
infos
[
i
]);
...
...
services/init/include/init_service_manager.h
浏览文件 @
e6d3a83d
...
...
@@ -61,8 +61,8 @@ void ReleaseService(Service *service);
void
StartAllServices
(
int
startMode
);
void
LoadAccessTokenId
(
void
);
Service
*
AddService
(
const
char
*
name
);
void
Dump
AllServices
(
void
);
void
DumpOneService
(
const
Service
*
service
);
void
Dump
ServiceHookExecute
(
const
char
*
name
,
const
char
*
info
);
void
ProcessControlFd
(
uint16_t
type
,
const
char
*
serviceCmd
,
const
void
*
context
);
#ifdef __cplusplus
#if __cplusplus
}
...
...
services/init/init_service_manager.c
浏览文件 @
e6d3a83d
...
...
@@ -51,122 +51,6 @@ static const int CRITICAL_DEFAULT_CRASH_TIME = 20;
static
const
int
CRITICAL_DEFAULT_CRASH_COUNT
=
4
;
static
const
int
CRITICAL_CONFIG_ARRAY_LEN
=
3
;
static
void
DumpServiceArgs
(
const
char
*
info
,
const
ServiceArgs
*
args
)
{
printf
(
"
\t
service %s count %d
\n
"
,
info
,
args
->
count
);
for
(
int
j
=
0
;
j
<
args
->
count
;
j
++
)
{
if
(
args
->
argv
[
j
]
!=
NULL
)
{
printf
(
"
\t\t
info [%d] %s
\n
"
,
j
,
args
->
argv
[
j
]);
}
}
}
static
void
DumpServiceJobs
(
const
Service
*
service
)
{
printf
(
"
\t
service job info
\n
"
);
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_BOOT
]
!=
NULL
)
{
printf
(
"
\t\t
service boot job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_BOOT
]);
}
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_START
]
!=
NULL
)
{
printf
(
"
\t\t
service start job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_START
]);
}
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_STOP
]
!=
NULL
)
{
printf
(
"
\t\t
service stop job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_STOP
]);
}
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_RESTART
]
!=
NULL
)
{
printf
(
"
\t\t
service restart job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_RESTART
]);
}
}
static
void
DumpServiceSocket
(
const
Service
*
service
)
{
printf
(
"
\t
service socket info
\n
"
);
ServiceSocket
*
sockopt
=
service
->
socketCfg
;
while
(
sockopt
!=
NULL
)
{
printf
(
"
\t\t
socket name: %s
\n
"
,
sockopt
->
name
);
printf
(
"
\t\t
socket type: %u
\n
"
,
sockopt
->
type
);
printf
(
"
\t\t
socket uid: %u
\n
"
,
sockopt
->
uid
);
printf
(
"
\t\t
socket gid: %u
\n
"
,
sockopt
->
gid
);
sockopt
=
sockopt
->
next
;
}
}
#ifndef OHOS_LITE
static
void
DumpServiceHookExecute
(
const
char
*
name
,
const
char
*
info
)
{
SERVICE_INFO_CTX
context
;
context
.
serviceName
=
name
;
context
.
reserved
=
info
;
(
void
)
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_DUMP
,
(
void
*
)(
&
context
),
NULL
);
}
#endif
void
DumpOneService
(
const
Service
*
service
)
{
const
InitArgInfo
startModeMap
[]
=
{
{
"condition"
,
START_MODE_CONDITION
},
{
"boot"
,
START_MODE_BOOT
},
{
"normal"
,
START_MODE_NORMAL
}
};
const
static
char
*
serviceStatusMap
[]
=
{
"created"
,
"starting"
,
"running"
,
"ready"
,
"stopping"
,
"stopped"
,
"suspended"
,
"freezed"
,
"disabled"
,
"critical"
};
printf
(
"
\t
service name: [%s]
\n
"
,
service
->
name
);
#ifdef WITH_SELINUX
if
(
service
->
secon
!=
NULL
)
{
printf
(
"
\t
service secon: [%s]
\n
"
,
service
->
secon
);
}
#endif
printf
(
"
\t
service pid: [%d]
\n
"
,
service
->
pid
);
printf
(
"
\t
service crashCnt: [%d]
\n
"
,
service
->
crashCnt
);
printf
(
"
\t
service attribute: [%u]
\n
"
,
service
->
attribute
);
printf
(
"
\t
service importance: [%d]
\n
"
,
service
->
importance
);
printf
(
"
\t
service startMode: [%s]
\n
"
,
startModeMap
[
service
->
startMode
].
name
);
printf
(
"
\t
service status: [%s]
\n
"
,
serviceStatusMap
[
service
->
status
]);
printf
(
"
\t
service perms uID [%u]
\n
"
,
service
->
servPerm
.
uID
);
DumpServiceArgs
(
"path arg"
,
&
service
->
pathArgs
);
DumpServiceArgs
(
"writepid file"
,
&
service
->
writePidArgs
);
DumpServiceJobs
(
service
);
DumpServiceSocket
(
service
);
printf
(
"
\t
service perms groupId %d
\n
"
,
service
->
servPerm
.
gIDCnt
);
for
(
int
i
=
0
;
i
<
service
->
servPerm
.
gIDCnt
;
i
++
)
{
printf
(
"
\t\t
service perms groupId %u
\n
"
,
service
->
servPerm
.
gIDArray
[
i
]);
}
printf
(
"
\t
service perms capability %u
\n
"
,
service
->
servPerm
.
capsCnt
);
for
(
int
i
=
0
;
i
<
(
int
)
service
->
servPerm
.
capsCnt
;
i
++
)
{
printf
(
"
\t\t
service perms capability %u
\n
"
,
service
->
servPerm
.
caps
[
i
]);
}
#ifndef OHOS_LITE
/*
* dump service hooks
*/
DumpServiceHookExecute
(
service
->
name
,
NULL
);
#endif
}
void
DumpAllServices
(
void
)
{
printf
(
"Ready to dump all services:
\n
"
);
printf
(
"total service number: %d
\n
"
,
g_serviceSpace
.
serviceCount
);
InitGroupNode
*
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
NULL
);
while
(
node
!=
NULL
)
{
if
(
node
->
data
.
service
==
NULL
)
{
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
node
);
continue
;
}
Service
*
service
=
node
->
data
.
service
;
DumpOneService
(
service
);
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
node
);
}
printf
(
"Dump all services finished
\n
"
);
}
static
void
FreeServiceArg
(
ServiceArgs
*
arg
)
{
if
(
arg
==
NULL
)
{
...
...
@@ -265,6 +149,12 @@ void ReleaseService(Service *service)
FreeServiceSocket
(
service
->
socketCfg
);
FreeServiceFile
(
service
->
fileCfg
);
#ifndef OHOS_LITE
// clear ext data
SERVICE_INFO_CTX
ctx
=
{
0
};
ctx
.
serviceName
=
service
->
name
;
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_CLEAR
,
(
void
*
)
&
ctx
,
NULL
);
#endif
g_serviceSpace
.
serviceCount
--
;
InitGroupNode
*
groupNode
=
GetGroupNode
(
NODE_TYPE_SERVICES
,
service
->
name
);
if
(
groupNode
!=
NULL
)
{
...
...
services/init/standard/init_control_fd_service.c
浏览文件 @
e6d3a83d
...
...
@@ -24,6 +24,134 @@
#include "init_modulemgr.h"
#include "init_utils.h"
#include "init_log.h"
#include "init_group_manager.h"
#include "hookmgr.h"
#include "bootstage.h"
static
void
DumpServiceArgs
(
const
char
*
info
,
const
ServiceArgs
*
args
)
{
printf
(
"
\t
service %s count %d
\n
"
,
info
,
args
->
count
);
for
(
int
j
=
0
;
j
<
args
->
count
;
j
++
)
{
if
(
args
->
argv
[
j
]
!=
NULL
)
{
printf
(
"
\t\t
info [%d] %s
\n
"
,
j
,
args
->
argv
[
j
]);
}
}
}
static
void
DumpServiceJobs
(
const
Service
*
service
)
{
printf
(
"
\t
service job info
\n
"
);
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_BOOT
]
!=
NULL
)
{
printf
(
"
\t\t
service boot job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_BOOT
]);
}
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_START
]
!=
NULL
)
{
printf
(
"
\t\t
service start job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_START
]);
}
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_STOP
]
!=
NULL
)
{
printf
(
"
\t\t
service stop job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_STOP
]);
}
if
(
service
->
serviceJobs
.
jobsName
[
JOB_ON_RESTART
]
!=
NULL
)
{
printf
(
"
\t\t
service restart job %s
\n
"
,
service
->
serviceJobs
.
jobsName
[
JOB_ON_RESTART
]);
}
}
static
void
DumpServiceSocket
(
const
Service
*
service
)
{
printf
(
"
\t
service socket info
\n
"
);
ServiceSocket
*
sockopt
=
service
->
socketCfg
;
while
(
sockopt
!=
NULL
)
{
printf
(
"
\t\t
socket name: %s
\n
"
,
sockopt
->
name
);
printf
(
"
\t\t
socket type: %u
\n
"
,
sockopt
->
type
);
printf
(
"
\t\t
socket uid: %u
\n
"
,
sockopt
->
uid
);
printf
(
"
\t\t
socket gid: %u
\n
"
,
sockopt
->
gid
);
sockopt
=
sockopt
->
next
;
}
}
void
DumpServiceHookExecute
(
const
char
*
name
,
const
char
*
info
)
{
SERVICE_INFO_CTX
context
;
context
.
serviceName
=
name
;
context
.
reserved
=
info
;
(
void
)
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_DUMP
,
(
void
*
)(
&
context
),
NULL
);
}
static
void
DumpOneService
(
const
Service
*
service
)
{
const
InitArgInfo
startModeMap
[]
=
{
{
"condition"
,
START_MODE_CONDITION
},
{
"boot"
,
START_MODE_BOOT
},
{
"normal"
,
START_MODE_NORMAL
}
};
const
static
char
*
serviceStatusMap
[]
=
{
"created"
,
"starting"
,
"running"
,
"ready"
,
"stopping"
,
"stopped"
,
"suspended"
,
"freezed"
,
"disabled"
,
"critical"
};
printf
(
"
\t
service name: [%s]
\n
"
,
service
->
name
);
printf
(
"
\t
service pid: [%d]
\n
"
,
service
->
pid
);
printf
(
"
\t
service crashCnt: [%d]
\n
"
,
service
->
crashCnt
);
printf
(
"
\t
service attribute: [%u]
\n
"
,
service
->
attribute
);
printf
(
"
\t
service importance: [%d]
\n
"
,
service
->
importance
);
printf
(
"
\t
service startMode: [%s]
\n
"
,
startModeMap
[
service
->
startMode
].
name
);
printf
(
"
\t
service status: [%s]
\n
"
,
serviceStatusMap
[
service
->
status
]);
printf
(
"
\t
service perms uID [%u]
\n
"
,
service
->
servPerm
.
uID
);
DumpServiceArgs
(
"path arg"
,
&
service
->
pathArgs
);
DumpServiceArgs
(
"writepid file"
,
&
service
->
writePidArgs
);
DumpServiceJobs
(
service
);
DumpServiceSocket
(
service
);
printf
(
"
\t
service perms groupId %d
\n
"
,
service
->
servPerm
.
gIDCnt
);
for
(
int
i
=
0
;
i
<
service
->
servPerm
.
gIDCnt
;
i
++
)
{
printf
(
"
\t\t
service perms groupId %u
\n
"
,
service
->
servPerm
.
gIDArray
[
i
]);
}
printf
(
"
\t
service perms capability %u
\n
"
,
service
->
servPerm
.
capsCnt
);
for
(
int
i
=
0
;
i
<
(
int
)
service
->
servPerm
.
capsCnt
;
i
++
)
{
printf
(
"
\t\t
service perms capability %u
\n
"
,
service
->
servPerm
.
caps
[
i
]);
}
DumpServiceHookExecute
(
service
->
name
,
NULL
);
}
static
void
PrintBootEventHead
(
const
char
*
cmd
)
{
if
(
strcmp
(
cmd
,
"bootevent"
)
==
0
)
{
printf
(
"
\t
%-20.20s
\t
%-50s
\t
%-20.20s
\t
%-20.20s
\n
"
,
"service-name"
,
"bootevent-name"
,
"fork"
,
"ready"
);
}
return
;
}
static
void
DumpAllExtData
(
const
char
*
cmd
)
{
PrintBootEventHead
(
cmd
);
InitGroupNode
*
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
NULL
);
while
(
node
!=
NULL
)
{
if
(
node
->
data
.
service
==
NULL
)
{
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
node
);
continue
;
}
DumpServiceHookExecute
(
node
->
name
,
cmd
);
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
node
);
}
}
static
void
DumpAllServices
(
void
)
{
printf
(
"Ready to dump all services:
\n
"
);
InitGroupNode
*
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
NULL
);
while
(
node
!=
NULL
)
{
if
(
node
->
data
.
service
==
NULL
)
{
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
node
);
continue
;
}
Service
*
service
=
node
->
data
.
service
;
DumpOneService
(
service
);
node
=
GetNextGroupNode
(
NODE_TYPE_SERVICES
,
node
);
}
printf
(
"Dump all services finished
\n
"
);
}
static
void
ProcessSandboxControlFd
(
uint16_t
type
,
const
char
*
serviceCmd
)
{
...
...
@@ -45,12 +173,28 @@ static void ProcessDumpServiceControlFd(uint16_t type, const char *serviceCmd)
if
((
type
!=
ACTION_DUMP
)
||
(
serviceCmd
==
NULL
))
{
return
;
}
Service
*
service
=
GetServiceByName
(
serviceCmd
);
char
*
cmd
=
strrchr
(
serviceCmd
,
'#'
);
if
(
cmd
!=
NULL
)
{
cmd
[
0
]
=
'\0'
;
cmd
++
;
}
if
(
service
==
NULL
)
{
DumpAllServices
();
}
else
{
DumpOneService
(
service
);
if
(
strcmp
(
serviceCmd
,
"all"
)
==
0
)
{
if
(
cmd
!=
NULL
)
{
DumpAllExtData
(
cmd
);
}
else
{
DumpAllServices
();
}
return
;
}
Service
*
service
=
GetServiceByName
(
serviceCmd
);
if
(
service
!=
NULL
)
{
if
(
cmd
!=
NULL
)
{
PrintBootEventHead
(
cmd
);
DumpServiceHookExecute
(
serviceCmd
,
cmd
);
}
else
{
DumpOneService
(
service
);
}
}
return
;
}
...
...
services/modules/bootevent/BUILD.gn
浏览文件 @
e6d3a83d
...
...
@@ -16,9 +16,12 @@ import("//build/ohos.gni")
config("bootevent_static_config") {
include_dirs = [
"//base/startup/init/services/param/linux",
"//base/startup/init/services/init/include",
"//base/startup/init/services/loopevent/include",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/services/param/include",
"//base/startup/init/services/include/param",
"//third_party/bounds_checking_function/include/",
]
}
...
...
@@ -27,4 +30,12 @@ ohos_source_set("libbootevent_static") {
include_dirs = [ ".." ]
public_configs = [ ":bootevent_static_config" ]
public_configs += [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
if (build_selinux) {
include_dirs += [
"//third_party/selinux/libselinux/include/",
"//base/security/selinux/interfaces/policycoreutils/include/",
"//base/startup/init/services/include/param",
]
defines = [ "WITH_SELINUX" ]
}
}
services/modules/bootevent/bootevent.c
浏览文件 @
e6d3a83d
...
...
@@ -18,155 +18,213 @@
#include "trigger_manager.h"
#include "init_log.h"
#include "plugin_adapter.h"
#include "init_hook.h"
#include "init_service.h"
#include "bootstage.h"
#include "securec.h"
#define BOOT_EVENT_PARA_PREFIX "bootevent."
#define BOOT_EVENT_PARA_PREFIX_LEN 10
#ifdef BOOTEVENT
#define BOOT_EVENT_TIMESTAMP_MAX_LEN 50
static
int
bootEventNum
=
0
;
enum
{
BOOTEVENT_FORK
,
BOOTEVENT_READY
,
BOOTEVENT_MAX
};
typedef
struct
tagBOOT_EVENT_PARAM_ITEM
{
ListNode
node
;
const
char
*
paramName
;
struct
timespec
timestamp
[
BOOTEVENT_MAX
];
}
BOOT_EVENT_PARAM_ITEM
;
static
ListNode
*
bootEventList
=
NULL
;
static
ListNode
bootEventList
=
{
&
bootEventList
,
&
bootEventList
}
;
static
ListNode
*
getBootEventParaList
(
bool
autoCreate
)
static
int
BootEventParaListCompareProc
(
ListNode
*
node
,
void
*
data
)
{
if
(
!
autoCreate
)
{
return
bootEventList
;
}
if
(
bootEventList
!=
NULL
)
{
return
bootEventList
;
}
// Create list node
bootEventList
=
(
ListNode
*
)
malloc
(
sizeof
(
ListNode
));
if
(
bootEventList
==
NULL
)
{
return
NULL
;
BOOT_EVENT_PARAM_ITEM
*
item
=
(
BOOT_EVENT_PARAM_ITEM
*
)
node
;
if
(
strcmp
(
item
->
paramName
+
BOOT_EVENT_PARA_PREFIX_LEN
,
(
const
char
*
)
data
)
==
0
)
{
return
0
;
}
OH_ListInit
(
bootEventList
);
return
bootEventList
;
return
-
1
;
}
static
void
BootEventParaAdd
(
const
char
*
paramName
)
static
int
AddServiceBootEvent
(
const
char
*
serviceName
,
const
char
*
paramName
)
{
ListNode
*
list
;
BOOT_EVENT_PARAM_ITEM
*
item
;
if
(
paramName
==
NULL
)
{
return
;
}
// Only bootevent. parameters can be added
ServiceExtData
*
extData
=
NULL
;
ListNode
*
found
=
NULL
;
if
(
strncmp
(
paramName
,
BOOT_EVENT_PARA_PREFIX
,
BOOT_EVENT_PARA_PREFIX_LEN
)
!=
0
)
{
return
;
return
-
1
;
}
INIT_LOGI
(
"Add bootevent [%s] ..."
,
paramName
);
list
=
getBootEventParaList
(
true
);
if
(
list
==
NULL
)
{
return
;
found
=
OH_ListFind
(
&
bootEventList
,
(
void
*
)
paramName
,
BootEventParaListCompareProc
);
if
(
found
!=
NULL
)
{
return
-
1
;
}
// Create item
item
=
(
BOOT_EVENT_PARAM_ITEM
*
)
malloc
(
sizeof
(
BOOT_EVENT_PARAM_ITEM
));
if
(
item
==
NULL
)
{
return
;
for
(
int
i
=
HOOK_ID_BOOTEVENT
;
i
<
HOOK_ID_BOOTEVENT_MAX
;
i
++
)
{
extData
=
AddServiceExtData
(
serviceName
,
i
,
NULL
,
sizeof
(
BOOT_EVENT_PARAM_ITEM
));
if
(
extData
!=
NULL
)
{
break
;
}
}
item
->
paramName
=
strdup
(
paramName
);
if
(
item
->
paramName
==
NULL
)
{
free
((
void
*
)
item
);
return
;
if
(
extData
==
NULL
)
{
return
-
1
;
}
// Add to list
OH_ListAddTail
(
list
,
(
ListNode
*
)
item
);
}
static
int
BootEventParaListCompareProc
(
ListNode
*
node
,
void
*
data
)
{
BOOT_EVENT_PARAM_ITEM
*
item
=
(
BOOT_EVENT_PARAM_ITEM
*
)
node
;
if
(
strcmp
(
item
->
paramName
,
(
const
char
*
)
data
)
==
0
)
{
return
0
;
BOOT_EVENT_PARAM_ITEM
*
item
=
(
BOOT_EVENT_PARAM_ITEM
*
)
extData
->
data
;
OH_ListInit
(
&
item
->
node
);
for
(
int
i
=
0
;
i
<
BOOTEVENT_MAX
;
i
++
)
{
item
->
timestamp
[
i
].
tv_nsec
=
0
;
item
->
timestamp
[
i
].
tv_sec
=
0
;
}
return
-
1
;
}
static
void
BootEventParaItemDestroy
(
BOOT_EVENT_PARAM_ITEM
*
item
)
{
if
(
item
->
paramName
!=
NULL
)
{
free
((
void
*
)
item
->
paramName
);
item
->
paramName
=
strdup
(
paramName
);
if
(
item
->
paramName
==
NULL
)
{
INIT_LOGI
(
"strdup failed"
);
return
-
1
;
}
free
((
void
*
)
item
);
OH_ListAddTail
(
&
bootEventList
,
(
ListNode
*
)
&
item
->
node
);
return
0
;
}
#define BOOT_EVENT_BOOT_COMPLETED "bootevent.boot.completed"
static
void
BootEventParaFireByName
(
const
char
*
paramName
)
{
ListNode
*
found
;
if
(
bootEvent
List
==
NULL
)
{
ListNode
*
found
=
NULL
;
char
*
bootEventValue
=
strrchr
(
paramName
,
'.'
);
if
(
bootEvent
Value
==
NULL
)
{
return
;
}
bootEventValue
[
0
]
=
'\0'
;
found
=
OH_ListFind
(
getBootEventParaList
(
false
),
(
void
*
)
paramName
,
BootEventParaListCompareProc
);
if
(
found
!=
NULL
)
{
// Remove from list
OH_ListRemove
(
found
);
BootEventParaItemDestroy
((
BOOT_EVENT_PARAM_ITEM
*
)
found
);
found
=
OH_ListFind
(
&
bootEventList
,
(
void
*
)
paramName
,
BootEventParaListCompareProc
);
if
(
found
==
NULL
)
{
return
;
}
if
(((
BOOT_EVENT_PARAM_ITEM
*
)
found
)
->
timestamp
[
BOOTEVENT_READY
].
tv_sec
!=
0
)
{
return
;
}
INIT_CHECK_ONLY_RETURN
(
clock_gettime
(
CLOCK_MONOTONIC
,
&
(((
BOOT_EVENT_PARAM_ITEM
*
)
found
)
->
timestamp
[
BOOTEVENT_READY
]))
==
0
);
bootEventNum
--
;
// Check if all boot event params are fired
if
(
OH_ListGetCnt
(
getBootEventParaList
(
false
))
>
0
)
{
if
(
bootEventNum
>
0
)
{
return
;
}
// Delete hooks for boot event
free
((
void
*
)
bootEventList
);
bootEventList
=
NULL
;
// All parameters are fired, set boot completed now ...
INIT_LOGI
(
"All bootevents are fired, boot complete now ..."
);
SystemWriteParam
(
BOOT_EVENT_BOOT_COMPLETED
,
"true"
);
return
;
}
#define BOOT_EVENT_FIELD_NAME "bootevents"
#endif
static
void
ServiceParseBootEventHook
(
SERVICE_PARSE_CTX
*
serviceParseCtx
)
{
PLUGIN_LOGI
(
"ServiceParseBootEventHook %s"
,
serviceParseCtx
->
serviceName
);
int
cnt
;
cJSON
*
bootEvents
=
cJSON_GetObjectItem
(
serviceParseCtx
->
serviceNode
,
BOOT_EVENT_FIELD_NAME
);
// No bootevents in config file
if
(
bootEvents
==
NULL
)
{
return
;
}
// Single bootevent in config file
if
(
!
cJSON_IsArray
(
bootEvents
))
{
if
(
AddServiceBootEvent
(
serviceParseCtx
->
serviceName
,
cJSON_GetStringValue
(
bootEvents
))
!=
0
)
{
INIT_LOGI
(
"Add service bootevent failed %s"
,
serviceParseCtx
->
serviceName
);
return
;
}
bootEventNum
++
;
return
;
}
// Multiple bootevents in config file
cnt
=
cJSON_GetArraySize
(
bootEvents
);
for
(
int
i
=
0
;
i
<
cnt
;
i
++
)
{
cJSON
*
item
=
cJSON_GetArrayItem
(
bootEvents
,
i
);
if
(
AddServiceBootEvent
(
serviceParseCtx
->
serviceName
,
cJSON_GetStringValue
(
item
))
!=
0
)
{
INIT_LOGI
(
"Add service bootevent failed %s"
,
serviceParseCtx
->
serviceName
);
return
;
}
bootEventNum
++
;
}
}
static
int
DoBootEventCmd
(
int
id
,
const
char
*
name
,
int
argc
,
const
char
**
argv
)
{
PLUGIN_LOGI
(
"DoBootEventCmd argc %d %s"
,
argc
,
name
);
PLUGIN_CHECK
(
argc
>=
1
,
return
-
1
,
"Invalid parameter"
);
// argv[0] samgr.ready.true
PLUGIN_LOGI
(
"DoBootEventCmd argv %s"
,
argv
[
0
]);
BootEventParaFireByName
(
argv
[
0
]);
return
0
;
}
void
ClearServiceBootEventHook
(
SERVICE_INFO_CTX
*
serviceCtx
)
{
PLUGIN_LOGI
(
"ClearServiceBootEventHook serviceName %s"
,
serviceCtx
->
serviceName
);
}
static
int32_t
g_executorId
=
-
1
;
static
int
ParamSetBootEventHook
(
const
HOOK_INFO
*
hookInfo
,
void
*
cookie
)
{
if
(
g_executorId
==
-
1
)
{
g_executorId
=
AddCmdExecutor
(
"bootevent"
,
DoBootEventCmd
);
PLUGIN_LOGI
(
"DoBootEventCmd executorId %d"
,
g_executorId
);
}
return
0
;
}
static
void
DumpServiceBootEvent
(
SERVICE_INFO_CTX
*
serviceCtx
)
{
if
(
serviceCtx
->
reserved
!=
NULL
&&
strcmp
(
serviceCtx
->
reserved
,
"bootevent"
)
!=
0
)
{
return
;
}
for
(
int
i
=
HOOK_ID_BOOTEVENT
;
i
<
HOOK_ID_BOOTEVENT_MAX
;
i
++
)
{
ServiceExtData
*
serviceExtData
=
GetServiceExtData
(
serviceCtx
->
serviceName
,
i
);
if
(
serviceExtData
==
NULL
)
{
return
;
}
BOOT_EVENT_PARAM_ITEM
*
item
=
(
BOOT_EVENT_PARAM_ITEM
*
)
serviceExtData
->
data
;
char
booteventForkTimeStamp
[
BOOT_EVENT_TIMESTAMP_MAX_LEN
]
=
""
;
char
booteventReadyTimeStamp
[
BOOT_EVENT_TIMESTAMP_MAX_LEN
]
=
""
;
INIT_CHECK_ONLY_RETURN
(
sprintf_s
(
booteventForkTimeStamp
,
BOOT_EVENT_TIMESTAMP_MAX_LEN
,
"%ld.%ld"
,
(
long
)
item
->
timestamp
[
BOOTEVENT_FORK
].
tv_sec
,
(
long
)
item
->
timestamp
[
BOOTEVENT_FORK
].
tv_nsec
)
>=
0
);
INIT_CHECK_ONLY_RETURN
(
sprintf_s
(
booteventReadyTimeStamp
,
BOOT_EVENT_TIMESTAMP_MAX_LEN
,
"%ld.%ld"
,
(
long
)
item
->
timestamp
[
BOOTEVENT_READY
].
tv_sec
,
(
long
)
item
->
timestamp
[
BOOTEVENT_READY
].
tv_nsec
)
>=
0
);
printf
(
"
\t
%-20.20s
\t
%-50s
\t
%-20.20s
\t
%-20.20s
\n
"
,
serviceCtx
->
serviceName
,
item
->
paramName
,
booteventForkTimeStamp
,
booteventReadyTimeStamp
);
}
return
;
}
static
void
ClearServiceBootEvent
(
SERVICE_INFO_CTX
*
serviceCtx
)
{
if
(
serviceCtx
->
reserved
==
NULL
||
strcmp
(
serviceCtx
->
reserved
,
"bootevent"
)
==
0
)
{
for
(
int
i
=
HOOK_ID_BOOTEVENT
;
i
<
HOOK_ID_BOOTEVENT_MAX
;
i
++
)
{
ServiceExtData
*
extData
=
GetServiceExtData
(
serviceCtx
->
serviceName
,
i
);
if
(
extData
==
NULL
)
{
return
;
}
OH_ListRemove
(
&
((
BOOT_EVENT_PARAM_ITEM
*
)
extData
->
data
)
->
node
);
DelServiceExtData
(
serviceCtx
->
serviceName
,
i
);
}
}
return
;
}
static
void
SetServiceBootEventFork
(
SERVICE_INFO_CTX
*
serviceCtx
)
{
for
(
int
i
=
HOOK_ID_BOOTEVENT
;
i
<
HOOK_ID_BOOTEVENT_MAX
;
i
++
)
{
ServiceExtData
*
extData
=
GetServiceExtData
(
serviceCtx
->
serviceName
,
i
);
if
(
extData
==
NULL
||
((
BOOT_EVENT_PARAM_ITEM
*
)
extData
->
data
)
->
timestamp
[
BOOTEVENT_FORK
].
tv_sec
!=
0
)
{
return
;
}
INIT_CHECK_ONLY_RETURN
(
clock_gettime
(
CLOCK_MONOTONIC
,
&
(((
BOOT_EVENT_PARAM_ITEM
*
)
extData
->
data
)
->
timestamp
[
BOOTEVENT_FORK
]))
==
0
);
}
return
;
}
MODULE_CONSTRUCTOR
(
void
)
{
EnableInitLog
(
INIT_DEBUG
);
InitAddServiceHook
(
SetServiceBootEventFork
,
INIT_SERVICE_FORK_BEFORE
);
InitAddServiceHook
(
ClearServiceBootEvent
,
INIT_SERVICE_CLEAR
);
InitAddServiceHook
(
DumpServiceBootEvent
,
INIT_SERVICE_DUMP
);
InitAddServiceParseHook
(
ServiceParseBootEventHook
);
InitAddGlobalInitHook
(
0
,
ParamSetBootEventHook
);
InitAddClearServiceHook
(
ClearServiceBootEventHook
);
}
services/modules/init_hook/init_hook.c
浏览文件 @
e6d3a83d
...
...
@@ -89,7 +89,6 @@ static int ServiceClearHookWrapper(const HOOK_INFO *hookInfo, void *executionCon
SERVICE_INFO_CTX
*
ctx
=
(
SERVICE_INFO_CTX
*
)
executionContext
;
ServiceHook
realHook
=
(
ServiceHook
)
hookInfo
->
hookCookie
;
realHook
(
ctx
);
INIT_LOGI
(
"ServiceClearHookWrapper realHook %p"
,
realHook
);
return
0
;
};
...
...
@@ -100,7 +99,6 @@ int InitAddClearServiceHook(ServiceHook hook)
info
.
prio
=
0
;
info
.
hook
=
ServiceClearHookWrapper
;
info
.
hookCookie
=
(
void
*
)
hook
;
PLUGIN_LOGI
(
"InitAddClearServiceHook hook %p info.stage %d %p"
,
hook
,
info
.
stage
,
GetBootStageHookMgr
());
return
HookMgrAddEx
(
GetBootStageHookMgr
(),
&
info
);
}
...
...
services/modules/init_hook/init_hook.h
浏览文件 @
e6d3a83d
...
...
@@ -41,7 +41,7 @@ const ParamCmdInfo *GetOtherSpecial(size_t *size);
typedef
struct
{
struct
ListNode
node
;
uint32_t
dataId
;
uint8_t
data
[];
uint8_t
data
[
0
];
}
ServiceExtData
;
ServiceExtData
*
AddServiceExtData
(
const
char
*
serviceName
,
uint32_t
id
,
void
*
data
,
uint32_t
dataLen
);
...
...
services/modules/plugin_adapter.h
浏览文件 @
e6d3a83d
...
...
@@ -50,5 +50,7 @@
enum
HOOK_ID_
{
HOOKID
(
BOOTCHART
),
HOOKID
(
SELINUX
),
HOOKID
(
BOOTEVENT
),
HOOKID
(
BOOTEVENT_MAX
)
=
HOOK_ID_BOOTEVENT
+
10
,
};
#endif
test/unittest/BUILD.gn
浏览文件 @
e6d3a83d
...
...
@@ -64,6 +64,7 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/init/standard/init.c",
"//base/startup/init/services/init/standard/init_cmdexecutor.c",
"//base/startup/init/services/init/standard/init_cmds.c",
"//base/startup/init/services/init/standard/init_control_fd_service.c",
"//base/startup/init/services/init/standard/init_jobs.c",
"//base/startup/init/services/init/standard/init_mount.c",
"//base/startup/init/services/init/standard/init_reboot.c",
...
...
@@ -81,6 +82,7 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/loopevent/task/le_watchtask.c",
"//base/startup/init/services/loopevent/timer/le_timer.c",
"//base/startup/init/services/loopevent/utils/le_utils.c",
"//base/startup/init/services/modules/bootevent/bootevent.c",
"//base/startup/init/services/modules/init_hook/init_hook.c",
"//base/startup/init/services/modules/init_hook/param_hook.c",
"//base/startup/init/services/param/adapter/param_dac.c",
...
...
test/unittest/init/group_unittest.cpp
浏览文件 @
e6d3a83d
...
...
@@ -23,6 +23,7 @@
#include "le_timer.h"
#include "param_stub.h"
#include "securec.h"
#include "control_fd.h"
using
namespace
testing
::
ext
;
using
namespace
std
;
...
...
@@ -299,7 +300,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1)
ASSERT_NE
(
nullptr
,
fileRoot
);
ParseAllServices
(
fileRoot
);
cJSON_Delete
(
fileRoot
);
DumpAllServices
();
char
cmdStr
[]
=
"all#bootevent"
;
ProcessControlFd
(
ACTION_DUMP
,
cmdStr
,
NULL
);
Service
*
service
=
GetServiceByName
(
"test-service6"
);
ASSERT_NE
(
service
,
nullptr
);
workspace
->
groupMode
=
GROUP_BOOT
;
...
...
test/unittest/init/service_unittest.cpp
浏览文件 @
e6d3a83d
...
...
@@ -26,6 +26,9 @@
#include "securec.h"
#include "init_group_manager.h"
#include "trigger_manager.h"
#include "bootstage.h"
#include "init_hook.h"
#include "plugin_adapter.h"
using
namespace
testing
::
ext
;
using
namespace
std
;
...
...
@@ -262,6 +265,36 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerGetService, TestSize.Level1)
ret
=
ParseOneService
(
serviceItem
,
service
);
EXPECT_NE
(
ret
,
0
);
}
HWTEST_F
(
ServiceUnitTest
,
TestServiceBootEventHook
,
TestSize
.
Level1
)
{
Service
*
service
=
nullptr
;
const
char
*
jsonStr
=
"{
\"
services
\"
:{
\"
name
\"
:
\"
test_service8
\"
,
\"
path
\"
:[
\"
/data/init_ut/test_service
\"
],"
"
\"
importance
\"
:-20,
\"
uid
\"
:
\"
system
\"
,
\"
writepid
\"
:[
\"
/dev/test_service
\"
],
\"
console
\"
:1,"
"
\"
bootevents
\"
: [
\"
bootevent1
\"
,
\"
bootevent2
\"
],"
"
\"
gid
\"
:[
\"
system
\"
],
\"
critical
\"
:[1,2]}}"
;
cJSON
*
jobItem
=
cJSON_Parse
(
jsonStr
);
ASSERT_NE
(
nullptr
,
jobItem
);
cJSON
*
serviceItem
=
cJSON_GetObjectItem
(
jobItem
,
"services"
);
ASSERT_NE
(
nullptr
,
serviceItem
);
service
=
AddService
(
"test_service2"
);
ASSERT_NE
(
nullptr
,
service
);
int
ret
=
ParseOneService
(
serviceItem
,
service
);
if
(
ret
<
0
)
{
return
;
}
SERVICE_PARSE_CTX
context
;
context
.
serviceName
=
"test_service2"
;
context
.
serviceNode
=
serviceItem
;
(
void
)
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_PARSE
,
(
void
*
)(
&
context
),
NULL
);
ASSERT_NE
(
GetServiceExtData
(
"test_service2"
,
HOOK_ID_BOOTEVENT
),
nullptr
);
SERVICE_INFO_CTX
serviceInfoContext
;
serviceInfoContext
.
serviceName
=
"test_service2"
;
serviceInfoContext
.
reserved
=
nullptr
;
(
void
)
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_FORK_BEFORE
,
(
void
*
)(
&
serviceInfoContext
),
NULL
);
(
void
)
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_DUMP
,
(
void
*
)(
&
serviceInfoContext
),
NULL
);
(
void
)
HookMgrExecute
(
GetBootStageHookMgr
(),
INIT_SERVICE_CLEAR
,
(
void
*
)(
&
serviceInfoContext
),
NULL
);
}
HWTEST_F
(
ServiceUnitTest
,
TestServiceExec
,
TestSize
.
Level1
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录