Initscripts (简体中文)

From ArchWiki
Jump to: navigation, search
摘要
一个按照时间顺序对 Arch 启动过程的概览。
概览
为了启动 Arch Linux,一个与 Linux 兼容的启动引导程序,如 GRUB, GRUB2, LILO, 或者 Syslinux 必须被安装到主引导记录(MBR), 或者GUID 分区表(GPT)。启动引导程序的任务是初始化 Arch 启动过程,然后加载内核以及初始化内存盘
相关页面
fstab (简体中文)
rc.conf (简体中文)
Arch Boot Process (简体中文)
Autostarting

本文按照时间顺序介绍 Initscripts 的启动过程以及使用的相关系统文件和进程,同时提供相关的 wiki 文章的链接。与常见的 SysV 启动架构不同,Initscripts 沿用了 BSD init 传统。系统默认设置成不同的 runlevel 运行相同的模块,不同的 runlevel 之间没有区别。优点是用户可以更简单地配置启动过程 (参见 rc.conf);缺点是一些 SysV 提供的精细调整好的配置选项没有了。Adding Runlevels 介绍如何把 SysV-like 的功能容纳到 Arch 中的方法。Wikipedia:init 包含了 SysV 和 BSD style 之间区别的更多信息。

Contents

init: The Arch boot scripts

Arch主要的启动过程是由init完成的,他通过克隆出其他的进程(以及这些进程克隆出的进程),使系统进入一个可用的状态。正如前文中提到的,Arch使用的是一种BSD风格的引导脚本。具体来说,init程序会首先读取/etc/inittab这个配置文件,inittab通常像这样:

/etc/inittab
...

# Boot to console
id:3:initdefault:
# Boot to X11
#id:5:initdefault:

rc::sysinit:/etc/rc.sysinit
rs:S1:wait:/etc/rc.single
rm:2345:wait:/etc/rc.multi
rh:06:wait:/etc/rc.shutdown
su:S:wait:/sbin/sulogin

...

根据这个文件的第一个未被注释掉的行可知,系统默认的启动级别为3(启动器(bootloader)通常可以给内核传递系统的运行级别,如果没有传递,系统运行级别就采用这里的默认值),当内核调用init时:

  • 首先,运行主初始化脚本/etc/rc.sysinit,这是个Bash脚本。
  • 如果系统处于单用户模式(运行级别为1或者S),系统就会接着运行/etc/rc.single脚本。否者,如果系统处于2~5之间的运行级别,系统就会接着运行/etc/rc.multi脚本。
  • 最后运行的脚本是/etc/rc.local,这个脚本默认什么都没有。

/etc/rc.sysinit

rc.sysinit是一个很大的启动脚本。它通过一系列的初始化任务,完成所有的硬件配置。当你看到屏幕打印出下面这些行时,代表它开始运行了:

Arch Linux
https://www.archlinux.org

