Android init.rc 文件分析

本文详细解析了Android系统的init.rc文件,涵盖Action、Services、Commands和Options四大组成部分。Action涉及不同触发时机,如early-init、init和boot。Services部分讨论了服务启动,包括Service的生命周期和启动条件。Commands部分介绍了如class_start、start、stop等常用命令。Options作为Service的配置选项,如critical、disabled和class。文中通过实例分析了服务启动顺序、启动过程以及服务重启策略,揭示了Android系统服务间相互依赖的关系。

Android init.rc 文件分析

rc 脚本由4种类型声明组成,Action、Commands、Services、Options

Action(动作)

通过触发器 trigger,即以 on 开头的语句来决定执行相应的 service 的 时机,具体有如下时机:

  • on early-init : 在初始化早期阶段触发;
  • on init: 在初始化阶段触发;
  • on late-init: 在初始化晚期阶段触发;
  • on boot/charger: 当系统启动/充电时触发,还包含其他情况,此处不一一列举;
  • on property: key=value: 当属性值满足条件时触发;

Services(服务)

服务 Service,以 service 开头,由 init 进程启动,一般运行在 init 的一个子进程, 所以启动 service 前需要判断对应的可执行文件是否存在。
init 生成的子进程, 定义在 rc 文件,其中每一个 service 在启动时会通过 fork 方式生成子进程。
例如,代表的是服务名为 servicemanager,服务执行的路径为/system/bin/servicemanager。

Commands(命令)

常用的命令

  • class_start <service_class_name>: 启动属于同一个 class 的所有服务;
  • start <service_name>: 启动指定的服务,若已启动则跳过;
  • stop <service_name>: 停止正在运行的服务
  • setprop :设置属性值
  • mkdir :创建指定目录
  • symlink <sym_link>: 创建连接到的<sym_link>符号链接;
  • write : 向文件 path 中写入字符串;
  • exec: fork 并执行,会阻塞 init 进程直到程序完毕;
  • exprot :设定环境变量;
  • loglevel :设置 log 级别

Options(选项)

Options 是 Service 的可选项,与 service 配合使用。

  • critical 表示对设备至关重要的服务,如果在四分钟内退出超过四次,则设备将重启进入恢复模式;
  • disabled 表示此服务不会自动启动,需要显式调用服务名来启动;
  • class 为服务指定一个class名,同一个class的所有服务必须同时启动或者停止,默认为default
  • onrestart 当次服务重启时,执行某些命令;
  • onshot 当服务退出时,不会主动去重启它;
  • user 在服务启动前将用户切换到 username,默认为root;
  • group 在服务启动前将用户组切换到 groupname;
  • socket [[]] 创建一个名为 /dev/socket/的 unix domain socket,然后把fd值传给启动它的进程;
  • default: 意味着 disabled=false,oneshot=false,critical=false。

案例1 服务启动顺序

on early-init on init
on late-init
	trigger post-fs
	trigger load_system_props_action trigger post-fs-data
	trigger load_persist_props_action trigger firmware_mounts_complete trigger boot
	
on post-fs //挂载文件系统 
	start logd
	mount rootfs rootfs / ro remount
	mount rootfs rootfs / shared rec
	mount none /mnt/runtime/default /storage slave bind rec ...
	
on post-fs-data //挂载 data 
	start logd
	start vold //启动 vold
...
on boot //启动核心服务
...
class_start core //启动 core class

触发器的执行顺序为 on early-init -> init -> late-init。在 late-init 触发器中会触发文件系统挂载以及 on boot。再 on boot 过程会触发启动 core class。至于 main class 的启动是由 vold.decrypt 的以下 4 个值的设置所决 定的, 该过程位于 system/vold/cryptfs.c 文件。

on nonencrypted 
	class_start  
	class_start late_start
on property:vold.decrypt=trigger_restart_min_framework 
	class_start main
on property:vold.decrypt=trigger_restart_framework 
	class_start main
class_start late_start
on property:vold.decrypt=trigger_reset_main 
	class_reset main
on property:vold.decrypt=trigger_shutdown_framework 
	class_reset late_start
	class_reset main

案例2 服务启动

在 init.zygote.rc 文件中,zygote 服务定义如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-sys tem-server
	class main
	socket zygote stream 660 root system
	onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on
	onrestart restart media
	onrestart restart netd

通过init_paraser.cpp完成整个 service 解析工作,此处就不详细展开讲解析过 程,该过程主要工作是:

  • 创建一个名叫”zygote”的 service 结构体;
  • 创建一个用于 socket 通信的 socketinfo 结构体;
  • 创建一个包含 4 个 onrestart 的 action 结构体。

Zygote 服务会随着 main class 的启动而启动,退出后会由 init 重启 zygote,即 使多次重启也不会进入 recovery 模式。zygote 所对应的可执行文件是 /system/bin/app_process,通过调用pid = fork()创建子进程,通过exec(svc->args[0], (char**)svc->args,(char**)ENV) 进入app_main.cpp的main函数,故 zygote 是通过 fork 和 execv 共同创建的。

案例3 服务重启

服务重启流程
当 init 子进程退出时,会产生 SIGCHLD 信号,并发送给 init 进程,通过 socket 套接字传递数据,调用到 wait_for_one_process()方法,根据是否是 oneshot, 来决定是重启子进程,还是放弃启动。
所有的 Service 里面只有 servicemanager ,zygote ,surfaceflinger 这 3 个服 务有关键字来触发其他 service 启动过程。

//zygote 可触发 media、netd 重启
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main
	socket zygote stream 660 root system
	onrestart write /sys/android_power/request_state wake 				onrestart write /sys/power/state on
	onrestart restart media
	onrestart restart netd

//servicemanager 可触发 healthd、zygote、media、surfaceflinger、drm 重启 
service servicemanager /system/bin/servicemanager
	class core
	user system
	group system
	critical
	onrestart restart healthd onrestart restart zygote onrestart restart media 				onrestart restart surfaceflinger onrestart restart drm

//surfaceflinger 可触发 zygote 重启
service surfaceflinger /system/bin/surfaceflinger
	class core
	user system
	group graphics drmrpc onrestart restart zygote

由上可知:

  • zygote:触发 media、netd 以及子进程(包括 system_server 进程)重启;
  • system_server: 触发 zygote 重启;
  • surfaceflinger:触发 zygote 重启;
  • servicemanager: 触发 zygote、healthd、media、surfaceflinger、drm 重
    启。
    所以,surfaceflinger,servicemanager,zygote 自身以及 system_server 进程被杀 都会触发 Zygote 重启。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值