Android -- init.rc配置文件简介
这篇文章的目的是记录近期从书中看到的内容,供后续查阅。
一个完整的init.rc脚本由四个部分组成:
- Actions-动作
- Commands-命令
- Services-服务
- Options-选项
它有一些通用的语法规则:
- 注释以"#"开头
- 关键字和参数以空格隔开,每个语句以行为单位
- C语言风格的反斜杠转义字符("\")可以用来为参数添加空格
- 为了防止字符串中的空格把其分隔成多个部分,我们需要对其使用双引号
- Actions和Services暗示着一个新语句的开始,这两个关键字后面跟着的commands或者options都属于这个新语句
- Actions和Services有唯一的名字,如果出现和已有动作或服务重名的,将会被当做错误忽略掉
init.rc文件是以块(section)为单位组织的,一个“块”可以包含多行。“块”分成两大类:一类称为“action(行为)”;另一类称为“service(服务)”。“行为”块以关键字“on”开始,表示一堆命令的集合,“服务”块以“service”开始,表示启动某个进程的方式和参数。“块”以关键字“on”或“service”开始,直到下一个“on”或“service”结束,中间所有行都属于这个“块”(空行或者注释都不具备分割作用)。
init.rc中注释以“#”号开始,下面是一部分.rc文件示例:
eg:
on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain
on property:sys.boot_from_charger_mode=1 // a
class_stop charger
trigger late-init // b
on nonencrypted
class_start main
class_start late_start
service installd /system/bin/installd
class main
socket installd stream 600 system system
on load_persist_props_action
load_persist_props
start logd // c
start logd-reinit // d
无论是“action”块还是“service”块,它们的执行顺序都与.rc文件中的声明顺序无关;是否执行及执行顺序要由init进程在运行时决定。
“action”的关键字“on”后面跟的字符串我们称之为“trigger(触发器)”,如上面的“boot”、“nonencrypted”,“trigger”后面的内容是命令列表。命令列表中的每一行都是一条命令,命令的种类非常多。
“行为”块的一般格式如下:
on <trigger>
<command>
<command>
<command>
“trigger”有多种格式,最简单的一种是一个单纯的字符串。这种简单的格式可以使用命令“trigger”来触发,如标记b处所示。另外一种常见的格式是“on property:<property>=<value>”,如标记a处所示,如果property值在运行时设定成了这里指定的值,如“1”,则“块”中的命令列表就会执行。
“service”块的关键字“service”后面的字符串是服务名称。我们可以使用“start”命令加“服务名称”来启动一个服务,如标记c、d处。服务名称后面是进程的可执行文件路径和要传递的启动参数。
“服务”块的一般格式如下:
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
关键字“service”以下的行称为“option(选项)”,选项也有很多种。常见的如“class”表示服务所属的类别;“class_start”可以同时启动一组服务。
上面的内容只是大概介绍了init.rc的文件格式,下面着重介绍init脚本的关键字定义
Android的rc脚本语言包含了4中类型的声明:Actions、Commands、Services和Options。所有这些都以行为单位,各种符号则由空格隔开。C语言风格的反斜杠可用于在符号间插入空格。双引号可用于防止字符串被空格分割成多个记号。行末的反斜杠用于折行。注释以“#”开头(运行以空格开头)。
Action和Service声明一个新的分组。所有命令或选项都属于最近申明的分组。位于第一个分组之前的命令或选项将被忽略。
Action其实就是一系列的Command集合。每个Action都有一个trigger,它决定本Action的执行时机。当一个符合Action触发条件的事件发生了,此Action会加入到执行队列的末尾(除非它已经在队列里了)。每一个Action都将依次从队列中取出,此Action的每个Command都将依次执行。在这些命令执行时Init还会同时处理着其他活动(创建设备节点、设置属性、重启进程等)。
Service则是一个后台程序,在Init中启动。
接着就来介绍下“action”和“service”中要使用到的关键字的具体定义:Options、Triggers和Commands。
Options
Options是Service的修订项,它们决定一个Service何时以及如何运行。
- critical:表示这是一个关键的服务。如果该Service4分钟内重新启动超过4次,系统将自动重启并进入recovery模式。
- disabled:表示服务不能通过start className(main/core等)启动。它必须以命令“start service_name”的形式显示指定名称启动。
- setenv <name> <value>:在Service启动时将环境变量“name”设置为“value”。
- socket <name> <type> [<user> [<group>]]:创建一个名为/dev/socket/<name>的套接字,并把文件描述符传递给要启动的进程。<type>的值是“dgram”或者是“stream”,User和group的值默认为0。
- user <username>:在启动这个Service前设置Service的用户名,默认是root。如果进程没有相应的权限,将不能使用该命令。如果进程有root权限,可以在程序中设置你想要的uid。
- group <groupname> [<groupname>]*:在启动这个Service前设置Service的服务。除了第一个组名,剩下的组名同城用于设置进程的附加组(通过setgroups())。默认是root。
- oneshot:Service退出后不再重启。
- class <name>:给Service指定一个名字。所有同名字的服务可以同时启动和停止。如果不通过class选项指定一个名字,则默认是“default”。
- onrestart:当Service重启时,执行一条命令。
- writepid <file...>:将当前进程的进程号写到<file...>文件中。
Triggers
Triggers是一个用于匹配某种事件类型的字符串,它将使对应的action执行
boot是Init执行后第一个触发的Trigger(在/init.conf装载之后)。
- <name>=<value>:这种形式的Trigger会在属性"name"设置为指定的“value”时被触发。
- device-added-<path>,device-removed-<path>:这种形式的Trigger会在一个设备文件增加或移除时触发。
- service-exited-<name>:这种形式的Trigger会在一个指定的Service退出时触发。
Commands
Commands是Action的命令列表中的命令,或者是Service的选项onrestart的参数命令。
- exec [ <seclabel> [ <user> [ <group> ]* ] ] -- <command> [ <argument> ]*:fork和启动一个程序,在程序完成启动之前,Init进程将会阻塞。command跟在“--”之后,在这之前我们可以指定像安全上下文、用户名和组名这样的参数信息;seclabel默认指定为“-”。
- export <name> <value>:设置全局环境变量<name>为<value>(所有在这命令执行之后运行的进程都将继承该环境变量)。
- ifup <interface>:启动网络接口<interface>。
- import <filename>:引入一个配置文件,扩展当前配置。
- hostname <name>:设置主机名。
- chdir <directory>:设置进程当前的工作目录。
- chmod <octal-mode> <path>:设置文件或目录的访问权限。
- chown <owner> <group> <path>:设置文件或目录的所有者和组。
- chroot <directory>:设置进程的根目录。
- class_start <serviceclass>:启动所有指定服务名称下的未运行服务。
- class_stop <serviceclass>:停止所有指定服务名称下的已运行的服务。
- domainname <name>:设置域名。
- insmod <path>:安装一个驱动模块。
- mkdir <path> [mode] [owner] [group]:新创建一个目录<path>,可以指定访问权限、拥有者和组。如果没有指定,默认的访问权限是755,属于root用户和root组。
- mount <type> <device> <dir> [ <mountoption>]*:在指定目录下挂载一个设备。<device>可以是以mtd@name的格式指定的一个mtd块设备。<mountoption>包括“ro”、“rw”、“remount”、“noatime”等。
- restorecon <path>:重新存储指定的文件到一个有file_contexts配置的安全上下文。不用指定目录,它们会被Init进程自动创建。
- setcon <securitycontext>:设置当前进程的安全上下文为指定的串。主要用在early-init中去设置Init的安全上下文。
- setenforce 0|1:设置SELinux系统级的enforcing状态。0代表permissive,1代表enforcing。
- setkey:目前未使用。
- setprop <name> <value>:设置系统属性<name>为<value>值。
- setrlimit <resource> <cur> <max>:设置<resource>的rlimit值。
- setsebool <name> <value>:设置SELinux的boolean型属性<name>的值为<value>。<value>的值可以是“1|true|on"或者”0|false|off“。
- start <service>:启动指定服务(如果此服务还未运行)。
- stop <service>:停止指定服务(如果此服务还在运行中)。
- symlink <target> <path>:创建一个符号连接。
- sysclktz <mins_west_of_gmt>:设置系统的时钟基准(0代表格林尼治平均时(GMT)为准)。
- trigger <event>触发一个事件。用于将一个Action和另一个Action连在一起执行。
- wait <path> [<timeout>]:等待指定路径的文件被创建出来,创建完成就停止等待,或者等到超时时间到达。如果未指定超时时间,缺省时间是5秒。
- write <path> <string> [<string]*:打开指定的文件,并写入一个或多个字符串。
更详细的字段定义可以查看/system/core/init/readme.txt文本中的官方介绍。
待续......