rc.sysinit 的任务是:

  1. 导入/etc/rc.conf文件
  2. 导入/etc/rc.d/functions文件
  3. 显示欢迎信息
  4. 挂载各种各样的虚拟文件系统(proc、sysfs之类的)
  5. 保证 rootfs 挂载为只读
  6. 启动 bootlogd
  7. 显示过期警告
  8. 配置硬件时钟
  9. 启动 udev,从 rc.conf 定义的 MODULES 数组装入文件等待 udev 处理完冷启动事件
  10. 启动回环(loopback)接口
  11. 配置RAID、btrfs 和加密文件系统映射
  12. 运行fsck检查相应分区的完整性
  13. 根据 /etc/fstab 中的配置重新挂载 rootfs
  14. 挂载本地文件系统(由于网络未加载,网络设备不会挂载)
  15. 启动 lvm 组的监视
  16. 激活交换分区
  17. 配置时区
  18. 初始化随机种子
  19. 移除leftover/temporary文件中的临时变量和文件,比如/tmp/*
  20. 根据rc.conf中的配置,设置主机名、locale、系统时钟
  21. 配置本地化、终端、键盘映射
  22. 设置终端字体
  23. 输出dmesg中输出的信息到/var/log/dmesg.log

/etc/rc.sysinit是一个脚本。他本身并不包含任何的配置信息,而是通过导入rc.conf来读取配置信息。就连他内部使用的很多实现彩色输出(比如右对齐的busy、done字符串)的函数,也是定义在/etc/rc.d/functions中。通常情况下不需要编辑这个文件。 升级时会被覆盖,要进行定制,请使用下面的钩子。

/etc/rc.single

单用户(Single)模式通常在无法正常启动时使用,他会直接以root用户启动。除了最基本的syslog-ng和udev外,不会启动任何服务。单用户模式在修复系统时,需要避免远程用户操作导致数据丢失时很有用。单用户模式下可以直接在提示符后输入'exit'进入到多用户模式。

/etc/rc.multi

/etc/rc.multi通常在多用户模式(运行级别为2~5)下执行。通常情况,从rc.sysinit切换到rc.multi时,用户不太能感觉到。因为两者使用的函数类似,导致输出的提示信息也差不多。这个脚本主要执行以下任务:

  • 首先,会根据/etc/sysctl.conf的设置,运行sysctl以在运行时修改内核参数,Arch除了网络配置外,通常很少用这么干。
  • 然后,会根据rc.conf文件中的DAEMONS变量,执行非常重要的——服务(守护进程)启动任务。
  • 最后,会执行/etc/rc.local脚本

/etc/rc.local

Warning: 如果同时安装了 systemd 和 initscripts,存在 /etc/rc.local 而且 systemd >= 197-4, 系统将无法完成启动,需要删除 /etc/rc.local 或卸载 initscripts.

/etc/rc.local 是本地多用户启动脚本,默认是空的。可以讲启动最后需要运行的程序放在这里。大部分系统配置任务(例如模块装入、字体修改、设备启动等) 都有固定的设置位置。为了避免混淆,请保证加入的命令不适合放在其他地方,例如 /etc/profile.d

编辑时请记得其中的命令会在大部分设置完成后以 root 用户运行,不管 X 有没有启动。下面例子中,rc.local 脚本开启 ALSA 声音设置:

/etc/rc.local
#!/bin/bash

# /etc/rc.local: Local multi-user startup script.

amixer sset 'Master Mono' 50% unmute &> /dev/null
amixer sset 'Master' 50% unmute &> /dev/null
amixer sset 'PCM' 75% unmute &> /dev/null

自定义钩子

钩子可以在 rc.* 脚本的不同位置加入自定义指令.

脚本名 执行位置
sysinit_start rc.sysinit 启动开始
sysinit_udevlaunched udev 被 rc.sysinit 启动之后
sysinit_udevsettled uevents 被 rc.sysinit 处理后
sysinit_prefsck rc.sysinit 运行 fsck 前
sysinit_postfsck rc.sysinit 运行 fsck 后
sysinit_premount rc.sysinit 将 root 被挂载成读写模式后,本地文件系统挂载前
sysinit_end rc.sysinit 结束
multi_start rc.multi 执行前
multi_end rc.multi 结束时
single_start rc.single 开始
single_prekillall rc.single 停止所有进程前
single_postkillall rc.single 停止所有进程后
single_udevlaunched rc.single 执行 udev 后
single_udevsettled rc.single 处理 uevents 后
single_end rc.single 结束时
shutdown_start rc.shutdown 开始时
shutdown_prekillall rc.shutdown 停止所有进程前
shutdown_postkillall rc.shutdown 停止所有进程后
shutdown_preumount 所有文件系统写结束后,卸载文件前。
shutdown_postumount 所有文件系统卸载后
shutdown_poweroff rc.shutdown 关闭系统前

要创建钩子,在/etc/rc.d/functions.d 中创建文件:

function_name() {
   ...
}
add_hook hook_name function_name

/etc/rc.d/functions 会引入/etc/rc.d/functions.d 中的所有文件。. 可以同时注册多个钩子,或者在多个钩子中注册同一函数。不要再这些文件中使用 add_hook 或 run_hook 作为函数名,这两个函数在 /etc/rc.d/functions 中有定义。

示例

如下钩子会在所有 daemon 启动禁用硬盘的回写缓存 (可以优化包含 MySQL InnoDB 文件的硬盘)。

/etc/rc.d/functions.d/hd_settings
hd_settings() {
    /usr/bin/hdparm -W0 /dev/sdb
}
add_hook sysinit_udevsettled hd_settings
add_hook single_udevsettled  hd_settings

先定义函数 hd_settings,然后注册到 single_udevsettledsysinit_udevsettled hooks。函数会在 /etc/rc.d/rc.sysinit/etc/rc.d/rc.single 处理完 uevent 消息后立即执行。

init: 登录

默认情况下,Arch启动过程完成后,agetty程序就会启动,并提示用户输入用户名。在输入用户名后agetty调用login,提示用户输入登录密码。

最后,在成功登录后login会启动用户的默认会话终端(shell)。默认终端和环境变量在/etc/profile下定义。还有一些别的配置在/etc目录下的文件中定义。用户也可以在自己的家目录下通过~/.bashrc这类的文件重新定义。如果两部分的定义冲突,那么将会优先采用主目录下的定义。

mingetty提供了一些选项,可以实现自动登录的功能。rungetty 也提供了一些用户登陆时自动运行程序的功能。

大多数用户可能希望启动图形界面,这个时候可以安装一个KDM、GDM之类的显示管理器(参考显示管理器)。

扩展资源