% ----------------------------------------------------------------------------
% Minit howto: v0.2.2
% ----------------------------------------------------------------------------
\documentclass[11pt,a4paper]{article}
\usepackage[latin1]{inputenc}    % Ascii-Format dieses Dokuments
\usepackage{longtable}           % lange Tabellen
\usepackage[dvips]{epsfig}
\usepackage{fancyhdr}
\pagestyle{fancy}
%\fancyhf{}                               % bisherige Kopf- und Fusszeilen loeschen
\fancyhead[R]{Nico Schottelius}           % rechter Kopfzeileneintrag
\fancyhead[L]{minit HOWTO}                % linker Kopfzeileneintrag
%\fancyhead[L]{\thepage}      % linker Kopfzeileneintrag
%\fancyfoot[C]{\thepage}                % Fusszeileneintrag (Seitenzahl zentriert)
\renewcommand{\headrulewidth}{0.4pt}  % Strichstaerke unter der Kopfzeile
% ----------------------------------------------------------------------------
\begin{document}
\title{minit-howto v0.2.2}
\date{\today}
\author{Nico Schottelius (nico-linux-minit@schottelius.org)}
% ----------------------------------------------------------------------------
% Title
% ----------------------------------------------------------------------------
\maketitle
% ----------------------------------------------------------------------------
% Inhaltsverzeichnis
% ----------------------------------------------------------------------------
\newpage
\tableofcontents
% ----------------------------------------------------------------------------
\newpage
\section{Preamble}
% ----------------------------------------------------------------------------
\subsection{Disclaimer}
This document is provided without any guarantees, including merchantability or
fitness for a particular use.
The maintainer cannot be responsible if following instructions in this document
leads to any damage (including equipment or data, angry neighbors, strange habits,
divorce, or any other calamity). This disclaimer is mostly stolen
from the NFS-HOWTO\cite{url_nfs_howto}.
% ----------------------------------------------------------------------------
\subsection{Copying}
Copying is allowed, as long as the content is unmodified.
The original source for this document is \cite{url_this}.
% ----------------------------------------------------------------------------
\subsection{Intended audience}
This document should be read by system administrators,
people who like to speedup their system and everyone else
interested in a new init system. You should have basic knowledge
of a standard GNU/Linux system (mkdir, vi, grub, lilo, ln, cat, echo and
ls are well known to you).
% ----------------------------------------------------------------------------
\subsection{Feedback}
I welcome feedback about how the HOWTO can be improved.
You can contact me at nico-linux-minit@schottelius.org
(You need to reply to a confirmation mail, otherwise your mail
will never reach me).
% ----------------------------------------------------------------------------
% \subsection{Thanks}
% Go to ... for correcting mistakes, spell errors and
% other confusing things.
% ----------------------------------------------------------------------------
\section{Introduction}
% ----------------------------------------------------------------------------
\subsection{What is minit?}
Every UNIX-variant needs a program, which manages the start process,
after the bootloader executed the kernel. Minit\cite{url_minit}
is such a program. This howto explains how minit works and how to use it.
% ----------------------------------------------------------------------------
\subsection{How it works}
For minit, everything is a service, which should either be started
once or respawned. Minit expects its configuration in the
\textbf{/etc/minit} directory.
Minit searches for a file called "`depends"' in the subdirectory
\textbf{default}. This file tells minit what services should be started
by default (in fact it tells minit that the service default
depends on other services, but "`default"' is the directory minit starts
to search in).
A typical \textbf{default/depends} file looks like that:
\begin{quote}
\begin{verbatim}
scice% cat default/depends 
mount
network
local-tuning
local-services
remote-services
getty
\end{verbatim}
\end{quote}
Minit now goes parallel to the directories mount, network, etc.
Those directories can either include "`depends"' files again, or
if no dependency exists, a "'run"' file. Let us have a look into the directory
"'getty"':
\begin{quote}
\begin{verbatim}
scice% ls -l getty/
total 4
drwxr-x---  2 nico nico 43 Dec  9  2003 1
drwxr-x---  2 nico nico 43 Dec  9  2003 2
drwxr-x---  2 nico nico 43 Dec  9  2003 3
drwxr-x---  2 nico nico 43 Dec  9  2003 4
drwxr-x---  2 nico nico 43 Dec  9  2003 5
drwxr-x---  2 nico nico 43 Dec  9  2003 6
drwxr-x---  2 nico nico 43 Dec  9  2003 7
drwxr-x---  2 nico nico 43 Dec  9  2003 8
-rw-r-----  1 nico nico 81 Feb 24  2004 depends
scice% cat getty/depends 
network/hostname
getty/1
getty/2
getty/3
getty/4
getty/5
getty/6
getty/7
getty/8
\end{verbatim}
\end{quote}
So getty itself depends on other services (which can depend
on other services, too).
The directory "`getty/1"' has no dependencies,
but the three files "`param"', "`respawn"' and "'run"':
\begin{quote}
\begin{verbatim}
scice% ls -l getty/1
total 4
-rw-r-----  1 nico nico 20 Dec  9  2003 params
-rw-r-----  1 nico nico  0 Dec  9  2003 respawn
lrwxrwxrwx  1 nico nico 12 Aug 25 08:08 run -> /sbin/fgetty
scice% cat getty/1/params 
/dev/vc/1
--noclear
\end{verbatim}
\end{quote}
\textbf{run} is the program minit should run, when starting this service.
\textbf{params} contains the paramaters passed to the program. One parameter on
each line. And the existence of the zero-sized file
\textbf{respawn} tells minit to restart the service when it exits.
% ----------------------------------------------------------------------------
\subsection{Using standards}
Minit is not LSB-conform\cite{url_lsb}, nor does it won't to be.
Minit uses the standard Un*x-Filesystem features like links, directories
and files. We can describe it as a complete new init system, throwing away
the problems of traditional init-systems.
% ----------------------------------------------------------------------------
\section{Installing}
\subsection{Download and build}
Either download the source package from \cite{url_minit} or use
CVS. Attention: If you use CVS, \textbf{/sbin/shutdown} will be overwritten.
That means if you call "`reboot"', "`halt"' or "'shutdown"' after installing
minit, they call the shutdown from minit.
Please do a backup of it before (\verb=cp /sbin/shutdown /sbin/shutdown.sysvinit=),
so you willl be able to reboot and halt with /sbin/shutdown.sysvinit.
We will use the CVS version: \verb=cvs -d :pserver:cvs@cvs.fefe.de:/cvs co minit=.
If you don't have dietlibc\cite{url_dietlibc} installed, 
you need to unset the variable "`DIET"'. You can either comment
it out in the Makefile (edit the Makefile and replace "`DIET=diet"'
with "`\#DIET=diet"') or simply prefixing it to make:
\begin{quote}
\begin{verbatim}
# build process for systems with dietlibc
scice% make

# build process for systems without dietlibc
scice% DIET="" make
\end{verbatim}
\end{quote}
After that simple type \verb=make= and wait some time. Then
install minit (as root) with \verb= make install =.
Now minit is installed and created the directory \textbf{/etc/minit}
with two FIFOs:
\begin{quote}
\begin{verbatim}
# your new /etc/minit dir
scice# ls -l /etc/minit
total 0
prw-------  1 root root 0 Aug 25 11:48 in
prw-------  1 root root 0 Aug 25 11:48 out
\end{verbatim}
\end{quote}
% ----------------------------------------------------------------------------
\subsection{Creating basic directories}
% ----------------------------------------------------------------------------
Now we need to create the services minit should manage.
First of all we change to the directory 
\textbf{/etc/minit} and create the directory \textbf{default}
(\verb=cd /etc/minit; mkdir default=). Then we add the service
getty to the standard startup (\verb=echo getty >> default/depends=).
Dependencies are always relative to the \textbf{/etc/minit} directory.
Now we create the service getty, which allows us to login to our
system. First we create the directory \textbf{getty} (below \textbf{/etc/minit})
(\verb=mkdir getty=), then we add the link to our getty and specify
the parameters. There are different steps for different gettys and
systems with and without devfs\cite{url_devfs}.
The example below uses devfs, if you don't use it, replace
"`vc/..."' with "`tty..."' (vc/1 becomes tty1).
\begin{quote}
\begin{verbatim}
# agetty (Debian uses it as /sbin/getty)
scice# ln -s /sbin/getty getty/run
scice# echo 38400 > getty/params 
scice# echo vc/1 >> getty/params 

# fgetty and mingetty
scice# ln -s /sbin/fgetty getty/run
scice# echo /dev/vc/1 > getty/params
scice# echo --noclear >> getty/params

# every getty needs to restart
scice# touch getty/respawn
\end{verbatim}
\end{quote}
You can also use the mini-script\cite{url_mini_create} to create those basic
entries. After you finished, you have to adjust your bootloader
to use minit: With LILO you add \textbf{append="init=/sbin/minit"} to
\textbf{/etc/lilo.conf}, with grub you simply add
\textbf{init=/sbin/minit} behind the \verb=kernel= entry.
It is recommened to add a new bootloader entry for use with minit, so
you can easily change back to your previous system.
After that simply reboot with \verb=/sbin/shutdown.sysvinit -r=.
Your system should startup and display a (more or less) normal
login prompt.
% ----------------------------------------------------------------------------
\subsection{Things to do}
Well, now you have a read-only mounted system, without keyboard settings,
without anything like /proc or /sys mounted.
This is just an early version of the minit howto, other parts
are still missing. You can download a copy of my minit
configuration\cite{url_my_minit}.
% ----------------------------------------------------------------------------
\subsection{Integrating Daemons}
Minit tracks the programs it started. If a daemon forks to the background,
minit cannot follow it.
In the minit-suite is a program called "`pidfilehack"' included, which
helps you to start daemons. I will show you how to do that with,
for instance, Openssh\cite{url_openssh}. Instead of linking
\textbf{run} to the program, you link to \textbf{/sbin/pifilehack}.
The \textbf{params} file now contains additional arguments for
\textbf{pidfilehack}: 
\begin{quote}
\begin{verbatim}
scice% ls -l remote-services/sshd/
total 4
-rw-r-----  1 nico nico 54 Dec 31  2003 params
-rw-r-----  1 nico nico  0 Nov 14  2001 respawn
lrwxrwxrwx  1 nico nico 17 Aug 25 08:08 run -> /sbin/pidfilehack
scice% cat remote-services/sshd/params 
remote-services/sshd
/var/run/sshd.pid
/usr/sbin/sshd
\end{verbatim}
\end{quote}
The first paramater of \textbf{pidfilehack} is the servicename
(Ask yourself: In which directory is the service?) and the second the
pid-file of the daemon. The third is the path to the daemon, all
following are parameters to the daemon itself.
% ----------------------------------------------------------------------------
\subsection{Recommended hierarchy}
After some testing you'll notice that some hierachies are
less good than others. I recommened the one found in my minit
configuration\cite{url_my_minit}, as it is extendable
and also well sorted:
\setlongtables
\begin{longtable}{|l|l|}
\caption{Recommened hierarchy}\\
\hline
ctraltdel   & ctr-alt-del service\\
\hline
default     & default startup service (required)\\
\hline
getty       & contains all gettys:\\
            & scice\% ls getty\\
            & 1  2  3  4  5  6  7  8  depends\\
            & scice\% ls getty/1\\
            & params respawn run\\
\hline
halt & service called when shutting down\\
\hline
in & minit-in-fifo (required)\\
\hline
kbreq & keyboard request service\\
\hline
local-services & Services only locally reachable:\\
               & For instance your local MTA\\
               & (qmail without tcpserver) or \\
               & mouse driver (gpm).\\
\hline
local-tuning   & Cleanups, driver loading, system tuning\\
               & loading keyboard driver (dvorak, qwertz, etc.)\\
               & permissions configuration, kernel settings, ...\\
\hline
local-untuning & saving kernel settings (like sound settings at halt/reboot)\\
\hline
mount          & mount root read/write, mount other (encrypted) devices\\
\hline
network        & startup networking\\
\hline
out            & minit-out-fifo (required)\\
\hline
reboot         & reboot service \\
\hline
remote-services & web-servers, dns-servers, ssh-server, etc.\\
\hline
\end{longtable}
% ----------------------------------------------------------------------------
\section{Internals}
% ----------------------------------------------------------------------------
\subsection{Special directories}
% ----------------------------------------------------------------------------
\subsubsection{/etc/minit}
This is the base directory. Everything else is below this
directory.
% ----------------------------------------------------------------------------
\subsubsection{ctraltdel}
What should be done if \textbf{ctr+alt+del} is pressed?
If this directory does not exist, nothing will happen
when you press ctr+alt+del.
% ----------------------------------------------------------------------------
\subsubsection{kbreq}
What to do when \textbf{alt+uparrow} is pressed.
If this directory does not exist, nothing will happen when
pressing the "`keyboard request"' (Alt+UP-Arrow under x86).
% ----------------------------------------------------------------------------
\subsubsection{default}
The services minit starts when booting the system.
If this directory does not exist, nothing will happen at
system startup. Quite bad.
% ----------------------------------------------------------------------------
\subsubsection{halt}
The services minit kills (newer versions of minit will
also be able to start services) when halting the system.
If this directory does not exist, nothing will happen when
halting the system.
% ----------------------------------------------------------------------------
\subsubsection{reboot}
The services minit kills (newer versions of minit will
also be able to start services) when halting the system.
If this directory does not exist, nothing will happen at reboot.
% ----------------------------------------------------------------------------
\subsubsection{log}
If this directory exists [within another service directory],
 it is taken as service and minit creates
a pipe between stdout of this service and stdin of the log service.
If the log service can not be started, this service will block if it
writes to stdout. File descriptors will be reused, i.e. if the log
process dies and is restarted, no log entries will be lost and there
will be no SIGPIPE\footnote{The log section was written by
Fridtjof Busse, \cite{url_fridtjof}.}.
% ----------------------------------------------------------------------------
\subsection{Special files}
% ----------------------------------------------------------------------------
\subsubsection{in and out}
% ----------------------------------------------------------------------------
\textbf{in} and \textbf{out} are the FIFOs minit communicates
with its helper programs.
% ----------------------------------------------------------------------------
\subsubsection{depends}
Contains the depenencies of the service relative to the \textbf{/etc/minit}
directory.
% ----------------------------------------------------------------------------
\subsubsection{run}
The run file is either a link or an executable, which is run, when
the service it is in is started.
% ----------------------------------------------------------------------------
\subsubsection{params}
The paramaters to pass to the program which is run. One
parameter on one line.
% ----------------------------------------------------------------------------
\subsubsection{respawn}
If existent, restarts the service when it exits.
% ----------------------------------------------------------------------------
\subsubsection{sync}
All other services have to wait for this one. Useful
for mounting.
% ----------------------------------------------------------------------------
\subsection{Other directories and files}
If not used in any depends file, other directories and files
are silently ignored. This allows us to add distribution specific
or own files like READMEs to the service directories.
% ----------------------------------------------------------------------------
\section{Other init systems}
There are many other init systems out there
(including runit\cite{url_runit}, need-scheme\cite{url_need}). The two best known
are "`Sys-V-Init"' and the "`BSD-init"', which are also described
here for reference.
% ----------------------------------------------------------------------------
\subsection{Sys-V-Init}
Sys-V-Init\cite{url_sysvinit} is the traditional init system under Linux.
It has the central configuration file \textbf{/etc/inittab}.
Sys-V-Init distinguishs between different system status, the
so called "`runlevels"':
% ----------------------------------------------------------------------------
\begin{longtable}{|c|c|}
\caption{Sys-V-Init runlevels}\\
\hline
\textbf{Runlevel} & \textbf{Description}\\
\hline
\textbf{0} & \textbf{halt}: This level is called when shutting down the system.\\
\hline
\textbf{1} & \textbf{single-user}: This level is used for emergency repairing.\\
& Only one local user can work with the system\\
\hline
\textbf{2-5} & \textbf{multiuser}: Each UNIX, each Linux distribution
has different settings:\\
& Some use runlevel 2 as normal runlevel, some use runlevel 2\\
& for normal operating, but without the graphical environment.\\
\hline
\textbf{6} & \textbf{reboot}: This level is called when rebooting the system.\\
\hline
\end{longtable}
% ----------------------------------------------------------------------------
At bootup, init calls the system initialization script
(\textbf{etc/init.d/rcS} for instance).
When entering a new runlevel (at system boot the runlevel
is undefined, sometimes described with "`N'"), Sys-V-Init executes a
master script (\textbf{/etc/init.d/rc} for instance).
This script begins to start all \textbf{start-scripts} for this runlevel
and before to execute all \textbf{stop-scripts} from the previous runlevel.
Those scripts are found either in \textbf{/etc/init.d},
\textbf{/etc/rc.d} or \textbf{/sbin/init.d}. Each runlevel
has a directory (like \textbf{/etc/rc2.d},  \textbf{/etc/rc6.d}, ...).
Those directories contain links to the real scripts. Sys-V-Init
detects whether to stop or to start a script by its name:
Start-scripts begin with a "`\textbf{S}"' at the beginning,
stop-scripts with a "`\textbf{K}"' (K as in "`kill"').
When starting the start-scripts, they are called with "`start"'
as the first and only parameter. When starting stop-scripts, they
are called with "`stop"' as first parameter. This is how a 
configuration for runlevel 2 could look like:
\begin{quote}
\begin{verbatim}
scice% ls -l /etc/rc2.d 
total 0
lrwxr-xr-x  1 root root 18 Feb 20  2004 S10sysklogd -> ../init.d/sysklogd
lrwxr-xr-x  1 root root 15 Feb 20  2004 S11klogd -> ../init.d/klogd
lrwxr-xr-x  1 root root 13 Feb 20  2004 S14ppp -> ../init.d/ppp
lrwxrwxrwx  1 root root 15 Feb 24  2004 S15bind9 -> ../init.d/bind9
lrwxrwxrwx  1 root root 18 Feb 20  2004 S18quotarpc -> ../init.d/quotarpc
[...]
scice% ls -l /etc/rc6.d 
lrwxrwxrwx  1 root root 15 Aug 31 16:22 /etc/rc6.d/K19aumix -> ../init.d/aumix
lrwxrwxrwx  1 root root 15 Apr 19 09:55 /etc/rc6.d/K19samba -> ../init.d/samba
lrwxrwxrwx  1 root root 13 Feb 25  2004 /etc/rc6.d/K20gpm -> ../init.d/gpm
[...]
\end{verbatim}
\end{quote}
The number behind the S or the K is the priority. The lower the priority, the
earlier the script is started. That way one can make orders what to start or
stop. Each service has an own init-script, which sometimes
also accepts "`restart"' or "`reload"' instead of "`start"' or "`stop"'.
% ----------------------------------------------------------------------------
\subsection{BSD-Init}
Today there exists more than one "`BSD-init"'. This section
describes the "`traditional"' BSD-Init, which is also implemented
by OpenBSD\cite{url_openbsd}.
At booting up \textbf{/etc/rc}, the master script, is called.
The configuration is read from the master configuration file
\textbf{/etc/rc.conf} (and also additional ones like
\textbf{rc.conf.local}, \textbf{rc.local}, \textbf{rc.securelevel} and
at shutdown \textbf{rc.shutdown}).
As there is a very small number of scripts called,
the boot process is finished quite fast, although there is no parallel 
execution. However, if a new package needs to install itself into the boot
process, it needs to \textit{edit} one of the existing files. This
is very dangerous: If the package installer makes a small mistake, the
whole startup process will fail.
% ----------------------------------------------------------------------------
\appendix
\begin{thebibliography}{666}
\bibitem{url_nfs_howto}
NFS-HOWTO;
http://www.tldp.org/HOWTO/NFS-HOWTO/index.html
\bibitem{url_this}
This document;
http://nico.schotteli.us/papers/linux/howto/minit-howto/
\bibitem{url_minit} Minit; http://www.fefe.de/minit/
\bibitem{url_lsb} LSB; http://www.linuxbase.org
\bibitem{url_devfs} Devfs;
 http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html
\bibitem{url_dietlibc}
Dietlibc; 
http://www.fefe.de/dietlibc/
\bibitem{url_mini_create}
Create-Mini-Minit entry;
http://nico.schotteli.us/papers/linux/howto/minit-howto/create-mini-minit.sh
\bibitem{url_my_minit}
My minit configuration; 
http://nico.schotteli.us/papers/linux/howto/minit-howto/minit-clinux-0.0.5.tar.bz2
\bibitem{url_openssh}
OpenSSH;
http://www.openssh.org
\bibitem{url_fridtjof} Fridtjof Busse; http://www.fbunet.de/minit.shtml
\bibitem{url_runit} runit; http://smarden.org/runit/
\bibitem{url_need} Linux Boot Scripts; Richard Gooch;
http://www.atnf.csiro.au/people/rgooch/linux/boot-scripts/
\bibitem{url_sysvinit} Sys-V-Init; ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/
\bibitem{url_openbsd} OpenBSD; http://openbsd.org
\end{thebibliography}
\end{document}

