Linux Installation

Overview

Here we need to install our custom linux distribution, and configure it for actual use. A broad outline is as follows.

Phase 1

Phase 2

NOTE: In the above outline, you should have noticed that we need to generate a lot of configuration files. To generate these, we start with appropriate template files and replace parts of the file with appropriate values, to generate the actual configuration file. This gsar (Global Search And Replace) utility makes the job creating a wide variety of configuration files very simple.

Identifying the Partitions

First identify all the hard disks, by looking at /dev/ide/hdX/media. This will separate the ide-devices to hard disks and optical drives. Checking for a windows installation is done by checking if there is a hard disk partition, whose type is FAT32 or NTFS and is marked active. Now get a list of all partitions of type Linux Native as well as the Linux swap partition (assume that only one swap partition exists). If there is only one Linux native partition, then it is the root partition, and we dont have any boot and opt partitions. If there are three Linux native partitions, sort them by size and the smallest is boot, followed by root, followed by opt. If there are two linux native partitions, sort them by size and assign them to {boot,root} or {root,opt} depending on whether the size of the small partiion is less then 108MB or not. The only remaining thing to identify is the device where LILO should be installed. If windows has been installed, the correct device to install LILO is the device where the windows partition exists. Otherwise, we install LILO on the device where the linux boot partition lives. It is possible that the windows and the linux boot partitions (or root if no linux boot) live on different devices. That does not pose any problem. This completes the first step.

Setting up sshd and mounting the root partition

Setting up sshd amounts to downloading the publickey of the user who is going to connect to this machine from the rdist server. We put this publickey on a webserver, and download this file and drop it into /.ssh/authorizedkeys (in our case the user in question is root). This allows root to ssh into the new machine without a password, but does not allow root to ssh out of this machine without a password. Then we mount the partition identified in the previous step as the root partition at /target. Then we store all the configuration information from the hard disk preparation stage to /tmp, since the gui-disting this machine, will delete this file from the hard disk.

Register this machine to be gui-disted

This is accomplished by trying to access a specific URL, and providing the URL with the client's current IP address (obtained through dhcp). More specifically all we do is to run wget HOSTNAME/SCRIPTNAME/subnet/SUBNET/ip/IP, where the words in CAPITAL letters are replaced by their actual values. The webserver is setup so that, accessing this URL, will add (SUBNET,IP) to a predefined table in a database. Also, in the table a couple of other fields are initialized. These basically state that the gui-dist has not yet been performed, the ssh keys for the new machine, have not been publicised, the pikt scripts and programs have not been installed....

Initiate gui-dist

For this we login to the rdist server (from another machine), and run the gui-dist script as root. This script downloads the IP addresses of all machines, which have registered themselves to be gui-disted, and rdists all these machines in parallel (actually 5 at a time). Then it runs another script once for each machine.

The second script, updates the guidist database entry for this machine, indicating that the gui-dist is now complete. It then copies over files which contain sensitive information (e.g. root passwd crypt string), or which cannot be simply copied over (files which represent devices) ssh tunelled tar. Once this is done, it registers this new machine with the PIKT master. This registering creates a UID,GID and KEY unique to this new machine. This information is then copied over to /tmp of the client machine. Finally, we initiate phase 2 on each of these machines.

Identifying the CD writers

In the previous phase, we have already identified all the optical drives. We ensure that the kernel we compiled has ide-scsi emulation turned on, and it does not have the ide-cd modules. This ensures that all optical drives are accessed using SCSI emulation, and are visible as /dev/sg{0,1,2,3} (they are also visible at /dev/scd0,/dev/sr0,...). Now run cdrecord dev= /dev/sg0 --prcap, to print the capabilities of the corresponding device. For CDRW's you should see a line saying Does write CDRs, or something to that effect. For SCSI devices, the same cdrecord trick will do the job. This completes this phase.

Importing Configuration options

Importing the configuration options defined during the hard disk preparation stage, is very trivial. Just source the /tmp/lininfo script, i.e. have a . /tmp/lininfo in the script which does the installation. Similarly any additional information provided by gui-dist is located in /tmp/new_config.sh. All that needs to be done is to source this file as well. PIKT related identity information is located in /tmp/piktinfo. So we source this file as well.

Configuring this machine and registering with PIKT

After the gui-dist phase, we still need to setup a lot of configuration files. The most important being /etc/lilo.conf and /etc/fstab. In our system, these files are actually symlinks to /etc/local/lilo.conf and /etc/local/fstab. Setting up these configuration files is simplified by the gsar utility, which creates the required configuration file using a specified template.

