⑴ 帮忙解释AIX中的init谢谢!
AIX(Advanced Interactive eXecutive)是IBM开发的一套UNIX操作系统。它符合Open group的UNIX 98行业标准(The Open Group UNIX 98 Base Brand),通过全面集成对32-位和64-位应用的并行运行支持,为这些应用提供了全面的可扩展性。它可以在所有的IBM ~ p系列和IBM RS/6000工作站、服务器和大型并行超级计算机上运行。
在系统启动过程中,在预初始化过程中装入根文件系统之后,将发生下面这些事件:
作为启动过程中的最后一个步骤,运行 init 命令。
init 命令尝试读取 /etc/inittab 文件。
如果 /etc/inittab 文件存在,那么 init 命令将尝试在 /etc/inittab 文件中查找 initdefault 条目。
如果 initdefault 条目存在,那么 init 命令使用指定的运行级别作为初始的系统运行级别。
如果 initdefault 条目不存在,那么 init 命令将请求用户从系统控制台 (/dev/console) 输入一个运行级别。
如果用户输入 S、s、M、或者 m 运行级别,那么 init 命令将进入维护运行级别。只有这些运行级别不需要经过正确格式化的 /etc/inittab 文件。
如果 /etc/inittab 文件不存在,那么 init 命令在缺省情况下将使系统进入维护运行级别。
init 命令每隔 60 秒将再次读取 /etc/inittab 文件。如果在 init 命令上一次读取 /etc/inittab 文件之后,其中的内容发生了更改,那么将执行 /etc/inittab 文件中的新命令。
/etc/inittab 文件
/etc/inittab 文件用于控制初始化过程。
/etc/inittab 文件提供了相应的脚本,以使得 init 命令的角色成为通用的进程调度器。init 命令的进程调度活动中的主要进程是 /etc/getty 线路进程,它将启动单独终端线路。通常由 init 命令进行调度的其他进程包括守护进程和 Shell。
/etc/inittab 文件由一些与位置无关的条目组成,它们的格式如下所示:
Identifier:RunLevel:Action:Command
每个条目之间由一个换行符进行分隔。换行符前面加上一个反斜杠 (\) 表示继续该条目。在 /etc/inittab 文件中,对于条目的数目没有任何限制(但不能超过最大的条目大小)。最大的条目大小为 1024 个字符。
条目字段包括:
Identifier,由一到十四个字符组成的字段,唯一地标识一个对象。
RunLevel,可以对该条目进行处理的运行级别。
运行级别具有下面的属性:
运行级别有效地对应于系统中的进程配置。
可以为每个由 init 命令启动的进程分配一个或者多个运行级别(该进程可以存在于其中)。
运行级别使用数字 0 到 9 进行表示。例如,如果系统处于运行级别 1,那么只有那些在运行级别字段中包含 1 的条目才会启动。
当您请求 init 命令更改运行级别时,在运行级别字段中不包含匹配条目(对于目标运行级别)的所有进程都将接收到一个警告信号 (SIGTERM)。在使用删除信号 (SIGKILL) 强行结束这些进程之前,有 20 秒钟的过渡期。
通过使用从 0 到 9 的任意组合,可以选择多个运行级别,从而在运行级别字段中为一个进程定义多个运行级别。如果没有指定运行级别,那么就假定该进程在所有的运行级别中都是有效的。
在运行级别字段中,还可能出现其他四种取值,即使它们并不是真正的运行 级别:a、b、c 和 h。仅当使用 telinit 命令请求它们运行时(无论系统当前运行级别如何),才会处理那些运行级别字段中包含这些字符的条目。它们与运行级别的不同之处在于,init 命令不可能进入到运行级别 a、b、c 或者 h。另外,任何这些进程的执行请求都不会更改当前运行级别。而且,在 init 命令更改级别时,不会终止以 a、b 或者 c 命令开头的进程。只有在下面三种情况下才会终止它们:在 /etc/inittab 文件中,它们所在行的操作字段被标记为 off,从 /etc/inittab 中完全删除它们所在的行,或者 init 命令进入到单用户模式。
Action,用于告诉 init 命令如何处理在进程字段中指定的进程。init 命令能识别下列的操作:
respawn:如果进程不存在,则启动该进程。不需要等待它的结束(继续扫描 /etc/inittab 文件)。当进程中止时,重新启动该进程。如果该进程已经存在,则什么也不做,继续扫描 /etc/inittab 文件。
wait:当 init 命令进入到与该条目的运行级别相匹配的运行级别时,启动该进程,并等待它的结束。当 init 命令处于相同的运行级别时,所有后续对 /etc/inittab 文件的读取操作都将导致 init 命令忽略这个条目。
once:当 init 命令进入到与该条目的运行级别相匹配的运行级别时,启动该进程,并且不需要等待它的结束。当它中止时,不重新启动该进程。当系统进入一个新的运行级别,并且该进程的运行来自前一个运行级别更改时,不重新启动该程序。
boot: 仅在系统启动时(即在系统启动的过程中当 init 命令读取 /etc/inittab 文件的时候)处理该条目。启动该进程,不需要等待它的结束,并且当它中止时,不重新启动该进程。为了使得该指令有意义,运行级别应该为缺省值,或者它必须 与启动时 init 命令的运行级别相匹配。对于系统硬件重新启动之后的初始化功能来说,这种操作是非常有价值的。
bootwait:在系统启动之后,当 init 命令第一次从单用户进入到多用户状态时,处理该条目。启动该进程,等待它的结束;并且当它中止时,不重新启动该进程。如果 initdefault 为 2,那么在启动之后运行该进程。
powerfail:仅当 init 命令接收到电源故障信号 (SIGPWR) 时,才执行与这个条目相关联的进程。
powerwait:仅当 init 命令接收到电源故障信号 (SIGPWR) 时,才执行与这个条目相关联的进程,并且在继续处理 /etc/inittab 文件之前,必须等待它结束。
off:如果与这个条目相关联的进程目前正在运行,那么发送警告信号 (SIGTERM),等待 20 秒钟,然后使用删除信号 (SIGKILL) 终止该进程。如果该进程没有运行,则忽略这个条目。
ondemand:从功能上看,与 respawn 是相同的,但是这个操作适用于 a、b 或者 c 值,而不是运行级别。
initdefault: 仅在 init 命令最初被调用时,才扫描包含这个操作的条目。init 命令使用这个条目(如果它存在的话)来确定最初要进入的运行级别。通过使用运行级别字段中所指定的最高运行级别,就可以实现这一点,并使用它作为其初始状 态。如果运行级别字段为空,那么将其解释为“0123456789”:因此,init 命令将进入运行级别 9。另外,如果 init 命令在 /etc/inittab 文件中没有找到 initdefault 条目,那么将要求用户在启动时指定一个最初的运行级别。
sysinit:当 init 命令在登录之前尝试访问控制台时,将执行这种类型的条目。在正常情况下,这个条目仅用于初始化设备(init 命令可能会对这些设备询问有关运行级别的问题)。执行这些条目,并等待它们结束,然后再继续。
Command: 要执行的 Shell 命令。整个命令字段以 exec 作为前缀,然后以 sh -c exec command 的形式传递给一个使用 fork 系统调用生成的 sh。任何合法的 sh 命令语法都可以出现在这个字段中。可以使用 # comment 语法插入注释。
getty 命令将覆盖 /etc/inittab 文件中出现在它之前的任何命令的输出。要将这些命令的输出记录到启动日志,可以使用管道将它们的输出传递给 alog -tboot 命令。
在 init 命令处理 inittab 条目时,stdin、stdout 和 stderr 文件描述符可能是不可用的。向 stdout 或者 stderr 进行写入操作的任何条目都可能无法按照预期的方式工作,除非它们将自己的输出重定向到一个文件或者 /dev/console。
对于修改 /etc/inittab 文件中的记录,仅支持下列的命令:
mkitab:将记录添加到 /etc/inittab 文件。
lsitab:列出 /etc/inittab 文件中的记录。
chitab:更改 /etc/inittab 文件中的记录。
rmitab:删除 /etc/inittab 文件中的记录。
例如,您希望向 /etc/inittab 文件添加一条记录,以便在运行级别 2 中运行 find 命令,并且在它结束后再次启动它:
1. 运行 ps 命令,并显示那些仅包含单词 find 的进程:
# ps -ef
grep find
root 19750 13964 0 10:47:23 pts/0 0:00 grep find
#
2. 使用 mkitab 命令向 /etc/inittab 添加一条名为 xcmd 的记录:
# mkitab "xcmd:2:respawn:find / -type f > /dev/null 2>&1"
3. 使用 lsitab 命令显示新的记录:
# lsitab xcmd
xcmd:2:respawn:find / -type f > /dev/null 2>&1
#
4. 显示进程:
# ps -ef
grep find
root 28972 13964 0 11:07:33 pts/0 0:00 grep find
#
5. 结束 find 进程:
# kill 25462
6. 显示进程:
# ps -ef
grep find
root 23538 13964 0 10:58:24 pts/0 0:00 grep find
root 28966 1 4 10:58:21 - 0:00 find / -type f
#
由于 action 项被设置成为了 respawn,所以一个新的 find 进程(上面显示的 28966)在前一个进程结束后又被系统启动了。
这个进程会被不断的重新启动,除非把 action 项的设置修改,如:
1. 把 xcmd 这条记录的 action 项的值从 respawn 修改为 once:
# chitab "xcmd:2:once:find / -type f > /dev/null 2>&1"
2. 显示进程:
# ps -ef
grep find
root 20378 13964 0 11:07:20 pts/0 0:00 grep find
root 28970 1 4 11:05:46 - 0:03 find / -type f
3. 结束 find 进程:
# kill 28970
4. 显示进程:
# ps -ef
grep find
root 28972 13964 0 11:07:33 pts/0 0:00 grep find
#
可以看到 find 进程没有再被系统启动。
要从 /etc/inittab 文件中删除这条记录,您可以使用 rmitab 命令。例如:
# rmitab xcmd
# lsitab xcmd
#
/etc/inittab 条目的顺序
在 /etc/inittab 文件中,基本条目按照如下所示的方式进行排序:
initdefault
sysinit
Powerfailure Detection (powerfail)
Multiuser check (rc)
/etc/firstboot (fbcheck)
System Resource Controller (srcmstr)
Start TCP/IP daemons (rctcpip)
Start NFS daemons (rcnfs)
cron
pb cleanup (piobe)
getty for the console (cons)
必须在 etc/inittab 文件的开始处附近启动系统资源控制器(System Resource Controller,SRC),因为需要 SRC 守护进程来启动其他进程。因为 NFS 需要 TCP/IP 守护进程正确地运行,所以应该在启动 NFS 守护进程之前启动 TCP/IP 守护进程。/etc/inittab 文件中的条目根据依赖关系进行排序,这意味着,如果一个进程 (process2) 的正常运行需要另一个进程 (process1) 的存在,那么在 /etc/inittab 文件中,process1 的条目应该出现在 process2 的条目之前。