HOWTO eINIT
From Gentoo Linux Wiki
| Installation • Kernel & Hardware • Networks • Portage • Software • System • X Server • Gaming • Non-x86 • Emulators • Misc |
Contents |
[edit] Introduction
[edit] What is eINIT?
eINIT is an “Init-System” for Unix operating systems. To figure out what this means, I’ll explain some things about how unices boot, and we’ll use Linux on an x86 as an example. Whenever you turn on your computer, the following happens:
- The CPU loads your BIOS
- Your BIOS sets up some devices and loads some bootloader off your HD (or whatever you’re booting from)
- The bootloader loads Linux
- Linux mounts your root-filesystem and executes /sbin/init
- /sbin/init will start up all sorts of services, check and mount filesystems, run your X-Server, etc...
- Upon completion of all this, you can log in.
The /sbin/init part is what eINIT does.
[edit] Really, what is eINIT?
eINIT is an "Init-System" for Unix operating systems. "Init" is the first program to be run by most Unix kernels after the kernel finishes initialisation. Most Unixes these days use a package called "System V Init" for that purpose -- as the name suggests, this system was derived from how things were handled on System V Unix.
On *BSD, the actual initialisation is done by a script located at /sbin/rc, and on Linux, the initialisation is performed using scripts located at /etc/init.d. Both of these "regular" systems have their pros and cons -- BSD's single script approach puts relatively little strain on the system and is rather straightforward, the init.d approach is nice and could allow for parallelisation, but that's hardly ever implemented and the use of a large number of scripts is quite a large overhead.
"eINIT" seeks to fix this overhead by integrating module management into the init system itself and make init.d scripts obsolete, and also to decrease overall boot time by using aggressive paralellisation.
[edit] So why eINIT?
Yes, Good question, Most Linux Distributions put some clone of System-V's init in place. When this init is run by the kernel, it will read a file called "inittab" which contains information about what runlevel to boot, what scripts to run, etc. That usually results in an /sbin/rc or /etc/rc script to be run, which will in turn try to start a set of scripts. Then, upon completion of the rc-program, init will set up a set of ttys so that you can log-in and begin working.
All of this works great and tends to be very stable, but it has some drawbacks (even though most of these might be irrelevant on fast machines):
- Most rc-scripts don't handle dependencies: You have to list all the scripts that have to be started in the order they need to be started.
- Usually /etc/rc (or /sbin/rc) is a shell-script, and so are most of the things it starts directly: It takes time for your shell to parse these scripts. It's really not much time that is required, but this is done every single time your computer boots, which can be very bad for embedded devices that need to be up ASAP.
- Some things just can't be done (easily|efficiently) in a shell-script: Dependency-calculations tend to be slow (which is probably why there aren't many rc-scripts that do this) and parallel bootup is tricky.
- None of these scripts (or maybe programs) stay in memory, thus they can't store status information in RAM, so they often have to write things like PIDs and whether or not a service has already been started in files on your harddisk. This is slow, so sometimes people go ahead and put the part of their filesystem that contains such status information on a RAM-disk. Obviously, both of these methods have more overhead than simply storing a 2-byte PID and a flag that says "running" in-memory, and every single byte could count on an embedded device with limited resources.
- Often you will find many init-scripts that only start or stop a daemon that all look pretty much the same. Having more than one script like this is... well, redundant.
- It's hard to modify the "feedback" you get. To modify that, you would normally have to modify the main rc-script and maybe some other utility-script, maybe download a different version that gives you graphical feedback instead of textual one. It gets even more tricky when you have to rely on aural output, maybe because you're blind...
- You will hardly find an init/rc combination that allows for "backup-services", as in "should named fail to start, try to get dnsmaq up". Unless, of course, you craft a special script for that.
- You just can't have scripts that make sure a daemon keeps running, as in, one that resurrects a daemon should it be killed or die because it's buggy. You could, of course, write a daemon to do this for you...
eINIT tries to address all these problems.
[edit] Installation
[edit] Using the Official eINIT overlay
[edit] Portage
The easiest way to use the official eINIT portage overlay is with layman.
Just
emerge layman layman -f layman -a einit
You might also need to modify make.conf to use layman's overlays, instructions should be given when you emerge layman.
echo "sys-apps/einit" >> /etc/portage/package.keywords echo "sys-apps/einit-modules-xml" >> /etc/portage/package.keywords emerge einit einit-modules-xml -av
[edit] Paludis
Paludis users can follow the following instructions. Paludis, a portage replacement, will use a repository configuration file similar to this one:
| File: /etc/paludis/repositories/einit.conf |
location = /var/paludis/repositories/einit format = ebuild sync = git://git.jyujin.de/einit/portage-overlay.git master_repository = gentoo names_cache = /var/cache/paludis/names write_cache = /var/cache/paludis/metadata |
- mkdir -p /var/paludis/repositories/einit/.cache
- paludis -s x-einit
- add “sys-apps/einit ” to /etc/paludis/keywords.conf
- paludis -i einit
[edit] Configuring the Bootloader
To use eINIT, you will have to modify your bootloader configuration.
Be warned: If you get this wrong, your system may no longer boot.
When you create the new entry, to boot using eINIT, leave the old entry (booting using sysvinit) in the configuration file: eINIT is still in beta, and maybe somewhat unstable for you. If you can't boot, you will want to be able to boot using sysvinit, so you can change the eINIT configuration.
[edit] LILO
If you are using Lilo as your bootloader, you will need to create a new entry in /etc/lilo.conf. Open the file in a text editor, copy your existing entry (giving it a new name), and add the following line:
append = "init=/sbin/einit"
For example:
| File: /etc/lilo.conf |
# Working image = /boot/kernel-2.6.11-gentoo-r9 root = /dev/hda2 label = Gentoo-2.6.11-r9 read-only # eINIT image = /boot/kernel-2.6.11-gentoo-r9 root = /dev/hda2 label = Gentoo-2.6.11-r9-eINIT append = "init=/sbin/einit" read-only |
[edit] GRUB
If you are using GRUB as your bootloader, you will need to create a new entry in /boot/grub/grub.conf. You may need to mount /boot first. Open the file in a text editor, copy your existing entry (giving it a new name), and add the following to the end of the "kernel" line:
init=/sbin/einit
For example:
| File: /boot/grub/grub.conf |
hiddenmenu timeout 5 default 0 fallback 1 splashimage=(hd0,0)/grub/splash.xpm.gz # Working title GNU/Linux 2.6.11-gentoo-r9 root (hd0,0) kernel /kernel-2.6.11-gentoo-r9 root=/dev/hda2 # eINIT title GNU/Linux 2.6.11-gentoo-r9 (eINIT) root (hd0,0) kernel /kernel-2.6.11-gentoo-r9 root=/dev/hda2 init=/sbin/einit |
[edit] Configuring eINIT
[edit] Basic Info
At this point there is no CLI, TUI or GUI to configure eINIT. So you need to manually edit the configuration XML files.
XML files aren't that hard once you get the hang of it though. And, of course, if you create a configuration tool yourself, feel free to tell the authors and they'll likely include it in the upstream release or provide links to it.
[edit] Files to edit
The very first thing we need to do is get a list of services einit currently supports.
einit -p -ls /services/all > ~/einitservices
We now have to figure out exactly what rc-scripts are loaded on startup.
rc-config show boot >> ~/rcservices rc-config show default >> ~/rcservices
[edit] local.xml
First we need to edit:
/etc/einit/local.xml
This file is an overlay for /lib/einit/einit.xml. Settings you change here override what is in that file. The first thing we are going to do is set our timezone. You can find your previous setting in /etc/conf.d/clock
<system> <timezone s="America/New_York"/> </system>
Next we are going to configure the kernel modules that need to be automatically loaded at boot. Take a look at /etc/modules.autoload.d/kernel-2.6 to see what is currently loading at startup. The actual module declarations can be done in different ways.
You can have one tag that lists all of the modules you need to load:
<kernelmodules s="nvidia:e1000:iwl4965:uvcvideo" />
Or you can have multiple lines that group your modules:
<nvidia s="nvidia" /> <network s="e1000:iwl4965" /> <webcam s="uvcvideo" />
So the end result with method one is this:
<kernel> <modules> <kernelmodules s="nvidia:e1000:iwl4965:uvcvideo" /> </modules> </kernel>
And the end result with method two is this:
<kernel> <modules> <nvidia s="nvidia" /> <network s="e1000:iwl4965" /> <webcam s="uvcvideo" /> </modules> </kernel>
Both methods are equivalent in function.
Now we will define some service groups. Service groups are useful because they allow you to group together services that einit provides into one need little group. To find your services, look in the ~/einitservices file we created earlier. Those exact names can be used in the service groups. Here is an example:
<alias> <audio group="alsa:kern-alsa" seq="all" /> <bluetooth group="bluetooth-hci:bluetooth-sdp:bluetooth-rfcomm" seq="all" /> </alias>
As you can see, the name of the service group is the first thing after the <. This is what you will later put into modes.xml. After that is the group= attribute. Inside the "" are the services that belong to that group separated by a :. The last attribute, seq, indicates that all services in the group should be started when that group is started.
[edit] modes.xml
The runlevels, their actions and the services in them are defined in the file:
/etc/einit/modes.xml
To add a service to a runlevel, edit modes.xml. For example:
<mode id="default" base="boot"> <enable services="network:ntp-client:audio:dbus:hal:displaymanager:mount-remote:ipc-dbus" /> <overrides> <ttys s="tty1-regular:tty2-regular:tty3-regular:tty4-regular:tty5-regular:tty6-regular" /> </overrides> </mode>
This is the default runlevel. The boot runlevel is the <mode> without an id=.
To add a service, find the service that you wish to add in the ~/einitservices and add it to the services attribute, separating services with a :.
For example if you want to add acpid the line
<enable services="network:ntp-client:audio:dbus:hal:displaymanager:mount-remote:ipc-dbus:bluetooth" />
should become
<enable services="network:ntp-client:acpid:audio:dbus:hal:displaymanager:mount-remote:ipc-dbus:bluetooth" />
Notice how the audio group is used as a service here. The audio group will launch all services that are defined in the local.xml file for that group. The same is true of bluetooth. The displaymanager is optional. You can also explicitly define your display manager by adding it as a service with a v- in front. For example, kdm would be v-kdm:
<enable services="network:ntp-client:audio:dbus:hal:displaymanager:mount-remote:ipc-dbus:bluetooth:v-kdm" />
You are going to want to add all services found in ~/rcservices to the appropriate runlevel in modes.xml. einit does the filesystem checking for you, so you don't need to worry about localmount, checkfs, checkroot, etc.
If you add local to your default runlevel, you are going to need to either copy /etc/conf.d/local.* over to /etc/einit/conf.d or symlink them. I recommend symlinking them so that way both sysv and einit can see all changes made to the files.
ln -s /etc/conf.d/local.* /etc/einit/conf.d/
[edit] network.xml
The network configuration is done through the file
/etc/einit/network.xml
Please see this article on how to properly configure advanced networking
[edit] Service Configuration
The configurable services have the configuration files in:
/etc/einit/conf.d
The XML files here are just like the config files in /etc/conf.d/
[edit] fstab.xml
einit can use either /etc/fstab or /etc/einit/fstab.xml for mounting your drives. The file itself is commented on its usage. Most people will want to leave this file alone and allow einit to use /etc/fstab.
[edit] Check configuration
Now that we have finished configuring einit, we need to run one more command to ensure that we have not made an error.
einit --wtf
This command will check our configuration files and tell us where problems in the configuration files occur. If a problem is reported, go back and fix it and then recheck for errors. Do so until einit --wtf reports no problems are found.
You can go ahead and delete ~/einitservices and ~/rcservices.
[edit] Usage
All einit services are enabled and disabled via the einit program. To initialize a service:
einit -e <service>
To stop a service that is already loaded:
einit -d <service>
You can also enable and disable einit modules on the the fly.
einit -em <module>
will enable a module while
einit -dm <module>
will disable a module.
Type
einit --help
for all options.
[edit] Logging
During Boot and shutdown eINIT logs the info to /var/log/einit.log while logging daemon is not up when it is up it will push the logs to the logging Daemon.
[edit] Help
Help is available at the eINIT forum and the irc channel.
[edit] Usefull links
Website: http://www.einit.org/
Forum: http://www.einit.org/forum/
[edit] IRC Room
#einit@freenode