The next set of important files are /etc/local/passwd and /etc/local/X11/XF86Config, which determine who can login to this machine and the X Configuration respectively. From the configuration option given during the prep stage, the script copies the right passwd file (it downloads all possible passwd files from the web). Ofcourse these password files do not contain any actual passwords or even their crypt strings. These are present in the /etc/shadow file. The /etc/local/passwd only determines the default shell for users based on their netgroups (and hence whether they are allowed to login ir not). Finally, the /etc/local/X11/XF86Config becomes a symlink to XF86Config-[OPTION], where [OPTION], is the option specified for the Video Card, Monitor combination. Of course, this means that one already has created an XF86Config file for each combination (atleast those which need to be used) of video card and monitor.

All the remaining configuration options are used only by the init scripts. For example, the hostname, ip address, network card module, sound module. To reduce the amount of scripts, which needs to tailor made for the machine, we write init scripts, which read a predetermined configuration file at startup (/etc/local/local.conf) and use information found there. This way, all the init scripts are part of the rdist image, and only the /etc/local/local.conf, file needs to created at install time. As usual, this is created using the gsar utility. A sample local.conf will look like this

#!/bin/sh
	  
START_XDM=yes
HOSTNAME="linhost"
SND_MOD="cmpci"
VIDEO_MOD="nvidia" # Kernel module to help XDriver NET_MOD="bcm4400" # BROADCOM netword card IPADDR=128.135.11.127
and the /etc/init.d/hostname will look like
#!/bin/sh
	  
if [ ! -r /etc/local/local.conf ]; then
    exit 0
fi
	  
. /etc/local/local.conf
	  
if [ -z "$HOSTNAME" ]; then 
   exit 0
fi
	  
echo $HOSTNAME > /etc/hostname
hostname --file /etc/hostname

Completing the client side of the pikt registration, amounts to creating a configuration file, and storing the UID, GID, private key and other information (which does not depend on the specific machine). So as usual, we execute the script left after the server side installation was complete. Now we know the actual values of UID, GID and private key. Using gsar and template configuration file, we finish the client side installation.

Applying the finishing touches

Now that all the required files are in place, we are ready to proceed with the final step of the installation. We first confirm that some important files are readable (if they are symlinks then we chase the symlinks till we get to a regular file). These important files are etc/lilo.conf, boot/vmlinuz, bin/bash, etc/fstab, etc/modules.conf. These files are needed to boot into single user mode. Then we run lilo to install the new master boot record. The lilo.conf file already allows us to boot into Windows, in case we are installing a dual boot machine. Once that it done, we unmount all the file systems on the hard disk (boot,root...) and run an e2fsck on them, to be safe. Then finally, we reboot the system, and boot off the hard disk.

The runonce stuff

Once we boot into the new machine for the first time, we still might need to initialise some things. This is done using a runonce script. Basically, we have a /etc/init.d/runonce script, which gets executed as one of the rc scripts. So the first time the machine is booted, this script runs and does what ever installation it wants. After it is done, it deactiviates itself.

Currently the runonce script, initialises the tripwire and locate database, and imports the public ssh host keys of all the other machines.

Stuff done later

Hourly Cron jobs check gather the ssh keys of the new machines. The same thing with installing pikt scripts and programs. Both these cron jobs, download the list of machines from a URL.

What the heck is gsar?

It is a shell script (actually a function in a shell script), which finds all occurences of %<VARNAME>% in the template file, and replaces it with the value of environment variable $<VARNAME>. In addition if any of these environment variables are empty (or unset), then it deletes the corresponding line from its output. More specifically, it takes two or more arguments, the first one is the template file, second is the output file, creates a temporary file with the required substitutions, and uses the install command to copy the temporary file to its final destination, passing any additional arguments (third,fourth,...) to install.

For example if liloconf.temp contains

root=/dev/%LINROOT%
boot=/dev/%LINBOOTDEV%
map=/boot/map
lba32
	  
image=/boot/vmlinuz
read-only
append="%KER_APPEND%"
label=linux
and the value of the environment variables $LINROOT, $LINBOOT and $KER_APPEND are respectively hda1,hda and unset respectively, then executing gsar liloconf.temp /target/etc/local/lilo.conf -m644 -o0 -g0, will create a /target/etc/local/lilo.conf with mode 644, owner root and group root containing
root=/dev/hda1
boot=/dev/hda
map=/boot/map
lba32
	  
image=/boot/vmlinuz
read-only
label=linux

Note the absence of the append line in the final file.


ganapathy murali krishnan
Last modified: Mon Jan 27 18:15:36 CST 2003