1、Linux 系统是十分优秀的操作系统,但启动时间长是该系统的缺点之一。那么能否通过一些设置来缩短 Linux 系统的启动时间呢?当然可以。本文将向读者展示如何在不牺牲 Linux系统可用性的前提下,缩短系统的启动时间。要实现这一目标,需要了解系统的各类服务及它们之间的从属关系,进而使它们在条件允许的前提下同时启动,从而大大节省系统启动时间。 准备工作 如果想采用本文介绍的方法对 Linux 系统进行设置,首先要熟悉 Linux 系统的设置语言。对系统的启动过程进行设置是一项比较危险的行为,容易造成系统无法启动。一旦发生这种情况,最好重新启动系统后选择单一用户模式,将系统还原并重启。当然,最重要
2、的是在设置前备份重要数据。 其次,建议用户最好在对本机系统进行修改前,先进行修改测试。如果用户只有一台计算机,那么这里建议使用用户模式 Linux 系统(UML)进行测试。UML 是一个内核补丁,它可以将 Linux 系统的内核转译成为二进制,以便用户可以像使用普通软件那样运行 Linux系统。一旦出现意外情况,损失的只是 UML,而原系统却可安然无恙。 Linux 系统的启动顺序和 runlevel Linux 系统的启动包括多个步骤,这里主要介绍一下内核加载后的系统启动步骤。用户可以通过运行/sbin/runlevel 命令来查看系统目前的 runlevel。runlevel 是 Linu
3、x 系统用来区别系统高级启动设置类型的数字。这些数字十分常见,它们中的绝大多数都有着明确的含义。以 Red Hat Linux 系统为例,它的 runlevel 主要有以下几种(见表 1): init 如何初始化系统 init 可以通过一个 ASC设置文件得知如何改变系统的 runlevel。通常情况下该设置文件可以指引 init 来执行/etc/rc.d/rc 命令,从而获得 runlevel 的相关信息。 系统服务 用户所需要的各种系统服务都是由 rc 指令程序来启动的。系统潜在的服务纷繁复杂。大多数 Linux 系统通常只提供 sshd(SecureShell 服务) 、syslog(
4、系统日志工具)和 lpd(打印服务)等功能。 用户可以从/etc/rc.d/目录中找到所有的服务。如果打开这个目录,会发现许多服务只是一种外壳程序,它只是引导其它程序来完成工作。也许有人会问,rc 程序是如何知道每个runlevel 要运行哪些程序呢?答案是在 /etc/rc.d/目录下面与 init.d/目录并列的还有一些目录,它们各自对应着自己的 runlevel。它们的名称为 rc*.d/,例如 runlevel 5 就是/etc/rc.d/rc5.d/ 。每个 rc*.d/目录中包含着两个符号链接,这些链接可以连接到/etc/init.d/目录中的指定服务程序。 动手改造 服务的启动和
5、终止 如果用户决定要启动 Linux 系统并进入图形模式(runlevel 5) ,那么当 init 引导 rc 指令程序运行并将 runlevel 的级数告知它时, rc 指令程序将对/etc/rc.d/rc5.d/进行查看,接着它将执行从该目录中找到所有链接。rc 指令程序执行链接的过程可分为两部分,首先它将执行所有名称以“K”打头的链接,将 “stop”参数传递给它们,并停止这些链接指向的所有服务。这些服务停止后,rc 指令程序将执行所有名称以“S”打头的链接,并将“start”参数传递给它们,启动这些链接所指向的服务。 另外,rc 指令程序可以根据链接名称的两个十进制数,确定链接的执行
6、顺序,数字小的先执行。 下面将举一个例子,帮助用户加深理解。当用户启动系统进入 runlevel 5 时,首先要执行的链接是 K05saslauthd,由于它是以“K ”打头的,而且后两位十进制数要小于其它以 “K”打头的链接。第一个要执行的启动链接是 S05kudzu。最后执行的将是 S99local。下面是runlevel 5 状态下指向程序的链接。 # cd /etc/rc.d/rc5.d# ls -altotal 8drwxr-xr-x2 rootroot4096 Jul 15 09:29 .drwxr-xr-x10 rootroot4096 Jun 21 08:52 lrwxrwxr
7、wx1 rootroot19 Jan12000 K05saslauthd - /init.d/saslauthdlrwxrwxrwx1 rootroot20 Feb12003 K15postgresql - /init.d/postgresqllrwxrwxrwx1 rootroot13 Jan12000 K20nfs - /init.d/nfslrwxrwxrwx1 rootroot14 Jan12000 K24irda - /init.d/irdalrwxrwxrwx1 rootroot17 Jan12000 K35winbind - /init.d/winbindlrwxrwxrwx1
8、rootroot15 Jan12000 K50snmpd - /init.d/snmpdlrwxrwxrwx1 rootroot18 Feb8 11:15 K92iptables - /init.d/iptableslrwxrwxrwx1 rootroot19 Feb12003 K95firstboot - /init.d/firstbootlrwxrwxrwx1 rootroot15 Jan12000 S05kudzu - /init.d/kudzulrwxrwxrwx1 rootroot14 Jun 21 08:55 S09isdn - /init.d/isdnlrwxrwxrwx1 ro
9、otroot17 Jan12000 S10network - /init.d/networklrwxrwxrwx1 rootroot16 Jan12000 S12syslog - /init.d/sysloglrwxrwxrwx1 rootroot17 Jan12000 S13portmap - /init.d/portmaplrwxrwxrwx1 rootroot17 Jan12000 S14nfslock - /init.d/nfslocklrwxrwxrwx1 rootroot18 Jan12000 S17keytable - /init.d/keytablelrwxrwxrwx1 ro
10、otroot16 Jan12000 S20random - /init.d/randomlrwxrwxrwx1 rootroot16 Jun 21 08:52 S24pcmcia - /init.d/pcmcialrwxrwxrwx1 rootroot15 Jan12000 S25netfs - /init.d/netfslrwxrwxrwx1 rootroot14 Jan12000 S26apmd - /init.d/apmdlrwxrwxrwx1 rootroot16 Jan12000 S28autofs - /init.d/autofslrwxrwxrwx1 rootroot14 Jan
11、12000 S55sshd - /init.d/sshdlrwxrwxrwx1 rootroot20 Jan12000 S56rawdevices - /init.d/rawdeviceslrwxrwxrwx1 rootroot16 Jan12000 S56xinetd - /init.d/xinetdlrwxrwxrwx1 rootroot14 Feb12003 S58ntpd - /init.d/ntpdlrwxrwxrwx1 rootroot13 Jun 21 10:42 S60afs - /init.d/afslrwxrwxrwx1 rootroot18 Jan12000 S80sen
12、dmail - /init.d/sendmaillrwxrwxrwx1 rootroot13 Jan12000 S85gpm - /init.d/gpmlrwxrwxrwx1 rootroot15 Mar 22 08:24 S85httpd - /init.d/httpdlrwxrwxrwx1 rootroot14 Jul 15 09:29 S98wine - /init.d/winelrwxrwxrwx1 rootroot13 Feb8 17:26 S99db2 - /init.d/db2lrwxrwxrwx1 rootroot11 Jun 21 08:52 S99local - /rc.l
13、ocal如果用户想暂时终止某一 runlevel 的一项服务,只要删除相对应的链接就行了。然而,对链接进行手动设置是一项繁重而又易错的工作,但有一个十分有用的帮手,它的名字叫chkconfig。 分辨没被终止的服务 要想了解哪些服务没有被终止,那么用户需要运行/sbin/chkconfig -list 命令。下面展示了命令执行后的显示结果,用户可以清楚地看到每一行有八项内容。chkconfig 命令还可以用来开启或终止某一服务。 afs0:off1:off2:off3:on4:off5:on6:offanacron0:off1:off2:on3:on4:on5:on6:offapmd0:off
14、1:off2:on3:on4:on5:on6:offatd0:off1:off2:off3:on4:on5:on6:offautofs0:off1:off2:off3:on4:on5:on6:offcrond0:off1:off2:on3:on4:on5:on6:off上面左起第一列显示的是服务的名称,接下来的第二列显示的是所在的 runlevel 和当前状态。例如 ntpd(网络时间无交互后台程序)服务被设定只在 runlevel 3 和 runlevel 5 开启,而 sshd 服务则在 runlevel 2、3、4 和 5 开启。 也许用户会发现,在 runlevel 0 和 runle
15、vel 6 没有启动的服务,是因为 runlevel 0 和 runlevel 6 表示系统终止,当然没有服务了。 从属关系 正如上文提到的,系统启动时要逐一运行每个 runlevel 的服务。也许用户很容易想到,如果可以使多个服务同时运行,必然会节省大量的系统启动时间。但不幸的是这种方法行不通,原因是各项服务之间都存在着从属关系。 传统的 Linux 系统并不能给用户指明服务间的从属关系。 现在通过一个简单的例子讲解如何明确服务间的从属关系。从 ntpd 服务需要一个网络基础可以得出结论ntpd 服务要依靠网络服务,这一关系可以用下面的语句表示: ntpd:network用户可以确定 net
16、fs 服务也要依靠网络服务,autofs 服务也要依靠网络服务,现在就可以列出一个简单的从属关系表: ntpd : networknetfs : networkautofs : network它的含义是一旦网络服务开启完毕,可以同时运行 ntpd、netfs 和 autofs 服务。假设启动每项服务需要 10 秒的时间,用传统的方法启动上面的四项服务就需要 40 秒的时间,而使用上面提到的方法只需要 20 秒就够了。事实上,各项服务的启动时间是不同的,但道理是一样的。 再例如,lpd 服务(S60lpd )要在网络服务后运行,但对于一个拥有喷墨打印机接口的家用系统而言,不必先建立网络连接再安装
17、打印机。在这种情况下,更合理的状况应该是打印机服务先于网络服务。另外 crond 服务(S90crond )同样应该在网络服务后运行。但是,除非用户有可以使用远端计算机文件的 cron 文件,否则 crond 服务根本不必在网络服务前运行。 可以看出,有些服务要依靠其它服务才能运行,有些服务是完全独立的,它们运行与否与其它服务毫无关系。因此,可以使这些与其它服务无从属关系的服务同时运行。当这些服务启动后,用户就可以启动以它们为运行前提的其它服务,这样环环相扣、循序渐进,直到启动整个系统。 听起来这似乎是一个十分复杂的过程,但是已经为用户准备了一件十分好用的工具,这就是“Make ”程序。 “Make”程序一般与编译软件一起使用,它可以为用户提供所需要的完整架构,用户只需要告诉它各项服务间的从属关系就行了。 结论 综上所述,缩短系统启动时间的方法就是先搞清各项服务间的从属关系,然后编排合理的启动次序,尽可能使限制条件相同的服务同时启动,当然别忘了只启动需要的服务。由于Linux 系统的种类不同,这种方法产生的效果也不尽相同,大家在使用过程中还要具体问题具体分析。