4.2技术细节
rc.d系统包含下面的内容:
/etc/rc 启动启动脚本
/etc/rc.shutdown 系统关闭脚本
/etc/rc.d/* 单个的服务脚本
/etc/rc.subr 各种脚本使用的通用程序(shell code)
/etc/default/rc.conf 系统默认的配置文件
/etc/rc.conf 系统配置文件
/etc/rc.conf.d/* 单一的服务配置文件
4.2.1 /etc/rc
系统启动后,init将运行/etc/rc
/etc/rc用rcorder对/etc/rc.d中的服务脚本排序:为含有nostart关键字的服务脚本排序(建立服务名的列表);然后为含有 start关键字的服务脚本排序(建立服务名的列表),并依这个列表逐个启动它们.
支持nostart关键字是为了:允许那些(不想)自动启动而通过(手工)启动的第三方脚本可以放入/etc/rc.d目录.netbsd的发布版本中并没有脚本(使用这个特性).
4.2.2 /etc/rc.shutdown
当系统关闭时,/etc/rc.shutdown将被shutdown调用,而halt,reboot,poweroff(不会使用)这个脚本.
/etc/rc.shutdown调用rcorder为那些包含有shutdown关键字的脚本建立依赖关系的列表(这个列表是脚本的名字),然后(翻转)这个列表,接着,/etc/rc.shutdown调用(这个列表)以每个脚本执行stop来关闭服务.
The rationale for this is that only a few services (such as databases) actually require a shutdown mechanism more complicated than the SIGHUP sent by /sbin/init at shutdown time. Also, having every script perform ` stop ' slows down system shutdown as well as causing problems in other areas (such as cleanly un-mounting a `busy' NFS mount once the networking services have been stopped).
4.2.3 /etc/rc.d/*中的服务脚本
这些脚本被/etc/rc调用(使用start参数),被/etc/rc.shutdown调用(使用stop参数),当然是按照rcorder(上面介绍的)排出的顺序逐个start和stop.
当然这些脚本可以被系统管理员手动运行(比如starting,reloading配置文件,stopping.等)
每个脚本都得(互斥)支持下面的参数:
start:启动服务.检查/etc/rc.conf中是否允许它启动.当然如果已经运行,则拒绝再次运行了.
stop:关闭服务,前提是/etc/rc.conf中允许启动了的话.
其他一些netbsd的/etc/rc.d脚本支持的参数:
restart:执行stop,然后start
status:如果脚本运行了一个进程(而不是一次性的),则显示进程的状态信息.另外,这个参数不是必须的.默认是显示进程的id(如果运行了的话).
rcvar:显示/etc/rc.conf用来控制这个服务的参数(如果有的话).
如果参数前加了force前缀,那么告诉脚本不检查/etc/rc.conf 是否设定允许它运行(即yes).这样允许管理员不用手工编辑/etc/rc.conf来管理那些被disable(不允许运行)的服务.(force) 也将检查服务是否运行.
这里有一些(站位符)placeholder服务,这些服务被其他一些服务需要使用以便确定是在那些placeholder服务完成操作之前或者之后运行.这些脚本通常有大写的名字,并按照默认的启动启动顺序排列:
NETWORK 确保网络服务已经运行,包跨网络配置(network),和dhclient
SERVERS 确保基本服务(如,NETWORK,ppp,syslogd,kdc)已存在....
DAEMON 在所有常用的daemon前,比如dhcpd,lpd,ntpd.
LOGIN 在用户登陆服务前(如inetd,telnetd,rshd,sshd,xdm),当然也在那些用户命令前(如cron,postfix, sendmail)
4.2.4,/etc/defaults/rc.conf,/etc/rc.conf,/etc/rc.conf.d/*
/etc/defaults/rc.conf包含了包准系统服务的默认配置,用来为系统升级提供方便.用户一般不要编辑它.
/etc/rc.conf是系统启动机制主要的配置文件.它先读取/etc/defaults/rc.conf(如果存在),然后(读取)用户放在其中的配置(这些配置覆盖了/etc/defaults/rc.conf的配置).这样,系统默认配置和用户改变了的配置就分的比较清楚.和freebsd提供的差不多
对于一个服务foo,它可以有自己的单独的配置文件在/etc/rc.conf.d/foo,当读完/etc/rc.conf后将读取这个单独的配置文件.这个方法允许第三方软件安装自己默认的配置文件而不必编辑/etc/rc.conf.
我们举例,比如:/etc/rc.conf中的dhclient是这样的:
dhclient=YES
dhclient_flags="-q tlp0"
(系统进入多用户模式,rc.conf中的rc_configured必须为yes,否则,系统进入单用户模式.系统安装的时候已经改变为yes了,但是系统升级后,我们需要手动改变它. /etc/rc.conf是一个shell脚本,所有我们可以放置一些shell命令以及其参数......)
4.2.5 /etc/rc.subr
它是一个shell脚本,包含被rc.d系统使用的函数.
checkyesno VAR
测试变量设置为yes还是no,yes返回0,no返回1
check_pidfile pidfile procname
解析pidfile的第一行的到PID,如果这个procname的进程正在运行,则打印pid.
load_rc_config command
载入rc.conf中的对command的配置,先看/etc/rc.conf,再看/etc/rc.conf.d/command(如果存在).
run_rc_command arg
Implement the `guts' of an rc.d script. This is highly flexible, and supports many different service types. arg is argument describing the operation to perform (e.g., `start' or `stop'). The behavior of run_rc_command is controlled by shell variables defined before invoking the function.
使用rc.subr,netbsd的rc.d系统看起来很小.
举例:/etc/rc.d/dhclient
#!/bin/sh
#
# PROVIDE: dhclient
# REQUIRE: network mountcritlocal
. /etc/rc.subr
name="dhclient"
rcvar=$name
command="/sbin/${name}"
pidfile="/var/run/${name}.pid"
load_rc_config $name
run_rc_command "$1"
并不要求一定要使用这些函数. 只要含有rcorder控制的行,以及支持start和stop操作的shell脚本不用修改都可以正常工作.为了于rc.d中的脚本保持一致,一般也要支持restart status,rcvar操作,包括支持force前缀.
4.2.6 rcorder
/sbin/rcorder提供脚本执行的顺序功能.它读取每个服务脚本中关于依赖关系的说明.....
举例 /etc/rc.d/dhclient
# PROVIDE: dhclient
# REQUIRE: network mountcritlocal
In this case, dhclient requires the services ` network ' (to configure basic network services) and ` mountcritlocal ' (to mount critical file-systems required for early in the boot sequence, usually /var ), and provides the service ` dhclient ' (which happens to be depended upon by the placeholder script /etc/rc.d/NETWORK ).
It is possible to tag a script with a keyword which can be used to conditionally include or exclude the script from being returned by rcorder in the result. /etc/rc uses this to exclude scripts that have a ` nostart ' keyword, and /etc/rc.shutdown uses this to only include scripts that have a ` shutdown ' keyword. For example, as xdm needs to be shut down cleanly on some platforms, /etc/rc.d/xdm contains:
# KEYWORD: shutdown
The rcorder dependency mechanism enables third-party scripts to be installed into /etc/rc.d and therefore added into the dependency tree at the appropriate start-up point without difficulty.
5 Future Work
I'd like to implement functionality to allow you to start up (or shut down) services from service A to service B . This would allow you to start in single user mode, and then start up enough to get the network running, or start all services until just before `multi user login', or just those between `network running' to `database start', etc.
This could be a fairly simple system, and would provide most of the functionality that most people seem to want run states for.
I encourage other systems that are still using a monolithic /etc/rc and who would like to resolve some of the similar issues NetBSD had, to consider this work. I would like to liaise with the maintainers of those systems to ensure as much code re-use as possible.
6 结论
NetBSD 1.5 has a start-up system which implements useful functionality such the ability to control the dependency ordering of services at system boot and manipulate individual services, as well as retaining useful features of previous releases such as /etc/rc.conf .
This work was extremely contentious and difficult to implement because of this contentious nature. The implementation phase did provide valuable insight into some of the difficulties involved in the design and development of large open source projects.
I the long run I believe that this work will have benefits for a majority of users, both in day-to-day operation of the system as well as during future upgrades from NetBSD 1.5.
Availability
This work first appeared in NetBSD 1.5, which was released in December, 2000 [7]. The CVSweb interface [6] can be used to browse the work and its CVS history.
Acknowledgements
Many people contributed to the discussions and design of the current system.
However, some people in particular provided some of the important elements: Matthew Green for finishing rcorder and providing the initial attempt at splitting /etc/rc into /etc/rc.d , and Perry Metzger for the idea of providing dependencies using a `PROVIDE' and `REQUIRE' mechanism, and for the initial rcorder implementation.
References
1. M. K. McKusick, K. Bostic, M. J. Karels, & J. S. Quarterman, The Design and Implementation of the 4.4BSD Operating System , Addison-Wesley, Reading, MA, 1996.
2. M. K. McKusick, K. Bostic, M. J. Karels, & S. J. Leffler, "Installing and Operating 4.4BSD UNIX", in 4.4BSD System Managers Manual , pp. 1:44-53, O'Reilly & Associates, Sebastopol, CA, 1994.
3. Sun Microsystems, System Administration Guide, Volume I , Sun Microsystems, Palo Alto, CA, 1998.
4. Sun Microsystems, "init(1M)", in man Page(1M) System Administration Commands , Sun Microsystems, Palo Alto, CA, 1998.
5. Robert Elz, in email to
tech-userlevel@netbsd.org:
http://mail-index.netbsd.org/tech-userlevel/
2000/03/17/0010.html
6. The NetBSD Project, "CVS Repository",
http://cvsweb.netbsd.org/
7. The NetBSD Project, "Information about NetBSD 1.5",
http://www.netbsd.org/Releases/formal-1.5/
------------------
tsgelib 20050124 v0.1