Signed-off-by: Goldgom <qym2005723@hotmail.com>
30 KiB
init组件
简介
init组件负责处理从内核加载第一个用户态进程开始,到第一个应用程序启动之间的系统服务进程启动过程。启动恢复子系统除负责加载各系统关键进程之外,还需在启动的同时设置其对应权限,并在子进程启动后对指定进程实行保活(若进程意外退出要重新启动),对于特殊进程意外退出时,启动恢复子系统还要执行系统复位操作。
目录
base/startup/init_lite/ # init组件
├── LICENSE
└── services
├── include # init组件头文件目录
├── src # init组件源文件目录
├── etc # init配置文件目录(json格式,镜像烧写后部署于/etc/init.cfg)
└── test # init组件测试用例源文件目录
└── unittest
device
└──hihope
└──rk3568
└──build
└──rootfs # init配置文件目录(适用于rk3568平台)
vendor
└──hisilicon
└──hispark_taurus_linux
└──init_configs # init配置文件目录(适用于L1 Linux内核版本)
约束
目前支持小型系统设备(参考内存≥1MB),如Hi3516DV300、Hi3518EV300以及RK3568等
使用说明
init将系统启动分为三个阶段:
“pre-init”阶段:启动系统服务之前需要先执行的操作,例如挂载文件系统、创建文件夹、修改权限等
“init”阶段:系统服务启动阶段
“post-init”阶段:系统服务启动完后还需要执行的操作
上述每个阶段在配置文件init.cfg中都用一个job表示,每个job都对应一个命令集合,init通过依次执行每个job中的命令来完成系统初始化。job执行顺序:先执行“pre-init”,再执行“init”,最后执行“post-init”,所有job都集中放在init.cfg的jobs数组中。
除上述jobs数组之外,init.cfg中还有一个services数组,用于存放所有需要由init进程启动的系统关键服务的服务名、可执行文件路径、权限和其他属性信息。
对于每个service的启动,从init拉起的方式上来区分,大致可分为以下三种策略:
- 通过start命令
在job中添加start service的命令,init将会在执行该job的阶段将对应服务拉起 - 分组并行启动
无须显式添加start命令,服务的start-mode属性为非condition配置,init将会为该服务按策略分组并在该分组服务启动时统一拉起 - 按需启动 按需启动的服务应当被认为是无须在系统启动过程中被拉起的,而是当需要时,这个当需要时的触发条件可能是被init监听的相关socket有消息上报、samgr收到客户端的请求需要拉起SA服务等情况,按需启动的服务需要配置ondemand属性为true,该属性拥有高优先级,配置该属性后服务将不再受start-mode属性控制,统一通过按需启动方式拉起
对于每个服务的启动,进程的运行,init提供了以保障系统安全性为目的的沙盒运行环境。每个进程运行时都有不同的环境约束,各个分层之间进程的资源隔离,确保每个进程都在各自的沙盒环境下运行,只访问允许的系统资源。
每个沙盒环境的分为只读资源和可写资源,只读资源由init在初始化时创建好,通过mount bind把只读文件指向全局FS中对应的目录,然后启动相应沙盒进程时通过chroot跳入到沙盒环境运行。对于可写目录,通过对全局/data目录进行划分,由存储服务进行统一管理分配,通过mnt namespace完成可写目录的沙盒化。
init的关键配置文件init.cfg位于代码仓库base/startup/init_lite/service/etc目录,部署在/etc/下,采用json格式,文件大小目前限制在100KB以内。
配置文件格式和内容说明如下所示:
{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /testdir",
"chmod 0700 /testdir",
"chown 99 99 /testdir",
"mkdir /testdir2",
"mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid"
]
}, {
"name" : "init",
"cmds" : [
"copy /testfile /testfile2",
"symlink /testfile /testlink",
"write /testfile 0",
"ifup lo",
"hostname testhost",
"domainname testdomain"
]
}, {
"name" : "post-init",
"cmds" : [
"trigger testjob",
"trigger testjob2"
]
}, {
"name" : "services:service2",
"cmds" : [
"chmod 0773 /data/service2"
]
}
],
"services" : [{
"name" : "service1",
"path" : ["/system/bin/process1"],
"socket" : [{
"name" : "process1",
"family" : "AF_NETLINK",
"type" : "SOCK_DGRAM",
"protocol" : "NETLINK_KOBJECT_UEVENT",
"permissions" : "0660",
"uid" : "system",
"gid" : "system",
"option" : [
"SOCKET_OPTION_PASSCRED",
"SOCKET_OPTION_RCVBUFFORCE"
]
}],
"critical" : [ 0, 15, 5],
"ondemand" : true
}, {
"name" : "service2",
"path" : ["/system/bin/process2"],
"start-mode" : "condition",
"disabled" : 1,
"console" : 1,
"uid" : "root",
"gid" : ["shell", "log", "readproc"],
"jobs" : {
"on-start" : "services:service2"
}
}
]
}
表 1 执行job介绍
最先执行的job,如果开发者的进程在启动之前需要首先执行一些操作(例如创建文件夹),可以把操作放到pre-init中先执行。 |
|
最后被执行的job,如果开发者的进程在启动完成之后需要有一些处理(如驱动初始化后再挂载设备),可以把这类操作放到该job执行。 |
单个job最多支持30条命令(当前仅支持start/mkdir/chmod/chown/mount/loadcfg),命令名称和后面的参数(参数长度≤128字节)之间有且只能有一个空格。
表 2 命令集说明
表 3 service字段说明
相关仓
[startup_init_lite]