HOWTO eINIT

From Gentoo Linux Wiki

Jump to: navigation, search
This article is part of the HOWTO series.
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

Warning: eINIT is fairly stable now and many people use it including me, still this is beta software, and should be used as such. You may have problems with it, such as random reboots, filesystem corruption, etc. It does cleanly unmount filesystems, and we've not seen a single case of actual filesystem corruption, but don't come crying if it sets your cat on fire. You've been warned.

[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

Note: All the eINIT files to be edited are located in /etc/einit

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.

Note: It does not matter what you put after the < in your module declarations. <foo is the same as <carrot

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.

Note: In the audio group, alsa is the service that restores mixers while kern-alsa is the service that auto-detects kernel modules

[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/

Talk:HOWTO eINIT

[edit] IRC Room

#einit@freenode
Personal tools