作为一名系统管理员,您应该对启动过程具有全面的认识。对于解决影响系统正常启动的问题来说,这种认识是非常有帮助的。这些问题 可能涉及软件和硬件两方面。我们还建议您应该熟悉您的系统的硬件配置。文章是节选自 IBM 的红皮书《IBM Certification Study Guide eServer p5 and pSeries Administration and Support for AIX 5L Version 5.3 》。
![]() |
启动过程包含下面的一些步骤:
- 启动一个系统的初始步骤是上电自检(Power On Self Test,POST)。其目的是验证基本硬件是否处于正常的工作状态。同时初始化内存、键盘、通信,以及音频设备。您可以看到在屏幕上显示了所有的这些设 备。在这个步骤中,您可以按下功能键,以选择不同的启动列表。这个阶段中所显示的 LED 值是模型特定的。硬件和软件方面的问题都可能使得系统无法启动。
注意:基于 MCI 体系结构的旧系统在这个步骤之前还将执行一个附加的步骤,即所谓的内建自检(Built In Self Test,BIST)。对于基于 PCI 体系结构的系统,不再需要执行这个步骤。 - 系统只读存储器(System Read Only Storage,ROS)对于每种类型的系统来说都是特定的。它是启动 AIX 5L Version 5.3 所必需的,但是它并不为启动工作构建所需的数据结构。它将定位和加载引导 (bootstrap) 代码。系统 ROS 中包含通用的启动信息,并且是独立于操作系统的。
- 软件 ROS(也称为引导程序)构成了 IPL 控制块,它与 AIX 5L Version 5.3 是兼容的,用于接收控制和构建 AIX 5L 的特定启动信息。将在内存中定位一种特殊的文件系统,并创建一种名为 RAMFS 的文件系统。然后,软件 ROS 定位、加载、并将控制权交给 AIX 5L 启动逻辑卷 (BLV)。软件 ROS 是基于计算机类型的 AIX 5L 信息,并且负责完成计算机准备工作,以使得它能够启动 AIX 5L 内核。
- 可以从 /usr/lib/boot 目录中获得 BLV 中所包含的文件的完整列表。其中最重要的组件包含以下内容:
- AIX 5L 内核
- 在启动过程中调用的启动命令,如 bootinfo 和 cfgmgr
- ODM 的一个简化的版本。在 hd4 可供使用之前,需要对许多设备进行配置,所以它们的相应方法必须存储在 BLV 中。这些设备都被标记为预定义设备 (PdDv) 中的基础设备。
- rc.boot 脚本
- 加载 AIX 5L 内核,并接管控制权。系统将在 LED 面板上显示 0299。前面所有的代码都是与硬件相关的。通过配置设备和启动 init 进程,内核将完成启动过程。在这个阶段中所显示的 LED 代码都是通用的 AIX 5L 代码。
- 到此为止,系统对硬件进行了检测、找到了 BLV、创建了 RAMFS,并且从 BLV 中启动了 init 进程。但是尚未激活 rootvg。从现在开始,将调用三次 rc.boot 脚本,并且每次都传递不同的参数。
在这个阶段中,将执行下面的步骤:
- 从 RAMFS 启动的 init 进程将执行启动脚本 rc.boot 1。如果出于某种原因,init 进程执行失败,那么将在 LED 显示屏上显示代码 c06。
- 在这个阶段中,将调用 restbase 命令,以便将 ODM 的部分镜像从 BLV 复制到 RAMFS。如果这个操作成功完成,那么 LED 显示屏将显示 510;否则,将显示 LED 代码 548。
- 在执行了该操作之后,cfgmgr -f 命令将从简化的 ODM 中读取 Config_Rules 类。在这个类中,将属性 phase=1 的设备认为是基础设备。基础设备是访问 rootvg 所需的所有设备。例如,如果 rootvg 位于某块磁盘中,那么必须对从主板到磁盘之间的所有设备进行初始化。调用相应的方法,以便能够在启动阶段 2 中激活 rootvg。
- 在启动阶段 1 结束后,将调用 bootinfo -b 命令以确定最后的启动设备。在这个阶段中,LED 将显示 511。
在启动阶段 2 中,向 rc.boot 脚本传递的参数为 2。
在这个阶段中,将执行下面的这些步骤:
- 可以使用 varyonvg 命令(名为 ipl_varyon 命令)的特殊版本来激活 rootvg 卷组。如果这个命令执行成功,那么系统将显示 517;否则,将显示下面 LED 代码中的某一个:552、554、或者 556,并且停止启动过程。
- 使用 fsck -f 命令来检查根文件系统 hd4。该操作将验证在上一次关机之前是否已经干净地卸载了这个文件系统。如果这个命令执行失败,那么系统将显示代码 555。
- 将根文件系统 (/dev/hd4) 装入到 RAMFS 中的临时装入点 (/mnt)。如果这个操作执行失败,那么在 LED 显示屏中将显示 557。
- 使用 fsck -f 命令检查 /usr 文件系统,然后进行装入。如果这个操作执行失败,那么 LED 将显示 518。
- 使用 fsck -f 命令检查 /var 文件系统,然后进行装入。使用 copycore 命令检查是否发生了转储。如果发生了转储,那么从缺省转储设备 /dev/hd6 复制到缺省复制目录 /var/adm/ras。然后,卸载 /var。
- 激活 rootvg 的主分页空间 /dev/hd6。
- 调用 mergedev 进程,并将 RAM 文件系统的所有 /dev 文件复制到磁盘。
- 将 RAM 文件系统中所有自定义的 ODM 文件复制到磁盘。对于 hd4 和 hd5 中的两个 ODM 版本,现在进行同步。
- 最后,将 rootvg(磁盘)中的根文件系统装入到 RAMFS 的根文件系统。rootvg 文件系统的装入点已变得可用。现在,再次将 rootvg 的 /var 和 /usr 文件系统装入到它们的正常装入点。
在阶段 2 完成之后,激活了 rootvg,并将执行下面的步骤:
- 启动 /etc/init 进程。它将读取 /etc/inittab 文件,并使用参数 3 调用 rc.boot。
- 装入 /tmp 文件系统。
- 通过调用 syncvg 命令(将该命令启动作为一个后台进程)对 rootvg 进行同步。因此,将对 rootvg 中所有过时的分区进行更新。在这个阶段中,将显示 LED 代码 553。
- 在这个阶段中,将调用 cfgmgr 命令;如果系统以正常模式进行启动,那么将使用选项 -p2 来调用 cfgmgr 命令;如果系统以服务模式进行启动,那么将使用选项 -p3 来调用 cfgmgr 命令。cfgmgr 命令将从 ODM 读取 Config_rules 文件,并且调用与 phase=2 或者 phase=3 相对应的所有方法。所有其他非基础设备的设备,并不在这里进行配置。
- 接下来,通过调用 cfgcon 命令对控制台进行配置。在配置了控制台之后,如果没有设置 STDOUT 重定向,那么启动消息将发送到控制台。然而,可以在 /var/adm/ras/conslog 中找到所有遗漏的消息。此时,可能显示的 LED 代码包括:
- c31:控制台尚未配置。提供相应的指令以选择控制台。
- c32:控制台是 LFT 终端。
- c33:控制台为 TTY。
- c34:控制台为磁盘中的文件。
- 最后,使用 savebase 命令对 BLV 中的 ODM 与 / (root) 文件系统中的 ODM 进行同步。
- 启动 syncd 守护进程和 errdemon。
- LED 显示屏将关闭。
- 如果文件 /etc/nologin 存在,则将其删除。
- 如果 CuDv 中有设备被标记为缺失,那么将在控制台中显示一条消息。
- 消息“System initialization completed”发送到控制台。rc.boot 执行完成。进程 init 将继续处理 /etc/inittab 中的下一条命令。
在系统启动过程中,在预初始化过程中装入根文件系统之后,将发生下面这些事件:
- 作为启动过程中的最后一个步骤,运行 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 文件提供了相应的脚本,以使得 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 文件中,基本条目按照如下所示的方式进行排序:
- 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 的条目之前。
转载于:https://blog.51cto.com/837244/1025567