Init rc 文件语法

Android init语言支持这五类语句:Actions, Commands, Services, Options, and Imports。其中#是注释符号,init.rc是主rc文件。

一、Actions

Actions种命令序列,它有一个trigger用于确定何时执行该操作。当一个事件同一个action的trigger匹配时,则将该action添加至待执行命令序列的队尾(除非已经存在于队列中)。队列中每个action都是按顺序出列执行的,包括设备创建/销毁、属性设置、进程重启等行为。其格式如下:

1
2
3
4
on <trigger1>
<command1>
on <trigger2> [&& <trigger2>]*
<command2>

二、Commands

(1)bootchart [start|stop]
用于启动或停止bootcharting,默认被设置在init.rc文件中。
但若/data/bootchart/enabled文件存在bootcharing就会被激活,否则没有任何操作。

(2)chmod <octal-mode> <path>
用于改变文件权限。

(3)chown <owner> <group> <path>
用于改变所有者或群组。

(4)class_start <serviceclass>
用于启动指定类的所有服务,若它们尚未运行。

(5)class_stop <serviceclass>
用于停止指定类的所有服务,若它们正在运行。

(6)class_reset <serviceclass>
用于停止指定类的所有服务,若它们正在运行且未被禁用。
稍后会用class_start重启它们。

(7)class_restart <serviceclass>
用于重启指定类的所有服务。

(9)copy <src> <dst>
用于将文件从源目录拷贝至目标目录。类似写操作,但是主要针对二进制或大数据。
默认以0600权限创建目标文件,另外源文件不能是链接文件、world-writable文件、group-writable files文件。

(10)domainname <name>
用于设置域名。

(11)enable <servicename>
用于将禁用服务转为启用服务。若该服务正在运行则立即启动。

(12)exec [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]
用于根据给定参数fork并执行指令。该指令在–之后开始,以便于可以提供一个可选的安全上下文,用户或补充群组。除非它执行完成否则不会执行其它指令。_seclabel可以默认是-,属性在argument中展开。直到fork进程退出否则init不会终止执行命令。

(13)exec_background [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]
用于根据给定参数fork执行指令。类似exec指令,差异在于init不会停止执行它除非进程退出。

(14)exec_start <service>
用于启动一个给定的服务,并暂停其它init命令执行进程直至其返回为止。类似于exec指令,差异在于它使用已存在的服务定义取代exec参数向量。

(15)export <name> <value>
用于在全局环境中将环境变量name设置为_value。

(16)hostname <name>
用于设置主机名

(17)ifup <interface>
用于将网络接口_interface联机。

(18)insmod [-f] <path> [<options>]
用于在路径path上安装模块。’-f’表示即使运行内核版本同编译内核版本不匹配也强制安装。

(19)load_all_props
用于加载/system,/vendor中属性。

(20)load_persist_props
用于在/data解密后加载persist相关属性。

(21)loglevel <level>
用于设置kernel日志输出级别。

(22)mkdir <path> [mode] [owner] [group]
用于在指定路径path创建目录,包括可选模式,所有者,群组。
若未指定则目录默认权限为755,所有者和群组均为root。若指定则更新相关讯息。

(23)mount_all <fstab> [ <path> ]\* [--<option>]
用于在给定fs_mgr-format的fstab文件上调用fs_mgr_mount_all,在指定路径导入rc文件且选择‘early’/‘late’。
Refer to the section of “Init .rc Files” for detail.

(24)mount <type> <device> <dir> [ <flag>\* ] [<options>]
用于挂载设备。dir对应目录,_flag_s包括”ro”, “rw”, “remount”, “noatime”等,options包括”barrier=1”, “noauto_da_alloc”, “discard”等。

(25)restart <service>
用于停止重启运行的服务。如果该服务正在重启则什么也不做,否则启动该服务。

(26)restorecon <path> [ <path>\* ]
用于将path命名的文件还原到file_contexts配置的指定安全上下文中。

(27)restorecon_recursive <path> [ <path>\* ]
用于递归将path命名的文件还原到file_contexts配置的指定安全上下文中。

(28)rm <path>
用于在给定路径调用unlink。

(29)rmdir <path>
用于在给定路径调用rmdir。

