linux第一个用户进程init--sysvinit

来源:互联网 发布:淘宝客免费建站 编辑:程序博客网 时间:2024/05/22 08:29

在《linux系统启动》一文中介绍了计算机从按开机键到系统启动的流程,在流程启动的最后一步就是启动系统的第一个用户态进程init进程,其进程ID永为1(其实还有一个id为0的进程swap,即有名的idle进程,当cpu没有进程可以运行时就会自动运行此进程,严格意义上来讲此进程才是内核创建的第一个进程)。

本文介绍一下init进程启动之后以及操作系统运行过程中都做了什么操作,以及担当什么样的角色。

目前比较流行的init进程分为三种:sysvinit、upstart、systemd。本文先重点介绍一下sysvinit。很多linux发行版中使用了sysvinit(即sysvinit-XXX.rpm包),里面包含了/sbin/init、/sbin/telinit、/sbin/runlevel等进程。

init的执行分为三个阶段(参见linux-init-process-analyse.pdf)


虽然是三个阶段,但是设计者写代码时把三个阶段合一了,都包含在/sbin/init进程中,根据不同的条件来走不能的流程。详细信息可以参见linux-init-process-analyse.pdf,这里只介绍重点内容。

1,在系统启动阶段init进程读取/etc/inittab文件中配置并将所有配置组成一个链表,后面循环此链表,并对每一项进程操作。


对于/etc/inittab文件需要注意以下几点:

  • 格式:id:runlevels:action:process
  • id很重要,必须唯一,因为作者对init的实现是当有重复id时不是忽略掉,而是直接停止继续处理后面内容。
  • action值为wait的配置项表示必须等我这个项操作完init才能去操作剩下的配置项,这导致了sysvinit机制很难并行执行,这一点也是upstart与systemd机制出现的原因。action值为respawn表示,这个配置项中的process(如图中的mingetty)退出了,init进程有责任把此进程再重新拉起来。所以大家在登录linux串口时即使杀掉tty进程也会回到登录界面,就是这个原因。
  • 想在系统启动阶段做一些特殊操作的话就可以从这里面入手,例如init会执行/etc/rc.d/rc脚本,可以添加自己的脚本文件来实现想要的功能。

2,系统启动过程中init执行完/etc/inittab中需要执行的操作之后,系统就算真正的启动了,这个时候init进程就会进入第三个阶段,即作为一个deamon来运行。

  • 首先创建一个管道/dev/initctl
  • 其次通过select系统调用等待在/dev/initctl管道的一端,一旦有进程往另一端写入希望init process执行的request,init 3就会分析该request,然后执行要求的动作(见check_init_fifo函数)
  • 同时当有signal发送给init process时,init在signal handler中并不马上处理该signal,而仅仅是在全局变量got_signals中置一下该signal发生过的标志,真正的处理是在init 3的循环中的process_signals()中。

3,当具有root权限的用户通过运行init来切换运行级别时,这种情况就称为init的第二个阶段,当然第三个阶段也就是为了处理这个阶段的请求才作为deamon来运行的。也即后面的交互都是第二阶段和第三阶段的交互,其桥梁就是管道/dev/initctl。


在管道/dev/initctl中传输的request格式如下:

struct init_request {

    int magic; /* Magic number */

    int cmd; /* What kind of request */

    int runlevel; /* Runlevel to change to */

    int sleeptime; /* Time between TERM and KILL */

    union {

        struct init_request_bsd bsd;

        char data[368];

    } i;

};

0 0
原创粉丝点击