SysVinit (简体中文)
init是Linux内核加载后执行的第一个进程。Arch的默认的 init 程序是systemd-sysvcompat提供的/sbin/init
(新安装的系统已经默认使用systemd) 或 sysvinitAUR.。本文中,init指sysvinit。
inittab文件位于/etc目录,是init的启动配置文件,其中指定了一些启动脚本、程序的路径,并指定在哪些运行级别执行它们。
迁移到 Systemd
从2012-10-13版安装介质开始,安装程序已经默认安装systemd 和 systemd-sysvcompat。本部分帮助还在使用sysvinitAUR 和 initscripts 的用户迁移到 systemd.
- 阅读该站,了解 systemd。
- systemd 自己有一套日志(journal)系统,用于代替 syslog。
- 虽然 systemd 可以替换 cron、acpid、xinetd 等的部分功能。至少目前还可以继续使用这些服务,无需立即切换。
- 交互式 initscripts 启动脚本在 systemd 中无法工作。
安装
- 从官方软件仓库安装 systemd 并添加内核参数
init=/usr/lib/systemd/systemd
- 使用
systemctl enable <服务名>
启用需要的服务(大致相当于以前DAEMONS
数组的作用,新的服务名称参见 Daemons List (简体中文))。 - 重启系统,执行命令
cat /proc/1/comm
,如果返回systemd
,表示 systemd 已经正常启动。 - 确认主机名已经正确设置:
hostnamectl set-hostname myhostname
。 - 删除 initscripts 和 sysvinit,并安装systemd-sysvcompat.
- (可选)删除
init=/usr/lib/systemd/systemd
内核参数,现在已经不需要它了。systemd-sysvcompat 软件包提供了一个软链接,使 systemd 成为默认 init。
附加信息
- 如果内核参数中有
quiet
,建议在一开始先去掉,以便调试。 - 使用 systemd 的时候无需将用户加入特殊用户组(如
sys
、disk
、lp
、network
、video
、audio
、optical
、storage
、scanner
、power
等等)。加入这些组反而会有问题,例如audio组会导致程序阻塞软件混声。每个 PAM 登录都拥有一个 logind 会话,它通过POSIX ACLs,赋予本地会话以声音设备访问权限、通过udisks挂载和卸载移动设备的权限等。 - 阅读 Network configuration (简体中文),了解如何配置网络。
init、inittab 概览
init总是Linux的1号进程,并且是一切进程的父进程。通过pstree
可以形象看出init在所有进程中所处的地位。
$ pstree -Ap
init(1)-+-acpid(3432) |-crond(3423) |-dbus-daemon(3469) |-gpm(3485) |-mylogin(3536) |-ngetty(3535)---login(3954)---zsh(4043)---pstree(4326) |-polkitd(4033)---{polkitd}(4035) |-syslog-ng(3413)---syslog-ng(3414) `-udevd(643)-+-udevd(3194) `-udevd(3218)
除了系统初始化,init还负责重启、关机、单用户恢复模式。为了支持上述操作,inittab把条目分到不同的运行级别(runlevel)中去。Arch使用以下运行级别:0——关机,1(又叫S)——单用户模式,3——普通的多用户模式,5——X使用,6——重启。其他发行版可能有所不同,但0、1、6级别是通用的。
运行时,init检查inittab并进行适当的操作。inittab中的启动项目格式如下:
id:runlevels:action:process
id
是项目独一无二的标识符(但只是个名称,对init没任何作用);runlevels
是一串无分隔字符串,设置运行级别;当init进入了指定的runlevels
,执行action
;如果顺利,执行process
。某些特殊的action
会忽略runlevels
,使用特殊的匹配方法。下一节有更详细的介绍。
调整运行级别
通过启动加载器
想要改变系统启动时的运行级别,只需要添加想要的运行级别 n
到启动加载器的内核参数。这通常的应用是 #inittab。要启动到需要的运行级别,将号码加入 内核参数 (例如 3
则启动要运行级别 3)。
运行级别追加到最后,这样内核就知道用哪个运行级别启动。想要使用另一个 init 程序(如 systemd),添加init=/usr/lib/systemd/systemd
或者类似的命令到内核行。
启动之后
系统启动后,可以调用telinit n
通知init切换到运行级别n
。然后init读取inittab,并做出当前运行级别到新的运行级别需要的改变——杀死新级别中没有的进程,执行旧级别未执行过的操作。两个级别共有的进程此时都会保留不动。杀死进程的过程有些复杂,技术信息参见init的manpage。
init不会监视inittab的改动,需要执行telinit
应用更改。telinit q
命令只应用inittab而不会修改运行级别。
inittab
这一部分将探究inittab中的常见项目,之后会给出几个inittab项目的实例。叙述顺序按照Arch默认的inittab。
telinit q
测试修改过的 /etc/inittab
,任何小小的语法错误都将导致系统无法启动。默认运行级别
默认运行级别为3。如果想要设置默认运行级别为5(通常X使用的级别),添加下面一行内容:
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
单用户启动
有时,因为重要文件丢失、文件系统损坏或硬件问题,内核可能启动失败。此时init可能自动进入单用户模式,此模式只允许使用root登陆,使用/sbin/sulogin(而非/sbin/login)控制login进程。也可以在 GRUB, LILO 或 syslinux 启动项添加S参数进入单用户模式。如果不想使用sulogin,可以在这里设置:
su:S:wait:/sbin/sulogin -p
终端初始化
该部分是初始化虚拟终端的关键。默认设置会在tty1-6开启6个getty,显示终端登陆提示。另见:openvt, chvt,stty,ioctl。
c1:234:respawn:/sbin/agetty 9600 tty1 xterm-color c5:5:respawn:/sbin/agetty 57600 tty2 xterm-256color
Ctrl-Alt-Del
以下内容定义按下Ctrl+Alt+Del
组合键时进行的操作:
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
X 程序
如果不怕麻烦,在inittab中启动各种程序都是可以的。以下内容示范了如何设置系统进入运行级别5时启动登陆管理器 SLiM :
x:5:respawn:/usr/bin/slim >/dev/null 2>&1 #x:5:respawn:/usr/bin/xdm -nodaemon -confi /etc/X11/xdm/archlinux/xdm-config
电源检测脚本
init可以根据UPS设备状态执行相应进程,示例如下:
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
自定义键盘请求
类似Ctrl+Alt+Del
,下面的内容添加了按下特定组合键时执行命令的功能:
kb::kbrequest:/usr/bin/wall "Keyboard Request -- edit /etc/inittab to customize"
触发 kbrequest
使用root用户,可以通过向init发送WINCH信号触发kbrequest。对于上述例子,命令:
kill -WINCH 1
会导致wall
命令执行,向所有用户发送信息:
Broadcast message from root@askapachehost (console) (Wed Oct 27 14:02:26 2010): Keyboard Request -- edit /etc/inittab to customize
另见
- Automatic login to virtual console
- Disable clearing of boot messages
- 开机启动 X
- Xinitrc (简体中文)
- 登陆管理器
- SLiM (简体中文)