(30)readahead <file|dir> [--fully]
用于在给定文件或指定目录文件上调用readahead,–fully参数表示读取整个文件内容。

(31)setprop <name> <value>
用于按属性name设置属性value

(32)setrlimit <resource> <cur> <max>
用于对资源设置限制。

(33)start <service>
用于启动该服务(该服务尚未运行),但它并非同步的。

(34)stop <service>
用于停止正在运行的服务。

(35)swapon_all <fstab>
用于在所给的fstab文件中调用fs_mgr_swapon_all。

(36)symlink <target> <path>
用于创建一个指定路径的链接。

(37)sysclktz <mins_west_of_gmt>
用于设置系统时钟基准

(38)trigger <event>
用于触发事件。action按顺序排列。

(39)umount <path>
用于卸载该路径上安装的文件系统。

(40)verity_load_state
用于加载dm-verity状态的内部实现细节。

(41)verity_update_state <mount-point>
用于加载dm-verity状态并设置分区的内部实现细节。

(42)wait <path> [ <timeout> ]
用于轮询指定路径文件,找到时返回,可设定超时时间,默认为5s。

(43)wait_for_prop <name> <value>
用于等待为指定系统属性name设置value

(44)write <path> <content>
用于打开指定路径path的文件并写入内容。若文件不存在则直接创建,若已存在则被截取。

三、Services

Services是init启动或重启退出时的程序,需要注意的是Services名称具有唯一性,若定义重名的Services会出错被忽略。其格式如下:

1
2
3
service <name> <pathname> [ <argument> ]*
<option1>
...

四、Options

Options是init处理Services的修饰符,包括如何、合适运行这些服务。

(1)console [<console>]
此服务需要一个控制台。可选的第二个参数选择特定的控制台而不是默认控制台。
可以通过设置“androidboot.console”内核参数来更改默认的“/dev/console”。
在所有情况下,应省略前导“/dev/”,因此“/dev/tty0”将被指定为“console tty0”。

(2)critical
这是一项设备关键型服务。 如果它在四分钟内退出四次以上,设备将重启进入恢复模式。

(3)disabled
此服务不会自动从其类开始。它必须由名称明确启动。

(4)setenv <name> <value>
在启动的进程中将环境变量name设置为value

(5)socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
创建名为/dev/socket/name的unix域套接字,并将其fd传递给已启动的进程。
type必须是“dgram”,“stream”或“seqpacket”。用户和组默认为0。
‘seclabel’是套接字的SELinux安全上下文。它默认为服务安全性上下文,由seclabel指定或基于服务可执行文件安全性上下文计算。

(6)enter_namespace <type> <path>
输入位于pathtype类型的命名空间。type设置为“net”时仅支持网络命名空间。只能输入给定type的一个名称空间。

(7)file <path> <type>
打开文件路径并将其fd传递给已启动的进程。type必须是“r”,“w”或“rw”。

(8)user <username>
在执行此服务之前更改为“用户名”。当前默认为root。
从Android M开始,进程应该使用此选项,即使它们也是如此需要Linux功能。
以前,要获得Linux功能,进程需要以root身份运行,请求功能,然后转到所需的uid。
通过fs_config有一种新机制,允许设备制造商将Linux功能添加到应该使用的文件系统上的特定二进制文件中。
使用此新机制时,进程可以使用user选项选择所需的uid,而无需以root身份运行。
从Android O开始,进程也可以直接在.rc文件中请求功能。

(9)group <groupname> [ <groupname>\* ]
在执行此服务之前更改为“groupname”。除了(必需的)第一个之外的其他组名用于设置进程的补充组(通过setgroups())。
当前默认为root。

(10)capabilities <capability> [ <capability>\* ]
执行此服务时设置功能。’capability’应该是没有“CAP_”前缀的Linux功能,如“NET_ADMIN”或“SETPCAP”。

(11)setrlimit <resource> <cur> <max>
这将给定的rlimit应用于服务。rlimits由子进程继承,因此这有效地将给定的rlimit应用于此服务启动的进程树。
它的解析类似于下面指定的setrlimit命令。

(12)seclabel <seclabel>
在执行此服务之前,请更改为“seclabel”。主要供从rootfs运行的服务使用,例如 ueventd,adbd。
系统分区上的服务可以基于其文件安全上下文使用策略定义的转换。如果未指定且策略中未定义转换,则默认为init上下文。

(13)oneshot
退出时不再重新启动的服务。

(14)class <name> [ <name>\* ]
指定服务的类名。命名类中的所有服务可以一起启动或停止。
如果未通过class选项指定服务,则服务在“默认”类中。除了(必需的)第一个之外的其他类名用于对服务进行分组。

(15)animation class
‘animation’类应该包括启动动画和关闭动画所需的所有服务。由于这些服务可以在启动期间很早启动,并且可以运行到关闭的最后阶段,因此无法保证对/data分区的访问。这些服务可以检查/data下的文件,但它不应该保持文件打开,并且在/data不可用时应该工作。

(16)onrestart
服务重新启动时执行命令(见下文)。

(17)writepid <file> [ <file>\* ]
在fork时将孩子的pid写入给定的文件。意味着cgroup/cpuset的使用。如果没有指定/dev/cpuset/下的文件,
但是系统属性’ro.cpuset.default’被设置为非空的cpuset名称(例如’/foreground’),
则pid被写入文件/dev/cpuset/_cpuset_name_/任务。

(18)priority <priority>
调度服务进程的优先级。 该值必须在-20到19的范围内。默认优先级为0.优先级通过setpriority()设置。

(19)namespace <pid|mnt>
在fork服务时输入新的PID或mount命名空间。

(20)oom_score_adjust <value>
将子项的/proc/self/oom_score_adj设置为指定值,该值必须介于-1000到1000之间。

(21)memcg.swappiness <value>
将子目录的memory.swappiness设置为指定值(仅当安装了memcg时),该值必须等于或大于0。

(22)memcg.soft_limit_in_bytes <value>
将子目录的memory.soft_limit_in_bytes设置为指定值(仅当安装了memcg时),该值必须等于或大于0。

(23)memcg.limit_in_bytes <value>
将子目录的memory.limit_in_bytes设置为指定值(仅当安装了memcg时),该值必须等于或大于0。

(24)shutdown <shutdown_behavior>
设置服务进程的关闭行为。如果未指定,则在关闭过程中使用SIGTERM和SIGKILL终止服务。
shutdown_behavior为“critical”的服务在关闭期间不会被终止,直到关闭超时。
当关机超时时,即使标记为“关键关键”的服务也将被终止。当关闭开始时标记为“关键关键”的服务未运行时,将启动它。

五、Imports

import <path>
解析init配置文件,扩展当前配置。若path是目录则会将该目录文件都解析,但是不支持递归嵌套目录。
import关键字不是命令,既不会作为action被执行。

导入rc文件有三个时机,分别是:
1.在初始引导期间导入/init.rc或属性ro.boot.init_rc指示的脚本时。
2.在导入/init.rc后立即为第一阶段安装设备导入/{system,vendor,odm}/etc/init/。
3.在mount_all期间在指定路径导入/{system,vendor,odm}/etc/init/或.rc文件时。

保证在另一个命令之前运行命令的唯一正确方法是:
1)将其置于具有较早执行触发器的Action中,
2)将其置于具有相同触发器的Action中 早先的一行。

六、Triggers

触发器是一些字符串,可用于匹配某些类型的事件并用于导致操作发生。触发器可分为事件触发器和属性触发器。Action可以有多个属性触发器,但可能只有一个事件触发器。
事件触发器是由“trigger”命令或init可执行文件中的QueueEventTrigger()函数触发的字符串。它们采用简单字符串的形式,例如’boot’或’late-init’。
属性触发器是当命名属性将值更改为给定新值或命名属性将值更改为任何新值时触发的字符串。它们分别采用’property: = ‘和’property: = \ *’的形式。 在init的初始引导阶段,还会相应地评估和触发属性触发器。

1
2
3
4
5
6
7
8
`on boot && property:a = b`
#定义了一个只在'boot'事件触发发生且属性a等于b时执行的动作。

`on property:a = b && property:c = d`
#定义了一次三次执行的动作:
#1.在初始引导期间,如果属性a = b且属性c = d。
#2.任何时候属性a转换为值b,而属性c已经等于d。
#3.任何时候属性c转换为值d,而属性a已经等于b。