LILO distinguishes different configurations (e.g., Windows or Linux) based on labels; each label has some information associated with it, such as a disk partition to boot from. For Linux partitions, there's also information about what file (kernel) to boot and about arguments to pass the kernel.
More than one label can specify the same partition to boot from. In fact, different labels can be identical; I have labels called `linux' and `l' which are otherwise identical, so they're essentially aliases for each other.
However, lately I (and my housemates) have had a need to use my laptop essentially as an X terminal to access another Linux computer (call it zemlya.example.net) on the house net. So when I'm at home, I generally want the laptop on the network, and I'd like it to boot and start X, but I'd like all my clients to run on zemlya. Ideally, I'd like the X server running on the laptop, but xdm (which displays the login window and starts the user's X session) running on zemlya.
Either of these configurations is easy to arrange; for a standalone machine, I want to run xdm on sputnik (which I do out of /etc/inittab; the default RedHat 5.2 inittab runs
/usr/bin/X11/xdm -nodaemonin runlevel 5, so I just edit /etc/inittab to make runlevel 5 the default runlevel. (xdm starts the X server by default when it runs, and if the X server dies, xdm will restart it. Likewise, init, the process that reads inittab, will typically restart xdm itself if it dies.)
To have sputnik run as an X terminal, I can just start the X server and have it query zemlya for xdm service, asking zemlya to display a login window. This can be done (assuming X isn't already running) with the line
/usr/bin/X11/X -query zemlya.example.net
So my situation is that in addition to choosing at boot time between Linux and Windows, I'd like to be able to choose between two different configurations of Linux. One way to do that would be to have two completely independent installations of Linux, and choose between them just as I choose between Linux and Windows, but that would be an inefficient use of disk space (and of my time, since I'd need to install and configure both of them).
# 0 - halt (Do NOT set initdefault to this) # 1 - Single user mode # 2 - Multiuser, without NFS (The same as 3, if you do not have networking) # 3 - Full multiuser mode # 4 - unused # 5 - X11 # 6 - reboot (Do NOT set initdefault to this)So for instance, under RedHat, whether X is running or not depends (by default) on what runlevel the machine is booted too; the same system, identically configured, will boot without X if you tell it to go to runlevel 3, or with X if you tell it to go to runlevel 5.
Warning: Different Linux distributions use the various runlevels for different things. If you're not using RedHat Linux - or even if you're using a different version - you should check what that distribution's conventions are for the runlevels before trying to use them. Also, some distributions use some other mechanism besides runlevels (e.g. an rc.local file) to decide whether to run X at boot time. However, any distribution that supports runlevels, and I think all the major ones do at this point, can be coerced to work like RedHat without too much effort if you need to.
The kernel knows what runlevel to go to based on arguments it is passed when it starts. If you're using LILO to boot, those arguments are passed by LILO. An argument can be passed to the kernel either through LILO's `append=' directive (associated with a label) or by the user on the LILO boot command line, after the label that specifies which configuration (partition, kernel, etc.) to boot from. For instance, if you want to boot into runlevel 3, and the LILO label for your Linux partition is `linux', you can issue
boot: linux 3at LILO's `boot:' prompt.
But you can also associate kernel arguments with a particular label. For instance, if you want to pass the arguments `root=/dev/sda4' to the kernel whenever you boot a particular configuration, you can put
append="root=/dev/sda4"after the appropriate label in your /etc/lilo.conf file.
So at this point I have two ways to choose which runlevel to boot into: I can specify it by hand at LILO's boot prompt, after the label (as `linux 3' or `linux 1', which latter is one of the ways to boot single-user), or I can set up separate labels in my /etc/lilo.conf, at least one of which has an `append=' line to specify a runlevel.
Note in the list of runlevels above that in RedHat, runlevel 4 is `unused' by default. Voilą; I can define a new runlevel 4 that does what I want. That is done in /etc/inittab, which lists processes to be run in each runlevel. (It's read at boot time by init, the special process started by the kernel, which is PID 1.)
Here's my /etc/inittab for the laptop:
The line with the identifier `xt' is new, and defines how my new runlevel 4 is different from the other runlevels; it runs the command `/usr/bin/X11/X -query zemlya.example.net'. (The respawn says that if X dies, init should restart it.)
So with this inittab file, runlevel 4 will cause the machine to act as an X terminal connecting to zemlya (although all the other services are still running, and you can telnet to the machine normally, or switch virtual consoles and type locally), and runlevel 5 is a normal standalone X environment with xdm running locally.
The `timeout=100' line causes LILO to wait ten seconds for me to choose a label to boot; if I don't, the first label is used (so a machine can boot unattended). The `message=/boot/message' line tells LILO to display a message describing the options. For completeness, here's that file: