Subject: Re: PROPOSAL: /etc/rc, /etc/init.d/*, ...
To: None <tech-userlevel@netbsd.org>
From: Wilfredo Sanchez <wsanchez@apple.com>
List: tech-userlevel
Date: 12/01/1999 18:42:58
This is just FYI-

  I've been working on a new startup scheme in Darwin/Mac OS X, and  
have run into some similar problems.  This may not be interesting to  
you, but it might be, so I thought I'd tell you what I've done in
case it's useful.

  Our old system was a series of scripts in /etc/startup.  /etc/rc
would call each in order (filenames were 0100_LocalMounts,
0200_Devices, etc).  Some of my goals:

- Want the ability to drop in a new script without having to give it  
a number, since we could renumber the scripts between system
releases, and this is therefore fragile.

- Want to be able to launch the window system very early so we can
show boot progress graphically (eg. a progress bar), as well as
optionally booting in verbose Unix-style.

- Need to be able to extend it eventually to load in application
libraries, so we can put up a dialog and ask users for input about
something (eg. another machine is using your IP address.  Start
without network? Pick a new address? etc.)

- Have start/stop functionality in each script.

  I've only met some of these goals so far, but the current scheme
uses a program called SystemStarter, which is currently launched by  
/etc/rc, though it will probably eventually replace /etc/rc.

  "Startup Items" are directories in /System/Library/StartupItems
(in BSD that would probably be /etc/startup).  Each directory
contains a program (currently all are scripts, but could be a
binary), a config file, and any resources needed by the program.
SystemStarter runs each script in an order that is affected by the
config files.

  Below are my notes on how that works.  You can get the source code  
from the Darwin read-only CVS server.  See
http://www.publicsource.apple.com/tools/cvs/ for info on that.  The  
module name is "Startup".  Note that is uses the Apple's
CoreFoundation (CF) library for C objects like strings and whatnot,  
so you won't be able to build it on BSD, but you can see what it
does.  It's not much code.

	-Fred


Logistics of Startup Items:

  Startup items are directory bundles which contain, at a minimum,
an excecutable file and a property list text file.  For a startup
item named "Foo", the bundle will be a directory named "Foo"
containing (at a minimum) an executable "Foo" and a plist file
"StartupParameters.plist".

Item Launch Ordering:

  The plist file contains parameters which tell SystemStarter some
information about the executable, such as what services is provides,  
which services are prerequisites to its use, and so on. The plist
contains the following attributes:

	{
	  Description     = "blah blah";
	  Provides        = ("service", ...);
	  Requires        = ("service", ...);
	  Uses            = ("service", ...);
	  OrderPreference = "time";
	  Messages =
	  {
	    start = "Starting blah.";
	    stop  = "Stoping blah.";
	  }
	}

  Note that while the above example is writting in the old
NeXT-style property list format for compactness, the new XML property  
lists are also handled.  You may prefer using PropertyListEditor.app  
to editing the property list files manually.

  Provides is an array that declares the services are provided by
this bundle.  A typical bundle provides a single service.  Two
bundles may not provide the same service; should multiple bundles
which provide the same service be installed on a system, the first
one encountered will be run, while the others will be disabled.  It  
is therefore undesireable to provide multiple services in a single
bundle unless they are codependant, as the overriding of one will
effectively override all services in a given bundle (see also "Search  
Paths for Startup Items").

  Requires and Uses comprise the primary method for sorting bundles  
into the startup order.  Requires is an array of services, provided  
by other bundles, that must be successfully started before the bundle  
can be run.  If no such service is provided by any other bundle, the  
requiring bundle will not run.  Uses is similar to Requires in that  
the bundle will attempt wait for the listed services before running,  
but it will still launch even if no such service can be provided by  
another bundle.

  OrderPreference provides a hint as to the ordering used when a set  
of bundles are all ready to load.  Bundles which have their
prerequisites met (that is, all Requires services are launched and
all Uses services are either launched or deemed unavailable) are
prioritized in this order, based on OrderPreference:

	First
	Early
	None (default)
	Late
	Last

  Note that other than the above ordering rules, there are no
guarantees about the startup order of items.  That is, if multiple
items are prioritized equally given the above contraints, there is no  
rule for while starts first.  In particular, we may be starting
multiple items in parallel at some point, and this will change the
ordering behaviour for equal-priority items.  You must use the above  
mechanism to ensure the correct dependancies have been met.

  Description is a general-use string describing the item, for use
by Admin tools.  The Messages property provides strings which are
displayed by SystemStarter during startup and shutdown.

Search Paths for Startup Items:

  Startup items may be placed in the "Library" subdirectory of the
primary file domains ("System", "Local", and "Network").  The search  
order is defined by routines defined in NSSystemDirectories.h: Local,  
then Network, then System.  However, because the Network mounts have  
not been established at the beginning of system startup, bundles in  
/Network is currently not searched; this may be fixed later such that  
/Network is searched when ti becomes available.  This search order
does not define the startup order, but it does effect the handling of  
conflicts between bundles which provide the same services.

Executables and Bundles:

  Presently, SystemStarter looks for an executable file with the
name of the bundle (eg. Foo/Foo), and runs that file with the single  
argument "start" during startup.  The argument "stop" is reserved for  
shutdown time.

  The plan is to also allow for loadable dyld bundles which get
loaded, run, and unloaded by SystemStarter.  This will provide some  
opportunity for SystemStarter to present a UI during startup during  
special events, such as failure conditions (eg. NetInfo isn't
available), and user configuration panels (eg. Location Manager).

Shutdown:

  The intent is to add a shutdown sequence in the future so that the  
computer can be brought down more cleanly.  The mechanism for this
is still in the design stage.


--
       Wilfredo Sanchez, wsanchez@apple.com
Apple Computer, Inc., Core Operating Systems / BSD
          Technical Lead, Darwin Project
   1 Infinite Loop, 302-4K, Cupertino, CA 95014