|
|
今天无意间看到一篇使系统服务并行运行加快系统启动速度的文章,于是
尝试了下,感觉办法很不错,同时让我对lfs的系统引导脚本有了更深的理解
总觉得系统启动太慢的兄弟们不妨研究研究尝试下。
原文在:
http://www-900.ibm.com/developerWorks/cn/linux/l-boot/index.shtml
03年11月的了,不知道有没有人已经在sir发过,刚才搜索下好象没找到。
因为要修改系统启动的脚本,很可能让系统启动不正常,所以最好有双linux系统,即使修改错误了,还可以从另一个系统引导修复。
如果很不幸,没有的话,可以先学下这招,紧急救护系统也有用 :p
紧急救护模式:
[PHP]
grub菜单中选择linux,按e,e,进入编辑模式,kernel......那一行最后加上
init=/bin/bash,这样引导系统可以得到一个bash shell
这样进入的系统会是read-only的,首先先使用fsck检查系统
fsck -a /dev/hdaX 处理根分区
fsck -R -A -a 处理其他分区
如果系统在上次重启,是正常重启的,文件系统是正常卸载的,可以不用fsck检查直接把系统挂载成read-write的
mount / -o remount,rw
mount /proc
swapon -a 打开所有的交换分区
在修复好系统后将系统重新挂载成ro的,就可以安全重启了。
mount / -o remount,ro
[/PHP]
下面简单的说一下linux系统的启动过程
如果你想更了解系统的启动,这有篇文章非常好。
http://www.faqs.org/docs/Linux-H ... h-Prompt-HOWTO.html
当grub加载内核后,/sbin/init首先从/etc/inittab取得运行级别
id:3:initdefault: 这里启动级别是3--文本模式
si::sysinit:/etc/rc.d/init.d/rc sysinit
这一行代表在任何运行级别都去执行/etc/rc.d/init.d/rc
sysinit 是传入的参数,并且这是init执行的第一个脚本,做系统的最基本的初始化,比如挂载proc系统拉,检查根分区拉,开启swap拉。等等
但是在不同的发行版可能不同,比如在Mandrakelinux中是:si::sysinit:/etc/rc.d/rc.sysinit
init执行的则是/etc/rc.d/rc.sysinit
经过了系统的初始化后,init开始读取run-level中的脚本,这些脚本位于
/etc/rc.d/rcX.d目录下。X是当前的运行级别.这里是系统启动的服务,比如network,alsa,httpd....等
l3:3:wait:/etc/rc.d/rc 3
:3:表示这是在运行级别3中执行的脚本,wait表示init会等待这些脚本都执行
完再继续运行,不知道如果改为once会怎么样,还没有实验.... :ask
另外有的发行版会在执行rcX.d之后去执行/etc/rc.d/rc.local
最后就看到可爱的login拉 
在/etc/rc.d/rcX.d中的脚本都是以SXX+服务名或者KXX+服务名组成的,并且都是到/etc/rc.d/init.d中相应脚本的符号链接,有的发行版是/etc/init.d
其中XX是0-9的数字,数字越小,则启动的时间越早。
以S开头的表示系统启动时传递start参数的服务,就是开启拉。K开头的就是
传递stop参数拉。kill bill...
/etc/rc.d/rc3.d:
S10sysklogd@ S20network@ S25random@ S30httpd S40alsa@ S85numlock@
可以看出,我的系统进入rc3.d时首先启动的服务是sysklogd,最后是numlock
很明显,httpd服务必须要在network之后运行,不然没有网络哪来的web服务?想知道系统是怎么识别这些数字作为顺序的吧,俺也是今天才知道的。。
原来是用ls -v 列出它们,挨个放血 
逐一的去执行它们,这样就会使系统启动的速度很慢,服务越多越明显
现在希望做的就是,让那些相互之间没有依赖关系的服务可以同时开启,而不是逐一的执行,这样系统启动的速度就会加快很多了。
而相互有依赖关系的服务,告诉make这些服务的依赖关系,然后让make去解决
再使用make -j 参数使服务可以并行启动。
在makefile中写入服务之间的相依赖关系
httpd : network
表示httpd依赖network,这样在network启动完毕,则可以启动httpd
而其他不相依赖的服务可以同时进行,这样系统启动的速度就快多拉 :2cool
原理就是这样,下面是我的实际做法:
首先是make 的配置文件:
/etc/rc.d/runlevel.mk
- ########################################################################
- # Description : Gnu Makefile to control the services in the specified
- # runlevel. It will run the required services, and log
- # the output of the services to the file
- # /var/log/initd.start (for service startup) and
- # /var/log/initd.stop (for service shutdown).
- #
- # This controlling program is designed to be invoked by
- # the "/etc/rc.d/rc" script.
- #
- # Author : [email]jameshunt@uk.ibm.com[/email]
- #
- # Notes :
- #
- # - Run as,
- #
- # make [-n] -j -f runlevel.mk \
- # RUNLEVEL={0|1|2|3|4|5|6} \
- # JOB={start|stop|restart|status}
- #
- # - $(JOB) is not validated - that is left to the service program.
- # - $(RUNLEVEL) is not validated - that is left to the calling program
- # (usually /etc/rc.d/rc).
- # - It wouldn't take too much effort to auto-generate this Makefile.
- #
- ########################################################################
- # passed as a parameter
- RUNLEVEL =
- # passed as a parameter (start, stop, status, etc)
- JOB =
- # set to a value to enable debug output
- DEBUG =
- ########################################################################
- # START CONFIGURATION
- # system commands used by this facility
- CAT = /bin/cat
- RM = /bin/rm
- ECHO = /bin/echo
- DATE = /bin/date
- # Directory containing scripts/programs to run.
- INITD_DIR := /etc/rc.d/init.d #这里要修改成自己系统的所有服
- #务脚本存放目录,有些发行版是/etc/init.d 这个目录必须正确
- # Directory into which a lock file is created when a service starts.
- # (Note that the lock file is created by the service).
- SUBSYS_FILE_DIR := /var/lock/subsys #这个目录自己创建
- # Used to create temporary files, before collating them all into
- # $(FINAL_OUTPUT_FILE).
- TMP_DIR := /tmp
- TMPFILE_PREFIX := .runlevel
- TMP_FILE = $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).$@
- # File that contains all output of programs/scripts run.
- FINAL_OUTPUT_FILE = /var/log/initd.$(JOB)
- # List of *all* services.
- #
- # (Important Note: if you don't include a service in this list,
- # it won't get run!)
- #这里写上所有的需要启动的服务,这些服务的名字必须要与/etc/rc.d/init.d
- #中的名字一致的。
- ALL = \
- sysklogd \
- network \
- httpd \
- random \
- alsa \
- numlock \
- # END CONFIGURATION
- ########################################################################
- # Check command-line parameters
- ifndef RUNLEVEL
- $(error must specify RUNLEVEL, so I know what to run)
- endif
- ifndef JOB
- $(error must specify JOB, so I know what to do)
- endif
- default: $(ALL) create_final_output_file
- ifneq ($(DEBUG),)
- @$(ECHO) "RUNLEVEL=$(RUNLEVEL)"
- @$(ECHO) "JOB=$(JOB)"
- @$(ECHO) "FINAL_OUTPUT_FILE=$(FINAL_OUTPUT_FILE)"
- @$(ECHO) "TMP_FILE=$(TMP_FILE)"
- @$(ECHO) "ALL=|$(ALL)|"
- #@$(ECHO)
- #@$(ECHO) "ALL (less local)=|$(filter-out local,$(ALL))|"
- #@$(ECHO)
- #@$(ECHO) "ALL (less kudzu)=|$(filter-out kudzu,$(ALL))|"
- #@$(ECHO)
- endif
- ##############################################################
- # Generic rule to control a service.
- #
- # Note that we capture all output to a file.
- $(ALL) : $(SUBSYS_FILE_DIR)/$@
- @$(ECHO) "Begin "$(JOB) $@" at `$(DATE)`" > $(TMP_FILE)
- @$(INITD_DIR)/$@ $(JOB) >> $(TMP_FILE) 2>&1
- @$(ECHO) "End "$(JOB) $@" at `$(DATE)`" >> $(TMP_FILE)
- ##############################################################
- # List of services that have dependencies.
- #
- # (Note: It is not necessary to list services that have no
- # dependencies).
- # Include the relevant dependencies. If you intend to use this facility,
- # you must provide 2 makefiles / runlevel, one for starting the services
- # in the runlevel, and one for stopping the services in the runlevel.
- #
- # WARNING: If make attempts to include a file that does not exist, it will
- # exit. This could cause your system to boot in an unfamiliar way.
- include /etc/rc.d/start3.mk #这里是服务依赖关系的记录文件
- #
- # Lastly, merge all the service output files into a single file.
- # Note that the order of the service output in the merged file is not
- # chronological.
- create_final_output_file :
- $(CAT) $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).* \
- > $(FINAL_OUTPUT_FILE)
- $(RM) -f $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).*
- # EOF
复制代码
/etc/rc.d/start3.mk #由上面的runlevel.mk决定位置名称
httpd : network
其中的空格必须是用TAB键打出来的
最后修改/etc/rc.d/init.d/rc使其不再运行/etc/rc.d/rcX.d中的脚本,而去执行
/etc/rc.d/runlevel.mk,实现服务的并行启动
/etc/rc.d/init.d/rc :
另外要修改rc脚本时,要注意语法。修改后用sh -n rc 测试有没有语法错误
并且这个rc位置也是由/etc/inittab决定的
如果MDK中rc就是在/etc/rc.d下。
l3:3:wait:/etc/rc.d/rc 3
另外哪位大侠知道这个变量是在哪里定义的阿?找了半天也没找到。
previous=$PREVLEVEL
一点小笔记,希望对你有帮助 |
|