pinit is a sysvinit alternative. It's a different way of booting linux. Keywords are: xml configuration, fast and parallel booting of services, modular design, dependecy based booting of services. It's intented to be more robust and faster than sysvinit.
Services can be found under the conf/services directory. They are given logical names, according to what they do and what state of the boot they belong. For example:
|net.eth0||Will setup eth0 when booting the network.|
|login.vc2||Will start a login on vc2 when we are in login fase.|
Services are described using xml configuration files. There are 3 different types of services:
Execute a command on startup, execute another command on shutdown.
<command provides="system.swap"> <startup message="Activating swap partitions"> /sbin/swapon -a </startup> <shutdown message="Deactivating swap partitions"> /sbin/swapoff -a </shutdown> <dependecy name="system.checkfs"/> </command>
This command will activate all swap partitions on startup by executing the swapon -a command. On shutdown the swapoff command is used to unmount all swap partitions
They do something on startup and do another thing on shutdown. They do that by calling a start()/stop() function in a module.
<module provides="system.devfs" source="devfs.so"> <dependecy name="system.proc"/> </module>
This module will mount the devfs filesystem on startup using a object file (module). The modules are under conf/modules, sources are in src/modules.
A deamon is started on startup and killed on shutdown. One can specify what signal is needed to kill the daemon. pinit will track the pid of the running daemon, so no need to save that to a file. When a daemon gets killed or dies outside of pinit. It will be restarted. So the daemon will always be available.
<daemon provides="local.log"> <startup> /usr/sbin/metalog </startup> <signal value="15" /> <dependecy name="local.cleanup" /> </daemon>
This will start the metalog daemon. On shutdown it will be killed with signal 15.
For booting some services depend on other services. For example one needs to check the filesystems before mounting them. In pinit dependecies of a service can be specified. Service can "provide" some kind of service, on which other services can depend. If a services depend on more than one service, it will wait until all the services it depends on are initialized. An example of a small dependecy tree is:
<command provides="net"> <startup message="Starting dhcp for eth0..."> /sbin/dhcpcd eth0 </startup> ... </command> <command provides="net"> <startup message="Bringing local network interface up..."> /sbin/ifconfig lo 127.0.0.1 up </startup> ... </command> <command provides="date"> <startup> /usr/bin/ntpdate -b -s ntp0.nl.net </startup> <dependecy name="local.hwclock"/> <dependecy name="net"/> </command>
The date command will wait for the network te be up, and the hardware clock to be initialized before starting to execute.
On startup pinit will build a tree of all services. Services that have no dependecies or services of which all dependecies are resolved will be started. Services that do not depend on each other will boot in parallel.
Profiles are collections services. They describe what services need to be started on boot. Modules can have a per service config file. Meaning that you can have, for example, a profile for "home" and a profile for "work". And the net module will use a static adress for home, and use the dhcp daemon for work.
<profile> <service name="system.hostname"/> <service name="system.devfsd"/> <service name="system.proc"/> <service name="system.devfs"/> <service name="system.checkfs"/> <service name="system.mountroot"/> <service name="system.mtab"/> <service name="system.mountfs"/> <service name="system.swap"/> <service name="system"/> <service name="local.console"/> <service name="local.cleanup"/> <service name="local.hwclock"/> <service name="local.alsa"/> <service name="local.random"/> <service name="local.hdparm"/> <service name="local.metalog"/> <service name="local.modprobe"/> ... </profile>
pinit uses a seperate program to control the init system. pinit manages all your services. And you are able to control the init system using pinitctrl. One can, for example, start and stop services or shutdown the computer. pinitcrtl will communicate over a unix socket to the pinit daemon. Multiple clients are able to connect at once. From the console the following commands are supported:
|start <service>||Start the given service if it's not already started|
|stop <service>||Stop the given service if it's not already stopped|
|status <service>||Return the status of the given service (started/stopped).|
|profile <profile>||Load another profile. All services that are started, but are not in the profile will be stopped. All services that are not running, but are needed for the new profile will be started.|
|shutdown (halt|reboot)||Shutdown the running system and either reboot or halt.|
The pinit daemon will respond to command with either OK or ERROR and a message. Messages from the services will be routed to all listening clients. The boot console is also a client in this model. All it does is receive messages and display them to console. The messages than can be send by services are seperated into the following levels:
|startup||The service will try to startup.|
|shutdown||The service will try to shutdown.|
|error||An error occured in the service.|
|notify||A general informative message.|
Commands do not need to be entered from the pinitctl console, but can also be entered on the command line of pinitctl:
% pinitctl status net.eth0 OK: status=started