Sunday, February 8, 2009

MCA 317

Software Testing Notes
I think in many ways the more recent revolution in how software is created comes not from programming languages or code organization but from how testing and quality assurance are accomplished. We learned a decade or so ago how an object-oriented approach helps in producing good software. To go further a testing structure is neccessary.
Many companies only have "black-box" testing done by non-programmers who are part of a "Quality Assurance" or "Quality Engineering" department, which is separated from the department which programmers are in. Their testing consists of using the program as an end-user would, while carefully tracking the results.
There are also various forms of automated "black-box" testing (i.e. external programs which simulate the actions of a user) as well as "white-box" testing which contacts internal pieces of the program not normally accessible to the end user.
Unit Testing
Unit testing is the practice of writing small automated test for the functionality of self-contained units within the code -- generally a single class or small set of classes.
For example, an Enterprise Java Bean which accesses a database might have a unit test which checks to make sure that basic get and put functions work.
JUnit is a set of Java classes that aid in unit testing. However, formal tools are not required. A simple convention is to include a main method for a Java class, which instantiates and tests some simple functionality of that class. Additional information can be found in the following articles:
JUnit Test Infected
Detailed Unit Testing Code Example
Automated Development Tests
A set of tests should be bundled together as a minimum baseline for interim development versions. Ideally, this should be run as a single step after compiling, as a simple make test or ant test command.
This can be as little as a handful of the unit tests discussed above. As a project approaches the point of hand-off to the QA department, the tests should probably be more extensive and establish at least a few of the minimum standards needed for hand-off (as described in the QA guidelines).
Web projects should develop simple automated testing as well for link testing and so forth. General use tools (such as a linkbot) should be made available within the company.
Logging
Logging is a neccessary process for debugging, testing, and maintenance. Like unit tests, log and info messages should be seen as an integral part of the product. They should not be considered as temporary code hacks to be thrown away later.
For any large-scale projects (and many others), logging procedure should be multi-level and runtime-configurable. These mean:
Multi-level means that there should be several distinct modes of logging for different situations, as opposed to simply "on-off". A typical arrangement of levels would be:
"FATAL" designates very severe error events that will presumably lead the application to abort.
"ERROR" designates error events that might still allow the application to continue running.
"WARN" designates potentially harmful situations.
"INFO" designates informational messages that highlight the progress of the application at coarse-grained level.
"DEBUG" designates fine-grained informational events that are most useful to debug an application.
Runtime-configurable means that the level of logging can be changed without altering the code. This can be handled by a variety of means such as command-line options, a configuration file, or environment variables. This feature is vital for debugging and testing of a versioned, stable product.
Logging with these features is a major step over the common practice of the programmer adding in "print" lines and then commenting them out when not needed. The most important change is that the programmer should look at log statements as a permanent part of the program rather than temporary hacks. This greatly aids the debugging process as well as use by external administrators.
These features can be implemented by custom code or by using an existing logging package. For Java, the open-source project log4j is an example of a package which supports these features with minimal impact on processing speed.
Bug Tracking
Once a software product is in the pipeline towards being made public, it frequently goes into a formal process where specific bugs are numbered and tracked. One of the pitfalls of such systems is that they can stifle open communication by being to formalized. In developing a product, the programmers need to keep others informed -- especially in communicating an accurate timeline of when fixes will be complete.
In reality, not all of the intended product requirements are always going to be met. Too often, engineers work under increasing pressure to get requirements completed by the deadline. Desperate to meet all the requirements, they work furiously right up to the deadline, but often what is produced is not their best work. Then, when the product is turned over QA testers, it is full of bugs which cannot be fixed in time for the intended shipping date, thereby resulting in either a missed product launch date or a buggy product.
The lesson is that programmers need to assess as early as possible which goals are realistic. At that point, either the requirements or the goals need to change, and other teams informed of these decisions.
Learn to program at Brooks College, San Jose

MCA 309

Getting Started
1.1 Working in the UNIX Environment
Before you can start using UNIX, your system administrator has to set up a UNIX account for you. Think of this account as your office - it's your place in the UNIX environment. Other users may also be at work on the same system. At many sites, there will be a whole network of UNIX computers. So in addition to knowing your account name, you may also need to know the hostname (name) of the computer that has your account.
Each user communicates with the computer from a terminal or a window. To get into the UNIX environment, you first connect to the UNIX computer. (You may have a terminal that's already connected to the computer.) Next, you start a session by logging in to your UNIX account. Logging in does two things: it identifies which user is in a session, and it tells the computer that you're ready to start working. When you've finished working, you log out - and, if necessary, disconnect from the UNIX computer.
1.1.1 Connecting to the UNIX Computer
If you turn on your terminal and see a message from the UNIX computer that looks something like this:login:
you can probably skip ahead to the section "Logging In" later in this chapter. Otherwise, browse through the next few sections and find the one that applies to you. (We can't cover every user's situation exactly. If none of these suggestions helps you enough, ask another UNIX user or your system administrator.)
1.1.1.1 Connecting from another operating system
If you're using a personal computer to connect to the UNIX system, you'll probably need to start a terminal emulation program. Some common programs are procomm, qmodem, kermit, minicom, and telnet. (There are lots of others.)
If you start the program and get a UNIX "login:" prompt, you're ready to log in. But if your screen stays blank or you get another message that you don't understand, check with another user or your system administrator for help.
1.1.1.2 Connecting with a data switch
Your office may have a data switch, a port contender, or another system that allows you to select which computer you will connect to. Like a telephone switchboard, this connects your terminal to one of a number of computers. Enter your computer's hostname or code number at the prompt - or choose from the menu of hosts.
1.1.2 Logging In
The process of making yourself known to the UNIX computer system and getting to your UNIX account is called logging in. Before you can start work, you must connect your terminal or window to the UNIX computer (see the previous sections). Then log in to UNIX and identify yourself. To log in, enter your username (usually your name or initials) and a private password. The password does not appear on the screen as you enter it.
When you log in successfully, you will get some system messages and finally the UNIX shell prompt (where you can enter UNIX commands). A successful login to the system named nutshell would look something like this:O'Reilly & Associates, Inc.nutshell.oreilly.com: Solaris UNIX version 2.5 login: johnPassword:Last login: Mon Nov 3 14:34:51 EST 1997 from joe_pc ------------- NOTICE TO ALL USERS -----------------The hosts nutshell, mongo and cruncher will be downfor maintenance from 6 to 9 PM tonight.--------------------------------------------------- My opinions may have changed, but not the fact that I am right.Tue Nov 4 12:24:48 EST 1997%
In this example, the system messages include a "fortune" and the date. Although this example doesn't show it, you may be asked for your terminal type, accounting or chargeback information, and so on. The last line to appear is the UNIX shell prompt. When you reach this point, you're logged in to your account and can start using UNIX commands.
Instead of a shell prompt, you may get a menu of choices ("email," "news," and so on). If one of the choices is something like "shell prompt" or "command prompt," select it. Then you'll be able to follow the descriptions and examples in this book.
The messages that appear when you log in differ from system to system and day to day. The shell prompt also differs. The examples in this book use the percentage sign as a prompt (%).
Let's summarize logging in, step by step:
1. If needed, connect your terminal or window to the UNIX system.
2. If you don't have a "login:" prompt, press the [RETURN] key a few times until you see that prompt on the screen.
3. Type in your username in lowercase letters at the prompt. For example, if your login name is "john," type:login: john
Press the [RETURN] key.
The system should prompt you to enter your password. If passwords aren't used on your system, you can skip the next step.
4. If you were assigned a password, type it at the prompt. For security, your password is not displayed as you type it:Password:
Press the [RETURN] key after you finish typing your password.
The system verifies your account name and password, and, if they're correct, logs you in to your account.
1.1.2.1 Problem checklist
Nothing seemed to happen after I logged in.
Wait a minute, since the system may just be slow. If you still don't get anything, ask other users if they're having the same problem.
The system says "login incorrect".
Try logging in again, taking care to enter the correct name and password. Be sure to type your username at the "login:" prompt and your password at the "password:" prompt. Backspacing may not work while entering either of these; if you make a mistake, use [RETURN] to get a new "login:" prompt and try again. Also make sure to use the exact combination of upper- and lowercase letters your password contains.
If you still fail after trying to log in a few more times, check with your system administrator to make sure you're using the right username and password for your account.
All letters are in UPPERCASE and/or have backslashes (\) before them.
You probably entered your username in uppercase letters. Type exit and log in again.
1.1.3 Remote Logins
The computer you log in to may not be the computer you need to use. For instance, you might have a workstation on your desk but need to do some work on the main computer in another building. Or you might be a professor doing research with a computer at another university.
Your UNIX system can probably connect to another computer to let you work as if you were sitting at the other computer. To do this, you first log in to your local computer. Then you start a program on your local computer that connects to the remote computer. Some typical programs are telnet and rlogin (for connecting over a computer network) as well as cu and tip (for connecting through telephone lines using a modem). You use the remote system until you're done; when you log off the remote computer, the remote-login program quits, and then returns you to your local computer.
The syntax for most remote-login programs is:
program-name remote-hostname
For example, if Dr. Nelson wanted to connect to the remote computer named biolab.medu.edu, she'd log in to her local computer (named fuzzy) first. Next, she'd use the telnet program to reach the remote computer. Her session might look something like this:login: jenniferPassword: NOTICE to all second-floor MDs: meeting in room 304 at 4 PM. fuzzy% telnet biolab.medu.edu Medical University Biology Laboratory biolab.medu.edu login: jdnelsonPassword: biolab% . . .biolab% exitConnection closed by foreign host.fuzzy%
Her accounts have shell prompts that include the hostname. This reminds her when she's logged in remotely. If you use more than one system but don't have the hostname in your prompt.
1.1.4 The UNIX Shell
Once you've logged in, you're working with a program called a shell. The shell interprets the commands you enter, runs the program you've asked for, and generally coordinates what happens between you and the UNIX operating system. Common shells include Bourne (sh), Korn (ksh), and C (csh) shells, as well as bash and tcsh.
For a beginner, the differences between most shells are slight. If you plan to do a lot of work with UNIX, though, ask your system administrator which shell your account uses; you should learn more about your shell and its set of special commands.
1.1.5 The Shell Prompt
When the system finishes running a command, the shell replies with a prompt to tell you that you can enter another command line.
Shell prompts usually contain $ or %. The prompt can be customized, though, so your own shell prompt may be different.
1.1.6 Entering a Command Line
Entering a command line at the shell prompt tells the computer what to do. Each command line includes the name of a UNIX program. When you press [RETURN], the shell interprets your command line and executes the program.
The first word that you type at a shell prompt is always a UNIX command (program name). Like most things in UNIX, command names are case-sensitive; if the command name is lowercase (and most are), you must type it in lowercase. Some simple command lines have just one word: the command name.
1.1.6.1 date
An example single-word command line is date. Entering the command date displays the current date and time:% dateTue Nov 4 13:39:24 EST 1997%
As you type a command line, the system simply collects your input from the keyboard. Pressing the [RETURN] key tells the shell that you have finished entering text and that it can start executing the command.
1.1.6.2 who
Another simple command is who. It lists each logged-on user's username, terminal number, and login time.
The who command can also tell you who is logged in at the terminal you're using. The command line is who am i. This command line consists of the command (who) and arguments (am i). (The section "Syntax of UNIX Command Lines," later in this chapter, explains arguments.)% who am icactus!john tty23 Nov 6 08:26 (rose)
The response shown in this example says that:
· "I am" John.
· I'm logged on to the computer named "cactus."
· I'm using terminal 23.
· I logged in at 8:26 on the morning of November 6.
· I started my login from another computer named "rose."
Not all versions of who am i give the same information.
1.1.7 Correcting a Mistake
What if you make a mistake in a command line? Suppose you typed dare instead of date and pressed the [RETURN] key before you realized your mistake. The shell will give you an error message:% daredare: command not found%
Don't be too concerned about getting error messages. Sometimes you'll get an error even if it appears that you typed the command correctly. This can be caused by typing control characters that are invisible on the screen. Once the prompt returns, reenter your command.
Most modern shells let you recall previous commands and edit command lines. If you'll be doing a lot of work at the shell prompt, it's worth learning these handy techniques. They take more time to learn than we can spend here, though. Ask other users for help or read a reference book for your shell. We'll concentrate on simple methods that work with all shells.
If you see a mistake before you press [RETURN], you can use the [BACKSPACE] key to erase the mistake and put in the correction.
The erase character differs from system to system and from account to account, and can be customized. The most common erase characters are:
· [BACKSPACE]
· [DELETE], [DEL], or [RUBOUT] key
· [CTRL-H]
[CTRL-H] is called a control character. To type a control character (for example, [CTRL-H], hold down the [CTRL] key while pressing the letter "h". (This is like the way you make an uppercase letter: hold the [SHIFT] key while pressing a letter key.) In the text, we will write control characters as [CTRL-H], but in the examples, we will use the standard notation: ^H. This is not the same as pressing the ^ (caret) key, letting go, and then typing an H!
The key labeled [DEL] may be used as the interrupt character instead of the erase character. (It's labeled [DELETE] or [RUBOUT] on some terminals.) This key is used to interrupt or cancel a command, and can be used in many (but not all) cases when you want to quit what you're doing. Another character often programmed to do the same thing is [CTRL-C].
Some other common control characters are:
[CTRL-U]
Erases the whole input line; you can start over.
[CTRL-S]
Pauses output from a program that is writing to the screen.
[CTRL-Q]
Restarts output after a pause by [CTRL-S].
[CTRL-D]
Used to signal end-of-input for some programs and return you to a shell prompt. If you type [CTRL-D] at a shell prompt, it may also log you out of the UNIX system.
Find the erase and interrupt characters for your account and write them down:
_______ Backspace and erase a character
_______ Interrupt a command
1.1.8 Logging Out
To end a UNIX session, you must log out. You should not end a session by just turning off your terminal! To log out, enter the command exit. (In many cases, the command logout will also work.) Depending on your shell, you may also be able to log out by typing [CTRL-D].
What happens next depends on the place from which you've logged in:
· If your terminal is connected directly to the computer, the "login:" prompt should appear on the screen.
· If you're using a window system, the window will probably close. If you have additional windows open, you'll need to log out or close them, too. You may also need to terminate the window system itself.
· If you were connected to a remote computer, the system prompt from your local computer should reappear on your screen. (That is, you're still logged in to your local computer.) Repeat the process if you want to log out from the local computer.
6.1 What Environment Variables Are Good For
Many UNIX utilities, including the shell, need information about you and what you're doing in order to do a reasonable job.
What kinds of information? Well, to start with, a lot of programs (particularly editors) need to know what kind of terminal you're using. The shell needs to know where any commands you want to use are likely to be found. Lots of UNIX programs (like mail programs) include a command to start an editor as a subprocess; they like to know your favorite editor. And so on.
Of course, one could always write programs that made you put all this information on the command line. For example, you might have to type commands like:% mail -editor vi -term aardvark48 -favoritecolor blue_no_red
But your favorite editor probably doesn't change every day. (Nor will your favorite color.) The terminal you use may change frequently, but it certainly won't change from the time you log in until the time you log out. And you certainly wouldn't want to type something like this whenever you want to send mail.
Rather than forcing you to type this information with every command, UNIX uses environment variables to store information that you'd rather not worry about. For example, the TERM (5.10) environment variable tells programs what kind of terminal you're using. Any programs that care about your terminal type know (or ought to know) that they can read this variable, find out your terminal type, and act accordingly.
Similarly, the directories that store the commands you want to execute are listed in the PATH (6.4) variable. When you type a command, your shell looks through each directory in your PATH variable to find that command. Presumably, UNIX wouldn't need a PATH variable if all commands were located in the same directory; but you'll soon be writing your own commands (if you aren't already), and storing them in your own "private" command directories (4.2), and you'll need to tell the shell how to find them (8.7).
Warning!
Environment variables are managed by your shell. The difference between environment variables and regular shell variables (6.8) is that a shell variable is local to a particular instance of the shell (such as a shell script), while environment variables are "inherited" by any program you start, including another shell (38.4). That is, the new process gets its own copy of these variables, which it can read, modify, and pass on in turn to its own children. In fact, every UNIX process (not just the shell) passes its environment variables to its child processes.
You can set environment variables with a command like this:
;
% setenv NAME value C shell$ NAME=value; export NAME Bourne or Korn shell
There's nothing particularly special about the NAME; you can create environment variables with any names you want. Of course, these don't necessarily do anything for you; variables like PATH and TERM are important because lots of programs have "agreed" (6.3) that these names are important. But if you want to create an environment variable that holds the name of your lover, that's your business:% setenv LOVER Judy
If you're so inclined, you could write a program called valentine that reads the LOVER environment variable and generates an appropriate message. If you like short-term relationships or tend to forget names, this might even be convenient!
By convention, the names of environment variables use all uppercase letters. There's nothing to enforce this convention - if you're making your own names, you can use any capitalization you please. But there's no advantage to violating the convention, either. The environment variables that are used by standard UNIX programs all have uppercase names. [I usually make my shell variable names lowercase so it's easy to tell the difference. -JP ]
If you want the C shell to forget that an environment variable ever existed, use the command unsetenv NAME. (Some Bourne shells, but not all, have a similar command: unset NAME.)
printenvenv
If you want to list all of your environment variables, use printenv or env. (Both are on the CD-ROM.) The printenv command also lets you ask about a particular variable. Here's a typical report:% printenv EDITOREDITOR=/usr/local/bin/emacs% printenvHOME=/home/los/mikelSHELL=/bin/cshTERM=sunUSER=mikel PATH=/usr/local/bin:/usr/ucb:/bin:/usr/bin:.:/home/los/mikel/binLOGNAME=mikel PWD=/home/los/mikel/power/articlesPRINTER=psEDITOR=/usr/local/bin/emacs
The set (6.8) command provides a similar listing of shell variables.
You can also use the echo (8.6) command to show the value of a particular variable, preceding the variable name with a dollar sign (which tells the shell to substitute the value of the variable):% echo $TERMxterm


6.3 Predefined Environment Variables
We've said that environment variables are used to store information that you'd rather not worry about, and that there are a number of standard environment variables that many UNIX programs use. These are often called "predefined" environment variables - not because their values are predefined, but because their names and uses are predefined. Here are the most important ones:
· PATH (6.4) contains your command search path (8.7). This is a list of directories in which the shell looks to find commands. It's usually set in one of your shell setup files (2.2).
· EDITOR can be loaded with the name of your favorite editor. It's usually set in one of your shell setup files. Some programs distinguish between EDITOR (usually set to a line editor (33.1) such as ed) and VISUAL (set to a full-screen editor like vi). Many people don't follow that convention; they set both to the same editor. (The Korn shell checks VISUAL and EDITOR, in that order, to determine your command editing mode (11.13).)
· PRINTER (43.4) can be loaded with the name of your default printer. It's quite useful at a site with many printers - you don't need to tell lpr (43.2) which printer to use. This variable is usually set in one of your shell setup files.
· PWD contains the absolute pathname of your current directory. It's set automatically by the cd command in some UNIX shells. PWD may be fooled (14.13) by cding through symbolic links.
· HOME (14.11) (called LOGDIR on some systems) contains the absolute pathname of your home directory. It's set automatically when you log in.
· SHELL contains the absolute pathname of your login shell. It's set automatically whenever you log in.
· USER or LOGNAME contains your username. It's set automatically when you log in, and doesn't change.
· TERM (5.10) contains the name of your terminal type in the termcap or terminfo database. It's usually set in a shell setup file.
· TERMCAP (5.4) can be loaded with the complete termcap database entry for the terminal you are using. This may make some programs start up more quickly, but it's not necessary. It's set (under some conditions) by the tset command, which is usually run in your shell setup file.
· ENV contains the name of an initialization file to be executed whenever a new Korn shell is started. (See article 2.2.) Korn shell only.
· PAGER can be set to the name of your favorite page-by-page screen display program like more (25.3) or less (25.4). (Programs like man (50.1) use PAGER to determine which paging program to use if their output is longer than a single screen.)
· EXINIT (30.35, 6.10) stores setup options for the vi editor (and the ex editor, where EXINIT got its name).
· PS1 contains the primary prompt (i.e., interactive command prompt) for Bourne shells. (The C shell doesn't store the prompt in an environment variable. It uses a shell variable called prompt because the .cshrc file (2.2) is read to set up each instance of the shell. See article 7.2.)
· PS2 (9.13) contains the secondary prompt (used within compound commands like while and for) for Bourne shells.
· MANPATH (50.10), if your man (50.1) command supports it, is a colon-separated list of directories to search for manual pages.
· TZ (6.6) contains the time zone. This is a name of a file in /usr/lib/zoneinfo that provides time zone information for your locality. It is read by commands like date (51.10, 6.7).
· DISPLAY is used by the X Window System (1.31) to identify the display server (keyboard and screen handling program) that will be used for input and output by X applications.
Because Bourne-type shells don't make as strict a distinction between environment variables and shell variables as the C shell does, we've included a few things here that might not be on other people's lists.
We may have implied that environment variables are relatively constant (like your favorite editor). That's not true. For example, in a windowing environment, the current length of your window might be kept in an environment variable. That can change as often as you resize your window. What is true (fortunately) is exactly what we've said: environment variables store information that you'd rather not have to worry about.
6.4 The PATH Environment Variable
Of all the environment variables, the PATH and TERM (5.10) variables are the most important. The others are often great conveniences; but PATH and TERM can make your life miserable if they get screwed up.
The PATH variable is just a list of directories separated by colon (:) characters. The shell searches through these directories in order whenever it needs to find a command. So, if you want to execute commands in /bin, /usr/bin, /usr/local, the current directory, and your personal bin directory, you would put a line like the one below in your .login file. An empty entry (: as the first or last character, or :: in the middle) means "the current directory."
$HOME/bin
setenv PATH /bin:/usr/bin:/usr/local::$HOME/bin
Article 8.7 explains more about setting the path.
The most common problem with PATH is that, somehow, it gets deleted. This usually happens if you try to change PATH and do so incorrectly. When PATH is deleted, your shell can only find its built-in commands (1.10) and commands for which you give the complete pathname. Here's a demonstration:% setenv PATH Set PATH to null accidentally% lsls: Command not found.
Needless to say, this can be very frustrating - especially if you can't figure out what's going on. There are a couple of easy fixes. The easiest is just to log out and log back in again. (logout is a built-in C shell command, so you won't have trouble finding it. If you get an error message like "Not login shell," try exit instead.) Another fix is to read (44.23) whichever initialization file defined your PATH variable, usually .login for C shell users or .profile for Bourne shell users:% source ~/.login$ . $HOME/.profile
This will almost certainly give you some of your path back; the problem is that a lot of initialization files merely add a few "private" directories to a system-wide default path. In this case, just execute the system-wide initialization files first (if your system has them). Their pathnames vary:% source /usr/lib/Cshrc% source /usr/lib/Login% source ~/.login
The other common PATH problem is that users sometimes can't find the commands they want. This happens most often when someone writes a new shell script with the same name as a standard UNIX command - say, true. He or she tries to execute it and can't; in fact, all that happens is:% true%
After staring at the script for a long time, the user sometimes gets the right idea: the script is fine, it's the path that's wrong. The PATH variable will look something like this:% printenv PATH/bin:/usr/local:/usr/ucb:/usr/bin::/home/mkl/bin
The shell searches the PATH in order; therefore, it finds the system's standard true command before seeing the new one. The new command never gets a chance. You could fix this problem by putting the current directory and $HOME/bin at the head of the search path, in which case, commands in the current directory and your private bin directory will override the standard commands. However, that's not recommended; it's a well-known security hole.
So what is recommended? Nothing much, except: if you write shell scripts or other programs, give them names that are different from the standard UNIX utilities (44.21). If you really need an overlapping name, you can use a relative pathname (1.21) to specify "the program called true in the current directory":% ./true
Here are some related articles. You can search your PATH for a command with which (50.8), findcmd (16.10), and whereiz (4.10). Article 6.5 explains the C shell's path variable.
6.8 Shell Variables
Shell variables are really just the "general case" of environment variables (6.1). If you're a programmer, remember that a UNIX shell really runs an interpreted programming language. Shell variables belong to the shell; you can set them, print them, and work with them much as you can in a C program (or a FORTRAN program or a BASIC program). If you're not a programmer, just remember that shell variables are pigeonholes that store information for you or your shell to use.
If you've read the section on environment variables, you realize that we defined them in exactly the same way. How are shell variables different from environment variables? Whenever you start a new shell or a UNIX program, it inherits all of its parent's environment variables. However, it does not inherit any shell variables; it starts with a clean slate. If you're a programmer, you can think of environment variables as "global" variables, while shell variables are "local" variables. By convention, shell variables have lowercase names.
Just as some programs use certain environment variables, the shell expects to use certain shell variables. For example, the C shell uses the history (11.1) variable to determine how many of your previous commands to remember; if the noclobber (13.6) variable is defined, the C shell prevents you from damaging files by making mistakes with standard output. Most users insert code into their .cshrc files (2.2) to define these important variables appropriately.
To set a shell variable, use one of these commands:% set name=value C shell$ name=value Bourne shell
As a special case, if you omit value, the shell variable is set to a "null" value. For example, the following commands are valid:% set name C shell$ name= Bourne shell
This is important: giving a variable a null value is not the same as deleting the value. Some programs look at variables to see whether or not they exist; they don't care what the actual value is, and an empty value is as good as anything else. If you want to make the shell forget that a variable ever existed, use the unset command. Unfortunately, older Bourne shells don't have a command like unset:% unset name C shell$ unset name Bourne shell
If you want to list all of your environment variables, use the command printenv (Berkeley UNIX) or env (System V). [1] If you want to list all of your Bourne or C shell variables, just type set. Here's a typical report in the C shell:
[1] printenv and env are external (1.10) commands; they work with any shell.% setargv ()cwd /home/los/mikel/power/articleshistory 40home /home/los/mikelnoclobberpath (/home/los/mikel/bin /usr/local/bin /usr/ucb /bin /usr/bin .)prompt los%shell /bin/cshstatus 0term sunuser mikel
If you want to print the value of an individual variable, give the command:% echo "$variable-name"
(While the example above gives a C shell prompt, this command works in all UNIX shells.)
Whenever you need the value of a shell variable - not just with echo (8.6)- you need to put a dollar sign ($) in front of the name. You don't need the dollar sign when you're assigning a new value to a shell variable. You can also stick curly braces ({}) around the name, if you want (e.g., ${name}); when you're writing shell programs, this can often make your code much clearer. Curly braces are mostly used when you need to separate the variable name from what comes after it.
But that's getting us out of the range of interactive variable use and into shell programming (44.1).


6.9 Special C Shell Variables
[Sorry, no articles about bash and tcsh variables. This book focuses on the "base" shells, sh and csh. csh variables work in tcsh, and many work (in slightly different forms) with bash too. For a complete list, check your bash or tcsh manpage. -JP]
The C shell recognizes and uses environment variables, but it also uses a great many simple shell variables (6.8) to control its own operation. These variables don't need to be put into the environment so they can be passed to subshells (38.4), because every instance of the C shell always reads the .cshrc file (2.2). Simple shell variables set there are thus propagated to every C shell.
Many of the special C shell variables are simply used as flags; that is, they need not be set to any particular value. The shell simply tests whether they exist or not. They are set simply by saying:set variable
rather than:set variable=value
Here are some of the special variable names used by the C shell:
· The cdpath (14.5) variable stores a list of directories. You can cd to subdirectories of these by typing just the subdirectory name.
· If the echo (8.17) variable is set, the shell will show the command line, after all variable and history (11.7) substitutions, before executing it. (This is very handy for debugging scripts such as .cshrc.)
If the verbose (8.17) variable is set, the shell will show the command line after history substitution but before any other substitutions.
The Bourne shell -v and -x options (46.1) work like the verbose and echo variables.
· If the filec or complete variable is set, the shell performs filename completion (9.8). The fignore (9.9) variable makes filename completion skip filenames that end with certain characters like .o.
· The cwd (14.13) variable shows the absolute pathname of the current directory. The cd, pushd, and popd commands set it.
· The hardpaths (14.13) variable fixes errors in the cwd variable that occur when you cd through symbolic links.
· Use the histchars (11.15) variable to set different history characters than exclamation point (!) and caret (^).
· The history (11.1) variable stores the number of shell command lines to save. The savehist (11.11) variable stores the number of lines of shell history to be saved when you log out. This amount of history is saved in a file called .history in your home directory, and the lines are restored the next time you log in.
· If you set ignoreeof (3.5), the shell won't respond to the end-of-file character (CTRL-d) and will require you to type logout or exit (38.4) to log out. This can save you from ending the shell accidentally (or logging out).
· The shell can tell you about new electronic mail (1.33) or changes in other files with the mail (21.8) variable.
· Stop the > redirection character from overwriting files with noclobber (13.6).
· The noglob variable stops wildcard expansion (15.1). (There's an example in article 5.4.)
· Set nonomatch when you want the C shell to treat nonmatching wildcards like the Bourne shell does . (15.4)
· The notify (12.6) variable asks the shell to tell you right away if a background job finishes or is stopped.
· The list of directories that the shell searches for commands is stored in path (6.5).
· Your login name from the USER or LOGNAME (6.3) environment variable is also stored in the C shell variable named user.
· The shell's command-line prompt is set by the prompt (7.2) variable. (The PS1 (6.3) environment variable is the Bourne shell equivalent. You can set the Bourne shell's secondary prompt (9.13), too, in PS2.)
· The exit status (44.7) of the last command is stored in the csh variable named status and the sh ? (question mark) variable.
· If a job takes more CPU seconds than the number set in the time (39.3) variable, the csh will print a line of statistics about the job.

MCA 301

What is an Operating System?
An operating system is an important part of a computer system. You can view a computer system as being built from three general components: the hardware, the operating system, and the applications. (See Figure 1.1.) The hardware includes pieces such as a central processing unit (CPU), a keyboard, a hard drive, and a printer. You can think of these as the parts you are able to touch physically. Applications are why you use computers; they use the rest of the system to perform the desired task (for example, play a game, edit a memo, send electronic mail). The operating system is the component that on one side manages and controls the hardware and on the other manages the applications.
Figure 1.1. Computer system components.
When you purchase a computer system, you must have at least hardware and an operating system. The hardware you purchase is able to use (or run) one or more different operating systems. You can purchase a bundled computer package, which includes the hardware, the operating system, and possibly one or more applications. The operating system is necessary in order to manage the hardware and the applications.
When you turn on your computer, the operating system performs a series of tasks, presented in chronological order in the next few sections.
Hardware Management, Part 1
One of the first things you do, after successfully plugging together a plethora of cables and components, is turn on your computer. The operating system takes care of all the starting functions that must occur to get your computer to a usable state. Various pieces of hardware need to be initialized. After the start-up procedure is complete, the operating system awaits further instructions. If you shut down the computer, the operating system also has a procedure that makes sure all the hardware is shut down correctly. Before turning your computer off again, you might want to do something useful, which means that one or more applications are executed. Most boot ROMs do some hardware initialization but not much. Initialization of I/O devices is part of the LINUX kernel.
Process Management
After the operating system completes hardware initialization, you can execute an application. This executing application is called a process. It is the operating system's job to manage execution of the application. When you execute a program, the operating system creates a new process. Many processes can exist simultaneously, but only one process can actually be executing on a CPU at one time. The operating system switches between your processes so quickly that it can appear that the processes are executing simultaneously. This concept is referred to as time-sharing or multitasking.
When you exit your program (or it finishes executing), the process terminates, and the operating system manages the termination by reclaiming any resources that were being used.
Most applications perform some tasks between the time that the process is created and the time that it terminates. To perform these tasks, the program makes requests to the operating system and the operating system responds to the requests and allocates necessary resources to the program. When an executing process needs to use some hardware, the operating system provides access for the process.
Hardware Management, Part 2
To perform its task, a process may need to access hardware resources. The process may need to read or write to a file, send data to a network card (to communicate with another computer), or send data to a printer. The operating system provides such services for the process. This is referred to as resource allocation. A piece of hardware is a resource, and the operating system allocates available resources to the different processes that are running.
See Table 1.1 for a summary of different actions and what the operating system (OS) does to manage them.


Table 1.1. Operating system functions.
Action


OS Does This


You turn on the computer
Hardware management
You execute an application
Process management
Application reads a tape
Hardware management
Application waits for data
Process management
Process waits while other process runs
Process management
Process displays data on screen
Hardware management
Process writes data to tape
Hardware management
You quit, the process terminates
Process management
You turn off the computer
Hardware management
From the time you turn on your computer until you turn it off, the operating system is coordinating the operations. As hardware is initialized, accessed, or shut down, the operating system manages these resources. As applications execute, request, and receive resources, or terminate, the operating system takes care of these actions. Without an operating system, no application can run and your computer is just an expensive paperweight.
Linux's History

Linux was developed as a freely distributable version of UNIX. UNIX is the most widely used operating system in the world and has long been the standard for high-performance workstations and larger servers. UNIX, first developed in 1969, has a strong programmer-oriented user group that supports the operating system.
How did UNIX get its name? It was based on operating systems called MULTICS (MULTiplexed Information and Computing System). Ken Thompson, Dennis Ritchie, and Brian Kernighan were involved the design of a new operating system based on MULTICS that would be much simpler. They called the new operating system UNICS (Uniplexed Information and Computing System), which was quickly changed to UNIX.
Because UNIX is a commercial product, it must be bought for each platform it runs on. Licensing fees for UNIX versions for PC machines range from a few hundred dollars to several thousand. In an attempt to make UNIX widely available for no cost to those who want to experiment with it, a number of public domain UNIX systems have been developed over the years.
One of the early UNIX workalikes was Minix, written by Andy Tanenbaum. Although Minix didn't have a full range of features, it provided a small operating system that could be used on PC machines. To expand on Minix, a number of users started developing an enhanced operating system that would take advantage of the 80386 CPU's architecture. One of the primary developers of this system, which became known as Linux, was Linus Torvalds of the University of Helsinki. He released an early version of Linux in 1991. A first commercial, almost bug-free release was unleashed to the programming community in March 1992.
Soon, many programmers were working on Linux, and as the challenge and excitement of producing a growing UNIX workalike caught on, Linux grew at a remarkable rate. As the number of developers working on Linux grew, the entire UNIX workalike operating system was eventually completed and now includes all the tools you will find in a commercial UNIX product. Linux continues to grow as programmers adapt features and programs that were originally written as commercial UNIX products to Linux. New versions of Linux and its utilities are appearing at an astounding rate. New releases often appear weekly.
To avoid any charges for Linux, the Linux developers do not use any code from other UNIX systems. There are no licensing fees involved with the Linux operating system, and part of its mandate is to be freely available. Some companies have undertaken the task of assembling and testing versions of Linux, which they package on a CD-ROM for a (usually) minimal price.
Linux is not based on a single version of UNIX; it is a consolidation of the best features of BSD UNIX and System V. BSD UNIX was developed at the University of California at Berkeley, starting in 1977. Several major releases increased the power of BSD UNIX. Several standard UNIX programs originated at BSD, although BSD stopped its UNIX development in the early 1990s. AT&T, which developed the first version of UNIX, continued their UNIX development by producing a series of UNIX versions called System III, System IV, and System V. Linux uses the last primary release of BSD UNIX called 4.4BSD as its base and takes some other features from the latest release of System V, called System V Release 4 (SVR4).












Linux’s relationship to Unix
Several versions of UNIX and UNIX-like systems have been made that are free or extremely cheap and include source code. These versions have become particularly attractive to the modern-day hobbyist, who can now run a UNIX system at home for little investment and with great opportunity to experiment with the operating system or make changes to suit his or her needs.
An early UNIX-like system was MINIX, by Andrew Tanenbaum. His books Operating Systems: Design and Implementations describes MINIX and includes a source listing of the original version of MINIX. The latest version of MINIX is available from the publisher. MINIX is available in binary form for several machines (PC, Amiga, Atari, Macintosh, and SPARCStation).
In addition to the BSD386 product from BSDI, there is a free version of UNIX also based on the BSD releases, and called, confusingly, 386BSD. This is an effort by Bill and Lynne Jolitz to create a system for operating system research and experimentation. The source is freely available, and 386BSD has been described in a series of articles in Dr. Dobbs' Journal.
Another popular source version of UNIX is Linux. Linux was designed from the ground up by Linus Torvalds to be a free replacement for UNIX, and it aims for POSIX compliance. There are current efforts to make Linux reliably run both SVR3.2 and SVR4 binaries. There is also a project called WINE to create Microsoft Windows emulation capability for Linux.

Linux distributions
Several versions of Linux are available, depending on which CD-ROM or FTP site you visit. This book doesn't care which version you use, because it applies to practically every version written. As of this writing, the latest Linux kernel versions were 1.2.13 and 1.3.15. The CD-ROM included with this book provides Slackware release 2.3, which includes the kernel version 1.2.8 (the last really stable version the author tested). You can change kernel versions by obtaining the source code for a new release, compiling it, and replacing your existing kernel. This procedure is covered in more detail later in the book.
You may find several CD-ROM distributions available at your local reseller. InfoMagic's Slackware release, for example, comes on four CD-ROMs and bears the name Linux Developer's Resource. In addition to the complete Linux system, it includes source code, FTP archives, full documentation, several extension products, and demonstration software of commercial applications (including WordPerfect). Some of this material is included on the CD-ROM at the back of this book.

Linux architecture
















Installing and Updating Linux

You probably already have installed Linux. Even so, you may not be happy with the installation, either because of poor organization or because you were experimenting with it and would like to try again with a better configuration. This chapter discusses the issues you should address when you install Linux for the first time (or reinstall it, as the case may be) and how to update your existing Linux installation with new software releases.
The process for installing Linux is straightforward, although lots of little potential problems are scattered throughout the process. Don't believe the easy installation claims on many packages of the distribution software! Several steps require patience, experimentation, and a knowledge of what is going on before Linux will install painlessly. The essential steps for installing Linux are as follows:
Create boot and root disks for Linux.
Partition the hard disk.
Boot Linux from a floppy disk.
Create a swap file partition.
Create a Linux filesystem.
Install the Linux software.
Configure the kernel.
Set the boot process.
Reboot into Linux from your hard disk.
This chapter covers each of these steps in more detail. The process is very similar for installing from a CD-ROM and from a floppy disk (which may have come from an FTP site, for example). Because CD-ROM is the most common form of installation, this chapter uses that process as an example.
If you are installing from floppy disks and have downloaded the distribution files (or copied them from a CD-ROM), you will need a DOS-formatted floppy disk for each file in the distribution disk set. You can use standard DOS COPY commands to copy the disk set files to the floppy disks, using one floppy for each file in the distribution set. The files are all numbered so you know which floppy disk is in which set, and what their order should be.

Creating Boot and Root Disks

Even if you are installing from CD-ROM, you need two high-capacity floppy disks (either 1.2M or 1.44M). These disks are the boot and root floppy disks. The boot floppy disk holds the kernel that is used to start Linux the first time, leading to your installation. The root floppy disk holds a small filesystem that includes utilities needed for the installation. The two disks together form a complete and very small implementation of Linux. Enough of a system is on the two floppy disks to play with Linux, although many of the utilities are missing.
In most cases, the boot and root floppy disks are copied from existing files called images. The image is a precompiled version of the system that you duplicate on the floppy disks, eliminating the need to start from scratch. CD-ROM and FTP distributions have directories for several boot and root images, depending on the hardware on your system. You must select the images that match your hardware as much as possible, copy them to the floppy disks, and start your system with the floppy disks. You can do most of these steps from DOS, although you can't use the DOS COPY command to create the boot and root floppy disks. You must create the floppy disks with a utility that ignores the DOS formatting. This utility, commonly called RAWRITE.EXE, is included with most Linux software distributions.
Selecting a Boot Kernel and Root Image

CD-ROMs usually have directories under the root directory called bootdsks.144 and rootdsks.144 (for 3.5-inch 1.44M floppy disks) and bootdsks.12 and rootdsks.12 (for 5.25-inch 1.2M floppy disks), which contain the boot and root images, respectively. To find these directories, run DOS either from a floppy disk or a partition on your hard disk to examine the CD-ROM. The boot and root directories for 1.44M floppy disks from a typical CD-ROM Linux distribution are shown in Figure 3.1. If you are copying your files from an FTP site, you can select the boot and root images you need while connected to the remote FTP machine and transfer only the images you need to your local machine.
Figure 3.1 The boot and root directory entries for 1.44M floppy disk images, which are used to create the boot and root floppy disks needed to install Linux.
The types of boot kernels usually available are described in a file in the kernel image directories (usually called README, READ.ME, or WHICH.ONE). The boot kernel images are named to reflect the hardware for which they have drivers installed into the kernel. For example, the scsi kernel image has drivers in the kernel for SCSI-based systems; if you are on a PC that has a SCSI controller, hard disk, and CD-ROM, this is the image you want to copy to your boot floppy disk. The number of boot images available is quite large. These are the primary images available from most CD-ROMs and FTP sites and the hardware they are designed to handle:
aztech
IDE and SCSI hard disk drivers, and Aztech non-IDE CD-ROM support, including Aztech, Okana, Orchid, and Wearnes non-IDE CD-ROM drives
bare
IDE hard disk drivers only (no CD-ROM support)
cdu31a
IDE and SCSI hard disk drivers, with a Sony CDU31 or Sony CDU33a CD-ROM drive
cdu535
IDE and SCSI hard disk drivers, with a Sony 535 or Sony 531 CD-ROM drive
idecd
IDE and SCSI hard disk drivers, with IDE or ATAPI CD-ROM drive
mitsumi
IDE and SCSI hard disk drivers, with a Mitsumi CD-ROM drive
net
IDE hard disk drivers and Ethernet network card drivers
sbpcd
IDE and SCSI hard disk drivers with Sound Blaster Pro or Panasonic CD-ROM drivers. This image is for CD-ROM drives run off a Sound Blaster card (as supplied in many Sound Blaster multimedia kits).
scsi
IDE and SCSI hard drivers with SCSI peripherals (CD-ROM drives)
scsinet1
IDE and SCSI hard disk drivers, SCSI CD-ROM driver, and Ethernet drivers for networking. The SCSI drivers support Adaptec 152X, 1542, 1740, 274x, and 284x adapters, Buslogic adapters, EATA-DMA adapters (such as DPT, NEC, and AT&T cards), Seagate ST-02 adapters, and Future Domain TCC-8xx and 16xx adapters. SCSI adapters compatible with any of these cards will also work.
scsinet2
IDE and SCSI hard disk drivers, SCSI CD-ROM driver, and Ethernet drivers for networking. The SCSI drivers support NCR5380-based adapters, NCR 53C7 and 8xx adapters, Always IN2000 adapter, Pro Audio Spectrum 16 adapter, Qlogic adapter, Trantor T128, T128F, and T228 adapters, Ultrastor adapters, and the 7000 FASST adapters. Compatibles of any of these cards should also work.
xt
IDE and IBM PC-XT-compatible hard disk drivers
With some distributions, an extension is added to the kernel image name to indicate the floppy disk type. For example, if the kernel image is for a 1.44M floppy disk, it will have the filetype .144 as part of the name. Similarly, a filetype of .12 indicates a 1.2M image. You cannot interchange these images, or the diskette will be useless (in other words you cannot load a .12 image onto a 1.44M diskette). Most distributions don't bother with this convention, since the files are in the appropriate directories for the floppy disk size.
You have fewer choices for the root floppy image. Most distributions include four basic images, although a few more esoteric images also appear from time to time. Each of the root images has the disk size as part of its name (color144 and color12, for example). The basic root floppy images are the following:
The color image offers a full-screen color-based installation script for installing Linux.
The tape image is designed to support Linux installation from a cartridge tape. This kernel has limited functionality and depends on the type of tape drive used. Typically, QIC drives are supported, but users of some models have reported problems.
The tty image is a dumb terminal installation version with no color or graphics.
The umsdos image is used to install UMSDOS, which allows you to install Linux into an existing MS-DOS partition. The installation script creates the subdirectories it needs. UMSDOS is not as efficient or fast as a dedicated Linux partition, but you can retain your current disk partitions.
The color root image is a lot more attractive than the tty image and can make the Linux installation a bit friendlier. The color image is intolerant of typing errors and doesn't always proceed smoothly, however. It's worth a try, in most cases, unless you know exactly how you want to install Linux. The color process tends to require much more user interaction, including clicking OK buttons at many stages.
Once you have determined which of the boot and root images you will use (if you are not sure, pick the boot image that most closely matches your hardware configuration and the color or tty root image), you can create the boot and root floppy disks. If you choose the boot and root images incorrectly, don't worry. All that will happen is that you won't be able to install Linux, and you'll have to start the process again.
Creating the Boot and Root Floppy Disks

You can create the boot and root floppy disks either from DOS or from UNIX (or Linux). If you don't run DOS yet, and don't have a DOS boot disk, you will have to use another machine to create the two floppy disks. Because creating the floppy disk from DOS is the most common method, this section deals with this method first.
To create the boot and root floppy disks, you must use a utility program to write the image to floppy disk. If you obtained your boot and root images from an FTP or BBS site, the files may be compressed and archived. If they are, they will end with the filetype .gz. Before you can install the images to a floppy disk, you must decompress them with the gzip utility. If you are working from CD-ROM, you will have to copy the files to a DOS hard disk because you can't write the decompressed image to the CD-ROM. Even if you start with decompressed files, it may be easier to copy the images to a temporary DOS directory as it will save you the hassle of worrying about directory pathnames.
To decompress a .gz file, issue the command

gzip -d
where filename is the name of the compressed file (including the .gz extension). The -d option tells gzip to decompress the file. After the file is decompressed, the .gz file is erased and only the decompressed file remains (with the same filename, without the .gz extension). To decompress the scsi.144 and color144 images, for example, you would issue the following commands:

gzip -d scsi.gz

gzip -d color144.gz
To write the images to the two floppy disks you need two high-density floppy disks and the RAWRITE utility. The two floppy disks don't have to be blank, as the RAWRITE utility doesn't respect DOS file formats (although the disk must be formatted). The two floppy disks must be high density, though. You can mix disk types (in other words, you can use a 1.2M boot floppy disk and 1.44M root floppy disk) with some distributions of Linux, although it's not recommended for most systems. Keeping everything the same disk size is a lot easier. The disks must be formatted using DOS' FORMAT program. The boot floppy disk must be the correct size for your system's boot floppy disk drive (A: in DOS terms).
RAWRITE is a DOS program that writes the images, block-by-block, to the floppy disk. To use the RAWRITE program, just enter its name. RAWRITE prompts you for the name of the file to copy, and the destination drive letter. RAWRITE will then copy the images. Once the process is completed, DOS cannot read the floppy disk. Label the disks as the boot and root floppy disks, for convenience.
If you have access to a UNIX or Linux system, you can create the boot disks from within that operating system. You will need to put the two image files on the UNIX or Linux system, and use the dd utility to copy them to the floppy disks. This is also the procedure to follow if you are upgrading your existing Linux system to a newer release. First, make sure the images are decompressed (no .gz extension). If they are not, decompress them with the UNIX gunzip utility (a GNU utility that you may have to obtain from another source, if it's not included with your distribution). To decompress files in UNIX or Linux, issue the command

gunzip
where filename is the name of the image file with a .gz extension. The gunzip utility erases the compressed file and leaves an decompressed version in its place.
To copy the images to a floppy disk, you need to know the device name of the floppy drive within the operating system. For most systems, the first floppy drive is /dev/fd0, and the second floppy drive is /dev/fd1. (Some systems treat the floppy drives as raw devices, which have the names /dev/rfd0 and /dev/rfd1.) Copy the image files to the floppy disks with the command

dd if= of=/dev/fd0 obs=18k
where filename is the name of the decompressed image. The dd command converts file formats. The if and of parts of the command indicate the input and output filenames of devices. The obs portion of the command indicates the output block size (in this case, 18K).
For example, to copy the scsi and color144 images to the first floppy drive (3.5-inch 1.44M), issue the following two commands:

dd if=scsi of=/dev/fd0 obs=18k

dd if=color144 of=/dev/fd0 obs=18k
Linux is particularly stubborn about telling you your progress, so you won't see many messages. When dd starts the copy, it tells you how many blocks it will move. When it finishes, it returns the shell prompt to you without any message (unless the procedure failed). Figure 3.2 shows the command for copying the root kernel scsi to a floppy disk. After you copy both the root and boot kernels, you have completed this stage of the installation. The two floppy disks are now ready to boot a minimum Linux system for you.
Figure 3.2. You can use the dd command to copy the boot and root images to floppy disk from any Linux or UNIX system.
Partitioning the Hard Disk

Hard disks are divided into partitions, which are areas dedicated to an operating system. A hard disk can have up to four primary partitions, with some partitions being divided into more logical drives by the operating system software. A more complete discussion of partitions is in Chapter 4, "LILO."
If you are running Linux from a DOS partition using the UMSDOS root image, you don't have to worry about repartitioning your drives. Your existing drive's partitions will be used. However, because UMSDOS is a poor filesystem compared to Linux's, you will probably want to create your own Linux partitions. Check the later section "Using UMSDOS" for information on setting up UMSDOS.
Linux prefers two partitions: one for the Linux swap space and one for the Linux software filesystem itself. The swap space is used as an extension of your machine's physical RAM and can be quite small. Technically, you don't need a swap partition, especially if you have lots of RAM, but it is a very good idea to create one anyway as your system can grind to a halt suddenly if RAM is exhausted. The Linux filesystem partition tends to be quite large, as it must hold all the Linux software. You can have several Linux filesystem partitions to hold utilities, applications, and user files, although one partition must be designated as the boot partition (where the kernel and primary utilities are located).
If you are using a hard disk that has an operating system already installed on it, you will have to repartition your hard disk to make room for Linux. This process will destroy anything already on your hard disk, so make backups of any existing data you want to keep!
You use the fdisk utility to partition a hard disk. The Linux version of fdisk does the same task as FDISK in DOS, although the menus are completely different (and much more complicated). Many PC-based UNIX systems also use fdisk to partition hard drives.
A DOS utility called FIPS sometimes allows non-destructive changes to your partitions, assuming no data is on the areas that will be repartitioned. FIPS is available from many sources, including most of the Linux FTP sites and on some Linux CD-ROMs. However, you should make backups, just in case.
You must decide how much space to allocate to the different partitions before you start, as changing your mind later will mean destroying all the data you have saved to disk. The Linux swap space partition size depends on the amount of RAM in your system, the number of users you expect, and the type of development you will do.
If you are going to maintain a DOS partition on the same disk, you will have to balance the disk space requirements of both operating systems against your total disk capacity. A minimum Linux filesystem partition will be about 20M, although closer to 100M is needed for a full X-based installation.
Determining the Size of the Linux Swap Space Partition

How big should the swap space partition be? No single number works for all installations, unfortunately. Generally, because the swap space is used as an extension of physical RAM, the more RAM you have, the less swap space is required. Add the amount of swap space and the amount of RAM together to get the amount of RAM Linux will use. For example, if you have 8M of RAM on your machine's motherboard and a 16M swap space partition, Linux will behave as though you had 24M RAM.
Linux uses the swap space by moving pages of physical RAM to the swap space when it doesn't need them, and moving them back again when it needs the memory pages. Why not make a very large swap space and let Linux think it's in heaven? The swap space is much slower in access time than RAM, and there is a point at which the size of the swap space starts to act against your Linux system's efficiency instead of for it. In addition, most versions of Linux have an upper limit of 16M for each swap partition. Those versions of Linux will, however, let you partition more than 16M to a swap space, but it will only use the first 16M. If needed, though, you can create multiple swap partitions. Up to eight swap partitions can exist, each up to 16M in size. The latest versions of Linux allow swap partitions larger than 16M, but it is wise to keep that size as a guide.
You may not even need swap space if you have lots of RAM. For example, if you have 16M of physical RAM and don't intend to do any application development or run X, you probably won't make much use of the swap space because Linux can fit everything it needs in the 16M. (You still should have a small swap space, just in case.) If you are running X, developing applications, or running memory-hog applications like databases, swap space is crucial even if you have lots of physical RAM. Even 16M RAM is not enough for X, so you need swap space.
A good rule is to create a swap space with the maximum size limit of 16M. Unless you have a very small capacity hard disk, a swap space of this size won't be a major drain on your resources, and it gives Linux plenty of space with which to work. If you don't want to allocate this much space, a good rule is to have a total of 16M RAM (swap space plus physical RAM). Don't eliminate the swap space completely, though, even if you have a lot of RAM. At a minimum, set up a 4M swap space. Running out of RAM can cause Linux to lock up or crash.
Once a swap space partition has been created, it is just like any other partition on the hard drive. If you want to change its size, you have to remove the existing partition and create a new one, although the space must be contiguous on the hard drive (which can be difficult to do if you have used all the space the drive offers for other partitions).
Setting up Partitions

You use the fdisk utility to set up the partitions on your hard disk. Remember that fdisk will destroy existing data on your disk! You can set up your Linux disk partitions either from DOS, or from within Linux. It really doesn't matter which approach you use, although the DOS FDISK program is a little easier to use than Linux's. If you are using DOS FDISK to repartition a DOS area on your drives, use it to set up the Linux swap space and filesystem partitions, too.
To set up partitions for Linux, remove any existing partitions first (unless you want to keep them as they are). If you intend to use DOS on the same system as Linux, DOS should be the first partition on the disk so it can boot. (You can use LILO to get by this restriction, but it is still a good rule to leave DOS as the first partition.) If you are keeping an existing DOS partition on your hard drive, leave the first partition as DOS if you can.
Create a DOS boot disk that can reformat and transfer the DOS kernel to the hard drive, regardless of whether you are leaving an existing DOS partition or creating a new one. To create the boot disk, use the DOS

format a: /s
command (assuming A: is the drive the disk is in). The /s option transfers the operating system kernel. Next, copy the utilities FDISK, FORMAT, SYS, and CHKDSK to the boot disk. You should also copy an editor such as EDIT(which requires the QBASIC files as well), and your existing CONFIG.SYS and AUTOEXEC.BAT files (although you could rename them). This disk will let you format any new DOS partitions. Alternatively, if you are starting from scratch with a new DOS partition, you can reload DOS from the original floppy disks when ready to format the DOS partition.
If you are removing an existing DOS partition and recreating a smaller one (as you would if your entire disk was DOS before Linux came into your life), follow these steps (after making a backup of your DOS data):
Remove the existing DOS partition.
Create a new primary DOS partition as the first partition.
Make the DOS partition active.
Reboot the system from your boot disk (or DOS disks).
Format the DOS partition and transfer the DOS kernel (COMMAND.COM).
Restore your backup files to the DOS partition. (You can do this step at anytime).
Next, set up the Linux swap space partition by creating a partition of the proper size. You can do this step either from DOS or when you have booted Linux from the boot and root floppy disks. The rest of this section assumes that you are setting up the partitions from DOS, although the process is the same either way.
Most versions of FDISK allow you to enter the size of the partition in megabytes, with the utility calculating the sector numbers that apply to it. Set the size of the Linux swap space to whatever size you decided, up to a maximum of 16M. Don't make the partition active or format it! You can set up the swap space partition in an extended disk partition, but a primary partition is a better choice if your disk can support it.
Finally, create the Linux filesystem partition to be whatever size you want; you can even make it the size of the rest of the disk if that's the only partition missing. Again, don't activate or format the partition. When you are running the Linux installation routine, you will identify and format the swap space and filesystem partitions properly.
Using UMSDOS

UMSDOS allows you to use an existing DOS partition to house your Linux system. However, since you will be forcing Linux to use the DOS disk layout, you will suffer some performance limitations compared to creating a dedicated Linux partition. On the other hand, using UMSDOS lets you keep your disk drive the way it is, preventing the hassle of repartitioning and reformatting your drive. It is also a fast and easy way to install Linux if you only want to experiment for a while before installing a full system.
Note that UMSDOS does not let you run DOS and Linux at the same time. UMSDOS (UNIX in MS-DOS) only creates the Linux filesystem under the DOS formatted partition, although the partition is modified to allow long filenames, Linux file permissions, and more. When you start the system, you still have to choose between booting Linux or DOS as the operating system. If you start DOS, you can't use the extended Linux filenames, although you will be able to snoop around the directories. Filenames may not make much sense because of the contraction from long Linux filenames to DOS-compatible filenames, though.
The only limitation about UMSDOS is that the DOS filesystem is not designed as well as the Linux filesystem, so you get some performance degradation. This problem isn't major as most people don't notice the difference unless they are running a file-intensive application like X or compiling programs. You can always start with UMSDOS; then if you decide you like Linux enough, back up the Linux data and repartition the drive to create a true Linux filesystem.
If you want to use UMSDOS, you have to perform a few extra steps when setting up the disk. You must still create the boot and root disks, although you will need a root image that supports UMSDOS. (Most distributions have the root images umsds144 and umsds12 for this purpose.) When you boot Linux and it asks which partition to use for the filesystem, you specify the DOS partition. UMSDOS then initializes the filesystem for you. After that, the procedure for installing the rest of Linux is the same as it is for a dedicated Linux partition.
Installing the Linux Partitions

The Linux installation process starts when you boot your system from the boot floppy disk. After the kernel has loaded, you will be prompted to remove the boot floppy disk and insert your root floppy disk. When the root filesystem has been read, you will either be sent directly to an installation script, or presented with the login prompt. Log in as root. No password is required, because you haven't yet added one to the system.
The first step is to set up the disk partitions, if you haven't already done so, using fdisk. If you have more than one hard drive, you can place your Linux partitions on either drive. If you are planning on keeping a DOS partition, though, make sure that partition is the first partition on the first drive. Linux isn't so picky. If you want to boot Linux cleanly, place a Linux filesystem on the first drive. You can also create Linux filesystems on the second drive. A Linux swap partition can be on either drive, although keeping it on the first drive with the first filesystem is a good idea.
Linux's fdisk

Linux's fdisk program is different than the one in DOS, so check the menus frequently to determine the proper commands. You invoke Linux's fdisk in the same manner as DOS'. If you don't specify a drive, fdisk assumes the first one in the system. Otherwise, you can specifically indicate which disk drive to partition by giving the device name on the command line, as in

fdisk /dev/hdb
which invokes fdisk for the second drive. If your system has IDE, ESDI, or RLL drives, the first drive is /dev/hda and the second is /dev/hdb. SCSI drives are /dev/sda, /dev/sdb, and so on. Because a single controller can support seven SCSI drives, you could have up to /dev/hdg. (You can go even higher with another controller card, but few Linux systems will require that many drives!)
You should not use Linux's fdisk utility to create partitions for operating systems other than Linux. If, for example, you want a DOS partition on your disk, create it with DOS' FDISK. Linux does not write the partition table properly for other operating systems.
As mentioned earlier, Linux's fdisk commands are different than the FDISK commands for DOS. The following list explains the commands you need to run Linux's fdisk utility:
Command
Action
d
Deletes an existing partition
l
Lists all known partition types
n
Creates a new partition
p
Displays the current partition table
q
Quits fdisk without saving changes
t
Changes a partition's type code
v
Verifies the partition table
w
Writes current partition table to disk and exits
Linux's fdisk utility offers quite a few more commands, as Figure 3.3 shows. This screen is the output from the Linux fdisk help (m) command. Note the warning at the top of the screen. This warning is issued whenever your hard drive has more than 1024 cylinders, which early versions of Linux (pre 1.0 kernels mostly) couldn't support. Later versions of Linux, including the version provided on this book's CD-ROM, all support much larger hard drives. The warning is a holdover from the earlier system and should really be taken out.
Figure 3.3. Linux's fdisk utility offers these commands.
The process for setting up a partition is to first examine the partition table to make sure any existing partitions are correct. If you have a DOS partition on your drive, it should show in the partition table. If you created Linux swap and filesystem partitions when you were in DOS' fdisk, they should appear in the partition table too, although the partitions' types will be incorrect.
Setting Up Linux Partitions

To create the Linux swap space partition, use the n command and give the starting sector number. Usually, this number will be immediately after any existing DOS partition (or other operating systems you have installed). Linux's fdisk lets you specify the size of the partition either by supplying an end sector number or by giving a size in megabytes (remember the swap space size has a practical maximum of 16M). If you give the size in megabytes, the format is usually +XXM, where XX is the number of megabytes (such as +16M). You can also specify kilobytes, but you don't want to create a swap partition that is less than 1M.
Most PC BIOSs cannot handle more than 1024 cylinders on a disk drive. You may not be able to create DOS or Linux partitions or filesystems that go beyond the 1,023th cylinder (numbering starts at zero). Some other operating systems, such as SCO UNIX, allow you to use anything beyond the 1,024 limit. Linux can use partitions beyond the 1,024 limit, but it can't boot from them. If you have a disk drive that has more than 1023 cylinders, make sure your primary Linux partition ends before 1023. You can create extra partitions following that cylinder and mount them as second filesystems. Alternatively, you can create a single large Linux filesystem that extends or starts beyond the 1,023rd cylinder and use a LILO boot floppy disk.
The fdisk program asks you whether you want to create a primary or an extended partition. If you are creating a primary partition, the program wants the number (one to four—remember a DOS partition has to be number one to boot). In most cases, you should create only primary partitions, unless you have a large disk drive. You can use extended partitions to add logical drives inside primary partitions, which is similar to the way DOS creates logical drives. In Linux, extended partitions are not the same as extended filesystems!
Some distributions of Linux issue the message Warning: Linux can't currently use X sectors of this partition. This warning was in early versions of Linux that couldn't handle filesystems larger than 64K and can be ignored.
After you have created the Linux partition, assign it a type. Some versions of fdisk prompt for this information right away, and others let you select the option to assign filesystem types from the fdisk menu. In either case, the letter l will display all known filesystem types. Choose the one that designates a Linux swap space (number 82), and check the partition table. Figure 3.4 shows the filesystem types supported by the version of Linux included with this book. As you can see, many filesystem types are allowed, although most users will only use the DOS, Linux swap, and Linux data types. The other filesystem types were included in earlier versions of Linux for compatibility with other operating systems.
Figure 3.4. The filesystem types supported by Linux, identified by type number and description.
Your Linux swap space partition should have the correct size and partition type when you display the partition table with the p command. Although Linux doesn't care about the partition type numbers, some other operating systems do note them, so it's a good practice to label them correctly in order to prevent future problems. This practice also helps you keep the partition table organized.
Next, create your primary Linux filesystem partition in the same manner. If you want to use the rest of the disk drive for that partition, you can enter the end sector number of your drive (Linux's fdisk will tell you the range you can use). This number would be the usual default if your hard drive has a DOS, Linux swap space, and Linux filesystem partition on it. After you have created the Linux filesystem partition, identify its filetype as 82, which is a Linux native type. You can display the partition table at any time with the p command (inside fdisk only). Figure 3.5 shows a partition table set up on a 2.4G SCSI hard drive (/dev/sda), which has 500M for DOS (/dev/sda1), a 16M Linux swap space partition (/dev/sda2), and the rest of the drive for Linux data (/dev/sda3).
Figure 3.5. A completed partition table with DOS and Linux sharing a large (2.4G) drive.
Make a note of the size of the swap space and filesystem partitions, in blocks, as you will need this information later. You can read this information straight from the partition table. After you create the Linux partitions and are satisfied with the partition table layout, save and exit fdisk. Make sure you write the table to disk with the w command. If you don't save the information, you will have to repeat the process again.
Enabling the Swap Space for Installation

Linux's installation routine requires a good chunk of RAM to proceed. If you have 4M of RAM or less, you will have problems installing Linux unless you have the kernel use the swap space partition. (If you have only 4M or less of RAM in your system, you should have a swap space of at least 8M, preferably 16M.) If you try to install Linux and get memory error messages, you system doesn't have enough RAM and the kernel needs to use the swap space. Even if you have lots of RAM, there's no reason not to enable the swap space now. To enable the swap space, issue the command

mkswap -c partition size
where partition is the name of the partition and size is the size of the partition in blocks. If you didn't make a note of this number earlier when setting up the partition table, you can start fdisk again and read the size in blocks from the partition table display.
For example, if you have set up the Linux swap space on partition /dev/hda2 (the second primary partition on the first non-SCSI drive) and it has a size of 13,565 blocks you would issue the command

mkswap -c /dev/hda2 13565
The -c option in the command line tells the mkswap utility to format the partition and check it for bad blocks. This option slows down the creation of the swap partition a little, but a bad block in the swap partition can cause your entire system to crash. If mkswap finds any errors in the swap space, it will generate an error message and mark the block as unusable by the operating system (the block is removed from the total available for swap space). Because mkswap flags bad blocks to be left alone, you can ignore the bad block messages unless there is a considerable number of them (ten or more is a good limit in a 16M partition), in which case your hard drive has too many bad blocks and you should consider either low-level formatting it or replacing it with a new drive.
After you set up the swap partition, you enable the Linux swap space partition with the swapon command. Usually, you have to specify the partition, although some versions use the partition table to figure out the partition automatically. It never hurts to be explicit, though. To enable the swap partition set up in the preceding example, you would enter the command

swapon /dev/hda2
You have to repeat the mkswap and swapon commands for each swap partition, if you created more than one. As soon as you execute the swapon command, the Linux kernel starts to use the new swap space as an extension of the physical RAM. Figure 3.6 shows a swap partition called /dev/sda2 (second partition on the first SCSI drive) being set up and activated. Note that you need to know the size of the partition in blocks. You get this number from the fdisk utility.
Figure 3.6. Setting up and activating a swap partition on /dev/sda2.
If you've turned on the swap space and still get error messages when you try to install Linux, you need either more physical RAM or a larger swap space. Increasing the swap space now and then installing Linux is better than having to redo it later. To increase the size of a swap space partition, you may have to remove the existing Linux partitions and recreate them with fdisk.

Creating the Linux Filesystem Partition

Once you have a swap space configured and working, you can set up the Linux filesystem. Some Linux installation scripts automate this step, or you may have to execute it yourself. Either way, this section explains what is going on.
You have already allocated the partition table to support a Linux filesystem. Now you can create the filesystem with the mkfs (make filesystem) command. The exact format of the command depends on the type of filesystem you are setting up. The most popular filesystem (for reasons of speed and flexibility) is called the Second Extended filesystem (which has nothing to do with extended partitions on a hard disk). To create a Second Extended filesystem, issue the command

mke2fs -c
where partition is the device name and size is the size of the partition in blocks (taken from the partition display in fdisk). For example, to create a filesystem in /dev/hda3 that is 162,344 blocks in size, the command would be

mke2fs -c /dev/hda3 162344
When specifying the size of a partition, make sure you use blocks and not sectors or cylinders. Using the wrong value will result in errors or only a fraction of your partition being used.
The mke2fs utility checks the partition for bad blocks (the -c option), and then sets the filesystem up properly in that partition. If you are setting up a large partition, the disk check can take a few minutes, but you should not skip it unless you know your disk is good.
The other filesystems available to Linux are the Xia filesystem, the Extended filesystem, and the Minix filesystem. The Xia filesystem is good, but not as popular as the Second Extended filesystem. The Extended filesystem is an older version of Second Extended, and the Minix filesystem is compatible with the old Minix operating system (which Linux was written to replace). You can create these filesystems with the following commands:
Extended
mkefs
Minix
mkfs
Xia
mkxfs
All three commands take the same arguments as the Second Extended filesystem command. The Minix filesystem is limited to 64M. None of the mkfs commands format the filesystem; they just set it up. You are prompted for a filesystem format during the installation process.
Installing the Linux Software

After you create and format the partitions and create the filesystems, you can install the Linux software. This step may be automated, depending on the installation procedure included with your Linux distribution. Most versions of Linux include a utility called setup that installs the software for you. From the Linux prompt, type the command

setup
If you are running the color root image, you get graphic, full-screen windows for the installation process. Other root images use character-based installation messages instead. Many users who install Linux frequently avoid the color root image because it can take a little longer to answer all the questions the script poses and some typing errors are difficult to correct. Whichever root image you choose, carefully read each screen.
The setup utility supplied with the Linux system on this book's CD-ROM is shown in Figure 3.7. Some minor variations in menu choices exist between versions of Linux, but the primary options are much the same.
Figure 3.7. The most common setup utility menu.
Linux presents you with many choices during the installation. Although the default choices are correct for most people, check that the default is what you want. You have the option of letting Linux install everything without your prompting, except when disk sets change, but you should use this option only if you know exactly what is going on your disk. If you are installing Linux for the first time or want to choose the software to be installed by examining descriptions of each package, use the verbose options to show all messages and let you control the process.
Selecting the Source and Disk Sets

The setup installation script either asks you or lets you set several pieces of information. First, you need to specify the source of the software. You can usually accomplish this step by by selecting Source from the setup menu when setup starts its automatic installation process. If you have a CD-ROM, it should have been activated during the boot process if the drivers were correct for your hardware. Select the CD-ROM option. You may be asked to further narrow down the type of CD-ROM you have on your system. Choose the exact type(or the one closest to it) and hope for the best. If you are installing from another disk drive partition (such as another Linux partition or a DOS partition), provide the full device and path names. Figure 3.8 shows the Source option choices presented from the setup menu. From here, you can select CD-ROM. If Linux didn't identify your CD-ROM drive when it booted, you may be presented with another screen and asked to choose the type of CD-ROM drive your system has.
Figure 3.8. The Source option on the setup menu lets you select where the Linux software will be read from.
The installation program then asks for the target of the installation. The target is where you want the software to be installed. The newly created Linux partition is probably the location you want, so enter the partition's name. You will probably be asked whether you want to format that partition; answer yes. (Running mkfs or its variants does not format the partition for you.)
Next, Linux displays a list of the disk sets you can install. You may get to this screen through the normal installation process, or you can select Disk Sets from the setup menu. Choose the ones you want. The list of disk sets is usually a scrolling window, as shown in Figure 3.9. Make sure you scroll through the entire list and mark the disk sets you want to install.
Figure 3.9. The scrolling list holds the names of each major package Linux offers.
Some setup versions let you further refine the list of utilities when the disk set is installed. As a last step, verify the information, and then let Linux install itself. If this process doesn't start automatically, choose the Install option from the setup menu. Linux may double-check with you that you want to install the disk sets you've selected. This screen message looks similar to the one shown in Figure 3.10. This is your last chance to change your mind before Linux starts copying files to your hard drive. After you tell Linux to go ahead and install the software, watch for messages and prompts, and follow any on-screen instructions. If you are installing from a floppy disk, you will be prompted at intervals to change to the next disk in the disk set.
Figure 3.10. The Linux installation routine usually stops and prompts you before it starts installing software.
As Linux installs software, it displays status screens like the one shown in Figure 3.11 whenever the disk set is changed. As each piece of software in a disk set is installed, its name, size, and a brief description is often displayed, as shown in Figure 3.12. Occasionally, you will be asked to choose whether to install a particular component, as shown in Figure 3.13. Choosing yes installs the package described on the screen; choosing no (use the scroll key to display the no option) skips that package and moves to the next.
Figure 3.11. As Linux installs each selected disk set, setup displays the letter of the set. The e set being installed here is the GNU Emacs editor.
Figure 3.12. Each package in a disk set that is installed by default is displayed in a status message, along with the size and brief description of the package.
Figure 3.13. Some disk sets contain optional components. When one is encountered, you are presented with a screen like this one that describes the package and asks whether you want to install it.
Creating a Boot Disk

At the end of the installation routine, you may be prompted whether you want to create a boot disk. Figure 3.14 shows this screen from the Linux CD-ROM included with this book. The boot disk enables you to access the system at any time, especially if the normal boot process fails. You should always make a boot disk for emergency purposes. This disk is not the same as the boot floppy disk you made to start the installation (which is only useful when you reinstall from scratch).
Figure 3.14. During the installation process, setup may ask you whether you want to create a boot disk.
When you choose to create a boot disk, Linux prompts you for a floppy disk, as shown in Figure 3.15. Insert a floppy disk in the drive and choose Yes. (Choosing No abandons the creation of the boot disk.) Linux then proceeds to copy the the kernel image and some extra information to the floppy disk. While Linux is creating the boot disk, it shows you a message like the one in Figure 3.16.
Figure 3.15. When you choose to create a boot disk, Linux prompts you to insert a floppy disk in the drive and choose Yes.
Figure 3.16. This screen shows the progress of the creation of the boot disk.
Configuration Details

After installing disk sets and creating a boot disk, the setup routine may give you a choice to continue with the installation process by configuring your system or to leave the configuration until later. It's a good idea to continue with the process because back-tracking can be difficult sometimes. Although the order of prompts and the options presented to you are different depending on the version of the Linux system you are installing, usually you are asked to set up your modem first, as shown in Figure 3.17.
Figure 3.17. The first configuration information you are asked about is your modem.
If you have a modem installed on your system already, choose the Yes option to configure the port and modem speed now. Alternatively, if you are not sure which port you want to use or want to add the modem later, choose No. If you choose Yes to install a modem, you are asked for the device it is attached to, as shown in Figure 3.18. The devices are named in Linux format, with /dev/cua0 equivalent to COM1, /dev/cua1 equivalent to COM2, and so on. Choose the proper device. If your modem is used by DOS' COM2 port, for example, scroll to /dev/cua1 and choose OK. If you are not sure which port to use, try /dev/cua1, as most mouse ports are COM1 (/dev/cua0). You can always reconfigure the system later.
Figure 3.18. Choose the device your modem is attached to by using the Linux /dev/cua conventions.
Next you will be asked whether you want to set up your mouse, as shown in Figure 3.19. You can set the mouse up later, but it's easier to do it when you first load the Linux software. If you choose to configure the mouse at this time, you have to choose the type of mouse you are using. Figure 3.20 shows the list of currently supported mouse types. Most mouse peripherals are serial, so select the serial mouse that matches your unit. If in doubt, choose Microsoft compatible serial mouse.
Figure 3.19. Linux ask you whether you want to set up your mouse.
Figure 3.20. Choose the type of mouse your system uses.
After you choose the mouse, you may be asked for more information about it. If the mouse is a serial mouse, you must choose the port it is attached to, as shown in Figure 3.21. The port numbering is similar to the modem port (although the device name is different), with /dev/S0 corresponding to COM1, /dev/S1 to COM2, and so on. Don't select the same port as the modem! If you are installing a bus mouse, you may be asked for the DMA the mouse uses.
Figure 3.21. For serial mouse units, you must select the port the mouse is attached to.
Finally, you may be asked whether you want to try out some screen fonts. This step is time-consuming and generally unproductive. It is much better to go with the default fonts for now and modify them later if you really don't like them. These fonts are used for all character-based messages.



Setting the Boot Process

The last step in the Linux installation process is setting the boot device. A utility called LILO (Linux Loader) usually boots Linux. LILO can boot your system in several different ways, depending on whether you want to use your system with another operating system. Most of the time, you will want LILO to boot your system into Linux with the option to load DOS (if you have it on your system).
The LILO screens explain most of the choices quite well, but LILO has a few quirks to it. Chapter 4 is devoted to explaining what LILO does and how to make it behave properly. For now, if you are impatient, follow the defaults, but don't let LILO overwrite your hard disk's Master Boot Record. Doing so can cause a bit of a hassle when you want to boot DOS. You can, though, let LILO write a boot sector to your Linux partition, and then use fdisk to make either DOS or Linux active. If you're not too sure what to do with LILO, ignore it for now. You have a boot floppy disk that lets you start your machine. When you better understand LILO, you can set it up the way you want.
As a last step in the installation process, reboot your machine and let Linux boot from the boot floppy disk or from LILO, if you installed it. If everything boots properly, you can use Linux as you normally would. If you experienced problems booting, watch error messages and check the installation process to see which part went screwy. As long as you have your boot disk, you should be able to get into Linux without a problem.
Viewing Installed Software Files

When Linux is up and running, you may want to install or remove disk sets and other software. You can also check that components of a disk set have been properly installed. A few different utilities are available for this task, but the most common is called pkgtool. When you enter the pkgtool command name at the shell prompt, a menu that enables you to install new software, remove existing software, or view installed files in a package appears on-screen. Figure 3.22 shows the pkgtool menu. You can also use the setup utility for these tasks.
Figure 3.22. The pkgtool utility is one way to install, remove, or examine software on your Linux system.
To view the contents of a package, select View from the main pkgtool menu, and then choose the name of the package from the list presented. Figure 3.23 shows the list of packages. The list should include all the disk set tools you have installed, as well as any additional software installed after the first installation. Selecting a tool name sends pkgtool to check all the files that should be in the software and report its success. Sometimes the list of software in a package can take a while to appear. Be patient! The list pkgtool presents usually has a brief description of the tool and a list of all the files in the installation. Figure 3.24 shows the entry for the base software package.
Figure 3.23 When you select View from the pkgtool utility, you must choose which package to view.
Figure 3.24 The pkgtool utility shows the components installed for each package on your system.
When the list of files is displayed, you can move through them with the space bar. To leave the list of files, select the Exit option at the bottom of the screen.
Troubleshooting

Many different problems can occur while setting up and installing a Linux system, although most of them are self-explanatory from error messages. The following sections look at a few of the most commonly encountered problems.
Software Installation Problems

You may encounter a few errors when installing Linux. If you get the message device full, you have run out of disk space and need to either break up the installation into several partitions or install fewer components. If you haven't yet installed the basic system, you need more disk space. You have to delete your partitions and start the installation process again, allocating more space to Linux.
Errors such as read error, file not found and tar: read error are indicative of a problem with either the disk medium you are installing from, or an incomplete disk set. These problems usually occur with floppy disks and may indicate that you have a bad floppy disk. All you can do in most cases is replace the floppy disk with a new one.
Hard Disk and Disk Controller Problems

When Linux boots, it displays a few messages, one of the most important being a partition check. You see messages like the following:

Partition check:

hda: hda1 hda2 hda3

hdb: hdb1 hdb2
In this example, the first non-SCSI disk has three partitions and the second disk has two. Your system's output is probably different, of course. If you don't see any partition information, either the hard disk controller is not recognized properly or the disk drives are not accessible. Check the following potential causes for these problems:
Check the cables inside the computer. The hard disk cable should run from the adapter card to each drive's connector. Make sure the cables are connected in the proper manner (the red strip on the cable is at pin 1 on the connector).
Check that the power connector is attached to each disk drive. Without power, your drive doesn't spin up and Linux can't touch it.
Check the partition table to make sure you created a Linux partition properly.
If the drive is still not working properly with Linux but works OK when you boot DOS, a kernel driver for the hard disk is likely at fault. Some IDE drives, for example, are not as well-behaved (not conforming to the IDE standards) as others, and your IDE kernel driver may not be able to talk to your drives. Try using a different kernel image and see if the problem solves itself. If you are using a SCSI kernel and adapter and the drives are not recognized, use the utilities that came with the SCSI adapter card to force a check of the hard drives. They may have a SCSI ID set incorrectly.
Device Conflicts

One of the most commonly encountered problems is hardware that is not recognized properly. This problem can happen to a CD-ROM, a network card, and even a hard disk. Most of the time, a conflict in the IRQ (interrupt), DMA (Direct Memory Address), or I/O address settings causes this problem. When two devices have the same settings on any one of these three characteristics, Linux and the BIOS may not be able to communicate with the device properly.
A symptom of this problem may be Linux hanging when it tries to find a specific device, as explained in the boot messages. When Linux boots up, it generates messages that explain what it is doing. If you see a message that it is trying to connect to the network card, for example, and it never gets past that point, chances are that the network card has a conflict with another device. (Totally failed cards are very rare and don't usually stop the boot process, as Linux ignores devices it can't access. The problem with a working card with conflicting settings is that Linux is getting messages from two devices that don't act the same.)
To check for conflicts, run a diagnostic utility under DOS, such as MSD or Norton Info. These utilities can show you the current IRQ, DMA, and I/O addresses and pinpoint any conflicts. you can also use them to find available settings. Alternatively, you can check the settings of every device in your system for conflicts. Usually, network cards conflict with sound boards, non-SCSI tape driver cards, video cards, and similar add-on cards. Most cards use DIPs or jumpers to set these parameters, so check them against the documentation. To help isolate the problem, remove cards that are not necessary, such as a sound card, and see whether the boot process moves past the device that caused the hangup.
Another problem that can occur is with SCSI devices (and a few others, although much rarer) that must have specific settings in the kernel image. Some kernels, especially special-purpose kernels that have been developed for non-mainstream adapters, were compiled with settings that are default values for adapters or disk drives, and if the settings have been changed, the kernel hangs up. To check for this type of problem, investigate any documentation that came with the kernel image.
The most common devices in a PC (COM ports, parallel ports, and floppy disks) and their IRQ, DMA, and I/O addresses are shown in in the following list. These are the default values for a PC, but they may be changed by users. Because only two COM ports (serial ports) are usually supported by DOS, they share IRQ values. The I/O addresses are different, though. Both floppy disks share the same I/O addresses, IRQ, and DMA.
Device
IRQ
DMA
I/O Address (Hex)
COM 1 (/dev/ttyS0)
4
N/A
3F8
COM 2 (/dev/ttyS1)
3
N/A
2F8
COM 3 (/dev/ttyS2)
4
N/A
3E8
COM 4 (/dev/ttys3)
3
N/A
2E8
LPT 1 (/dev/lp0)
7
N/A
378-37F
LPT 2 (/dev/lp1)
5
N/A
278-27F
Floppy A (/dev/fd0)
6
2
3F0-3F7
Floppy B (/dev/fd1)
6
2
3F0-3F7
You may have noticed that the serial ports are called /dev/ttyS0, /dev/ttyS1, and so on in the list of devices. Yet they were called /dev/cua0, /dev/cua1, and so on when you configured the modem. The ports are the same (/dev/ttyS0 is the same as /dev/cua0); Linux just handles the devices differently. Don't get too confused about these device driver names yet. Just remember that /dev/cua refers to a modem port.
Network cards, SCSI adapters, sound boards, video cards, and other peripherals all must have unique IRQ, DMA, and I/O addresses, which can be difficult to arrange with a fully loaded system. For more information on available values, check your device or card installation manual for recommended values and potential conflicts.
SCSI Problems

SCSI is one of the most versatile interfaces, and it pays for that versatility in potential problems. Linux is usually good about reporting problems with SCSI devices, although the error messages may leave you wondering about the real cause of the problem.
The following list explains many of the common SCSI errors and their probable causes. Find the message that closely matches the error message Linux displays to determine your corrective steps.
SCSI device at all possible IDs
One or more devices is at the same SCSI ID as the controller. Check and change device IDs. Controllers should be ID 7.
Sense errors
This error is probably caused by bad termination. Check that both ends of the SCSI chain are terminated. If that is not the problem, the cable is likely at fault.
Timeout errors
This error is usually caused by a DMA, IRQ, or I/O address conflict. See the preceding section for more information.
SCSI adapter not detected
The BIOS is disabled or the kernel doesn't recognize the SCSI adapter. Check the drivers.
Cylinders Beyond 1024
Your disk has more than 1,024 cylinders, which the PC BIOS can't handle. Linux can use more than 1,024 cylinders, but it can't boot from a partition that extends across that cylinder boundary.
CD-ROM drive not recognized
Some CD-ROM drives require a CD in the drive to be recognized properly. Insert a CD and reboot.

Problems Booting Linux

If you have installed Linux and the system doesn't boot properly from your hard disk, it may be a problem with LILO or with the partitions. If you created a boot floppy disk, boot from that. If that boots without a problem, check the partition table by executing fdisk. Make sure the Linux partition is active. If it is and you still can't boot from the hard disk, boot from the floppy disk and run LILO again to configure the boot sector. See Chapter 4 for more information on LILO.
A problem will sometimes occur when Linux can't find the main Linux partition. Boot from the floppy disk and hold down the Shift or Ctrl key. This will produce a menu that enables you to specify the boot device explicitly. This problem can usually be corrected with LILO.
Booting, init, and Shutdown

The most basic tasks you face with a Linux system are starting the machine properly and shutting it down when you are finished. Although the two processes sound simple, there are several ways of accomplishing each task and several hazards associated with performing the processes incorrectly. UNIX, as a whole, doesn't like shocks to the filesystem, such as fast power-offs, so you must carefully shut down the system to preserve your information.
This chapter looks at the startup and shutdown procedures used with Linux and the init daemon. The init daemon is probably the most important process running on any Linux system. Understanding what init does and how to use it properly can help you on the way to getting the best performance from your Linux system.
Starting Linux

Starting the Linux system can be as simple as turning on the power switch of your PC. If Linux is configured to autoload, Linux will be up and running after a few seconds. Few systems are set up to run only Linux, though, and even fewer have it boot automatically when the power is turned on. Although automatic startup is convenient, many Linux users prefer to be able to choose which operating system to boot into (if other operating systems are loaded on the system) or to change the level of access to Linux.
You can start a Linux system by using a boot floppy disk or using LILO in one of several configurations. Each method has benefits and potential problems, which are discussed in the following sections.
Using LILO to Boot

LILO is the most common user method of booting a Linux system because it doesn't involve using a boot floppy disk. Chapter 4, "LILO," examined LILO in detail. LILO is a program that sits in the boot sector of a disk partition or the master boot record of the entire hard disk and points to the partition and location of the Linux kernel image.
If LILO is installed as a first-stage boot loader (meaning it boots Linux automatically), Linux starts to boot whenever the power is turned on. If you want to halt the boot process, you can use the Ctrl+Alt+Del sequence when the machine starts the boot sequence. (You must be careful when you hit Ctrl+Alt+Del, as you may reboot the machine by accident. Wait until you see the loader start its actions.) The Ctrl+Alt+Del sequence instructs LILO to pause and display the following prompt:

Boot:
From this boot prompt, you can tell LILO which operating system to load (DOS, Linux, OS/2, and so on). If you press the Tab key when the boot prompt is displayed, LILO displays a list of all partitions and operating systems it knows about. The operating system partitions must have their configuration information included in the LILO information. Providing this information is simply a matter of identifying the partition device name and a name for the operating system when you are creating the LILO configuration file. Chapter 4, "LILO," covered these steps.
Because LILO writes data to the disk drive that other operating systems cannot read, it is not always the best solution if you install and remove operating systems frequently from your hard disks. Whenever you make changes to the configuration of your Linux system or other partitions on the hard disk, update the LILO information by rerunning LILO.
Using a Boot Floppy Disk

If you don't want to rely on LILO (which modifies disk sectors and may cause problems when you use several operating systems or change operating systems frequently), you can use a boot floppy disk to start up Linux. A boot floppy disk is a single floppy disk that contains a complete copy of the Linux kernel and instructions for accessing the root partition on your hard drive. The boot floppy disk must be of the proper format to run on the first disk drive on your system (drive A in DOS terms). Linux cannot boot from a second (drive B) floppy disk drive.
In many ways, a boot floppy disk is the easiest and most versatile method of starting Linux. If, for example, you have your hard disk partitioned to contain both DOS and Linux, with DOS the normal boot partition, simply turning on your PC boots DOS without a hitch. If you want Linux to boot, you insert the boot floppy disk and start the machine. Linux boots from the floppy disk, and then accesses the hard drives as if it had booted from them.
If you are using a boot floppy disk to start Linux, be sure to update the kernel image on the floppy disk every time you make a change to the system that involves rebuilding the kernel. Keep in mind that you must rebuild the kernel almost every time you add devices or device drivers. Use the procedure outlined in the following paragraphs to update your existing floppy disk, or, even better, create a new floppy disk and save your current floppy disk for emergencies. You are not prompted to create a new boot floppy disk when you make changes to the kernel, so you must remember to perform this step.
To create a boot floppy disk, you need a blank, formatted, high-density floppy disk (1.44M or 1.2M, depending on the A drive on your system). Format the floppy disk under DOS to lay down the sector and track information properly for Linux to read. Some small kernels can fit on low-density floppy disks, but high-density drives are most likely to be used on your system because they are the standard. The high-density floppy disk can have information on it as well as the Linux kernel, but make sure you have enough disk space for the kernel image.
Some versions of Linux (such as Slackware) can create the boot floppy disk as part of the normal setup routine. If you are using a distribution that has a setup routine, try choosing the Configure option on the menu, follow through the prompts, and see whether you are prompted to create a boot floppy disk at the end. Alternatively, some distributions have a separate menu option for creating the boot floppy disk.
If you want to create the boot floppy disk manually, locate the Linux kernel on your system. Usually it is in the root directory. The kernel name changes depending on the version of Linux, but it is often called Image or vmlinux. Some versions of Linux store the kernel image in the /etc directory.
Some versions of Linux also store the kernel in a compressed format. The names of compressed kernels end in z, as in vmlinuz or vmlinux.z. A compressed kernel takes up less space on the hard disk or floppy disk, and it is decompressed when the Linux kernel boots. A compressed kernel takes a little longer to load than a kernel that isn't compressed, but because it is decompressed only when the system boots, the trade-off is usually beneficial (unless you have tons of empty disk space).
You should be able to find the kernel quite easily by watching the startup messages when you boot the system and noting the kernel name, and then using find or whereis to locate it. Much easier is to change to the root directory and look for a large file called Image or vmlinux. The file is owned by root and has only read permission in many distributions of Linux. For example, when you do a listing command (such as ls-l), you see an entry like the following:

-r-------- 1 root root 457700 Aug 10 13:52 vmlinuz
This entry shows a kernel image file of almost half a megabyte that is compressed. The date and time of the kernel match the last time you rebuilt the kernel or the time and date you installed Linux.
Once you have identified the kernel file, instruct Linux that the file is the root device and indicate which partition it is on by using the rdev command. For example, to set the root device to the kernel vmlinuz in the root directory of the partition /dev/sda3, you would issue the command

rdev /vmlinuz /dev/sda3
Because you must specify the path to the kernel completely, the leading slash is included to show the root directory.
If you issue the rdev command by itself, it displays the current partition of the root filesystem:

$rdev

/dev/sda3 /
You can use this command to check the current settings if you are not sure which partition is your root filesystem. (This chapter looks at the rdev command in a little more detail in a later section.)
After you set the root device, you can copy the kernel to your formatted floppy disk. Use the cp command and the device name of the floppy disk:

cp /vmlinuz /dev/fd0
Once the image file has been transferred, the floppy disk should be able to boot Linux. If it doesn't, either the image didn't transfer properly due to a lack of disk space or a corrupted disk sector, or there is a problem with the kernel image.


Creating and Using a Maintenance Disk

Every system should have a maintenance disk (also called an emergency boot disk) that you can use to boot the Linux system in case anything happens to the boot system (such as LILO). A maintenance disk is a combination boot and root disk that boots a complete Linux kernel independent of your hard disk installation. After you load the maintenance disk, you can use it to mount the hard disk and check for problems, or use one of the hard disk utilities to rebuild LILO or the kernel, depending on the problem with the drive.
To create a maintenance disk, you create a root filesystem on a floppy disk, copy essential tools to it, install LILO, and then make the disk bootable by copying the kernel. Perform this process every time you make a change to the Linux kernel so that your maintenance disk has the same kernel build. Keeping your maintenance disk up-to-date prevents hassles with utilities and devices.
You probably already have a set of maintenance disks in the pair of floppy disks you used to install Linux in the first place. Although these disks are not configured for your system, you can use them to load Linux and mount your hard drive. Many Linux setup procedures have a built-in routine to create boot floppy disks. You can use this routine to create the maintenance floppy disk.
If you have to boot off the maintenance floppy disk for any reason, mount the existing hard drive with the mount command. For example, if you are booting off your floppy disk and want to mount the partition /dev/sda2 (which wouldn't boot Linux for some reason), issue the command

mount -t ext2 /dev/sda2 /mnt
which mounts the hard drive partition under the directory /mnt. The directory must exist before you perform this operation, and it should be empty. The -t option specifies the file type. If your filesystem is not an extended filesystem, change the type.
Shutting Down Linux

The temptation to treat Linux like DOS can be overwhelming when you are ready to finish with your session. Simply turning off the power should shut down everything, right? Well, it does, but it also can completely corrupt all the contents of your hard disk partition, as well as lose any information you were just working on. Granted, that's a very rare and extreme case, but arbitrarily turning off the power to a Linux session is still a bad idea.
Linux manages the hard disk and user spaces in RAM, using i-node tables to maintain the disk information and a memory manager for user information. Linux writes any changes to the i-node tables to the disk drive every so often, but it maintains the RAM copies as the most recent because of RAM's greater speed. If you shut down the power before Linux writes any changes to the disk, the disk contents and the i-node tables written on the disk may not match, causing lost files and an incorrect list of what disk space is available. Even worse, if Linux was in the process of writing the i-node table or any other information at the moment the power is turned off, the write process is interrupted, and disk head crashes or bad sector information can result. The same principle applies to any processes that are running. If, for example, you were running a database reindex when you killed the power, the indexes and databases may be corrupted. Shutting down the Linux system properly makes sure that all processes write and close all open files and terminate cleanly.
There are two easy ways to shut down the Linux system properly. The easiest is to use the Ctrl+Alt+Del sequence. On many Linux versions, this keyboard combination issues a shutdown command that closes all the processes properly, and then reboots the machine. Linux essentially traps the Ctrl+Alt+Del sequence and uses it to shut down the machine. Not all versions of Linux support this sequence, though, so check your documentation carefully.
If your system doesn't trap Ctrl+Alt+Del and reboots the machine when you issue it without shutting down Linux properly, it's the same effect as turning off the power. Make sure your Linux version supports this command before you use it!
The other method of shutting down Linux is with the UNIX command

shutdown
When you issue the shutdown command, Linux starts to terminate all processes and then shuts down the kernel. The shutdown command displays several different messages, depending on the version of Linux, but all inform you of the process or check that you really want to shut down the system.
The shutdown command allows you to specify a time until shutdown, as well as an optional warning message to be displayed to all users logged in. The format of the command is

shutdown time message
As an example, this command

shutdown 15 'Backup Time!'
shuts down the system after 15 minutes and display the message "Backup Time!" to all users on the system, prompting them to log off. This command is handy when you enforce a policy of shutting down at specific intervals, either for maintenance or backups.
In most versions of Linux, the shutdown command accepts the -r option. This option causes the PC to reboot after the shutdown has occurred. You can use this option to reboot to another operating system or to restart Linux after making changes to the kernel or devices. You can use the -r option with a time or message, if you want. The command

shutdown -r 5
reboots the system after five minutes.
In most cases, using Ctrl+Alt+Del or the shutdown command results in the display of a number of status messages on the main console. When Linux has finished shutting down the system, you see the message

The system is halted
When this message appears on-screen, it is safe to shut off the system power or reboot the machine. Although it may seem a little strange to have to follow these extra steps, you will find that many high-end operating systems such as UNIX (and even Windows NT and Windows 95) require you to follow a specific shutdown procedure to prevent loss of information. Get in the habit!
Understanding the init Daemon

The init daemon is usually invoked as the last step in the booting of the Linux kernel. The init daemon is one of the most important Linux daemons because it creates processes for the rest of the system. The init daemon is executed when Linux starts and stays active until Linux is shut down. Understanding what init (and its linked utility telinit) does and how it controls the operating system is important to better administering the Linux system.
Both init and telinit use several configuration files to perform their tasks, so the following sections look at those files in detail, too. These files are closely involved in the starting and stopping of terminals and console sessions. The init program is usually kept in the /bin directory, although some versions of Linux keep it in /sbin. The same directories apply to the telinit utility. The configuration files are always kept in /etc, though.


Run Levels

When the init daemon is executed, it reads instructions from the file /etc/inittab, which is primarily used to start getty processes for terminals and other processes required by Linux. While examining the /etc/inittab file, init searches for an entry labeled initdefault, which sets the default initial run level of the system. If no initdefault level is defined in the /etc/inittab file, the system prompts for the level.
A run level is a particular set of processes ranging from a bare minimum for system administration only to a full operation supporting all configured devices. Run levels are defined by a number from zero to six. An additional superuser level (often called single-user level as only root can log in) is defined as s. The init daemon knows which processes are associated with each run level from information in the /etc/inittab file.
When you use the s run level to display the system in single-user mode, the /etc/inittab file is not read. Instead, the utility /bin/su is invoked for the system console (defined by /dev/console). The init process can save the current state of a system when instructed to change to single-user mode from a higher run level. With some versions of init, the current state of the system is saved in a file called /etc/ioctl.save by the program ioctl. When the console is restarted to a higher run level, the states in this file are restored. If no ioctl.save file is found, the default states are used.
When starting up into multiuser mode (run levels higher than single-user mode), the init daemon performs any entries identified by the instructions boot and bootwait in the /etc/inittab file. Following these instructions usually allows filesystems to be mounted. After these instructions are processed, the rest of the entries that match the selected run level are executed.
The run level of the system can be changed by a user with access to the commands that affect the level. This access is usually restricted to the system administrator for security reasons. You change the run level by using the utility program /etc/telinit (which is linked to /etc/init). The telinit utility is responsible for sending messages to the init daemon to alter the current run level to the requested new level. To alter the run level, add the required level (zero through six or s) to the telinit command. For example, the command

telinit 2
changes the run level to level two and causes init to reread the /etc/inittab file and execute all processes for that level or terminate those for higher levels. To drop into superuser (single-user) mode, use the s option:

telinit s
When switching to the superuser level, you can use either an uppercase or lowercase s. The telinit and init utilities can handle both cases.
You can specify a time delay for the change, in seconds, after the -t option. The command

telinit -t5 3
changes the run level to level three after five seconds. If no time is specified, Linux uses the default value of 20 seconds.
When you change the run level, init sends a SIGTERM warning signal to all processes that are not valid with the new run level. After sending the SIGTERM signal, init waits the specified number of seconds (or the default 20 seconds), and then terminates the process forcibly.
If a process started by init has spawned new processes that are not in the same process group, init doesn't terminate them when you change the run level. You must terminate these processes manually.

The /etc/inittab File

As mentioned previously, the /etc/inittab file is tied closely to the init daemon. Look at the /etc/inittab file on your system to understand which processes are started and which run level is invoked when Linux starts. Extracts from a sample /etc/inittab file show the processes involved in starting the system with init. The first section in the sample /etc/inittab file identifies the default run level, in this case level five:

id:5:initdefault:
The next section in the /etc/inittab file handles the system startup through the files in the /etc/rc.d directories:

si:S:sysinit:/etc/rc.d/rc.S
Following this section is a pointer to the file /etc/rc.d/rc.K, which is used when the system enters the single-user run level:

su:S:wait:/etc/rc.d/rc.K
Next is a pointer to the file /etc/rc.d/rc.M for when the system is started in multiuser level (any one of the levels one through six):

rc:123456:wait:/etc/rc.d/rc.M
The most common run level is five, which is the normal operating level for Linux in multiuser mode. Most installations seldom use the other levels, although they can be used in some circumstances to control access to peripherals. Run levels are best left as the system wants them to prevent problems. This means using run level s for superuser mode and run level five for general use.
Because Linux runs on PC machines, it can support the "three-fingered salute" or Ctrl+Alt+Del sequence. This sequence is not usually supported on PC UNIX systems, so a special instruction is mapped to the sequence in the /etc/inittab file:

ca::ctrlaltdel:/sbin/shutdown -t3 -rf now
When the Ctrl+Alt+Del sequence is intercepted, the system begins a shutdown as shown by the command at the end of the preceding line.
The /etc/inittab file then holds an instruction to start a getty process for each terminal and virtual screen on the system. This sample /etc/inittab file starts six virtual screens (tty1 through tty6) and two serial lines (ttyS0 and ttyS1):

c1:12345:respawn:/sbin/agetty 38400 tty1

c2:12345:respawn:/sbin/agetty 38400 tty2

c3:45:respawn:/sbin/agetty 38400 tty3

c4:45:respawn:/sbin/agetty 38400 tty4

c5:45:respawn:/sbin/agetty 38400 tty5

c6:456:respawn:/sbin/agetty 38400 tty6

s1:45:respawn:/sbin/agetty 19200 ttyS0

s2:45:respawn:/sbin/agetty 19200 ttyS1
The terminal and serial line instructions are examined in more detail in Chapter 11, "Terminals and term."
The lines in the /etc/inittab file follow a specific format. The format follows this pattern:

ID:runlevel:action:process
The ID is a one- or two-character string that uniquely identifies the entry. In most cases, this string corresponds to the device name, such as 1 for tty1, 2 for tty2, and so on. The runlevel decides which of the run levels the line applies to (varying from zero to six). If no entry is provided, then all run levels are supported. Multiple run levels may be identified in the field.
The action indicates the command to execute when init reads the line. The following items are all valid entries for the action field:
The boot action runs when inittab is first read.
The bootwait action runs when inittab is first read.
The initdefault action sets the initial run level.
The off action terminates the process if it is running.
The once action starts the process once.
The ondemand action always keeps the process running (the same as respawn).
The powerfail action executes when init gets a power fail signal.
The powerwait action executes when init gets a power fail signal.
The sysinit action executes before accessing the console.
The respawn action always keeps the process running.
The wait action starts the process once.
If init senses a powerfail condition (such as termination of power to the PC signaled by an Uninterruptible Power Supply) and the system was in multiuser mode, some special powerfail conditions are executed upon restart. These conditions usually check the filesystem for problems prior to bringing the system back up. The /etc/inittab file can contain specific instructions for these conditions, as shown in the following code:

# What to do when power fails (shutdown to single user).

pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING"

# If power is back before shutdown, cancel the running shutdown.

pg:0123456:powerokwait:/sbin/shutdown -c "THE POWER IS BACK"

# If power comes back in single user mode, return to multi user mode.

ps:S:powerokwait:/sbin/init 5
All these powerfail conditions assume that some device manages to send the powerfail signals to the init process. Special device drivers that interface with UPSs usually do this.
The init daemon doesn't terminate when it has finished reading /etc/inittab. It stays active and monitors the system for specific instructions to change the run level (from a telinit command). It is also responsible for watching all the processes it started, including the getty processes for terminals. Whenever a process init started (called a child process, with init as the parent process) is terminated for any reason, init records the event and a reason for the termination (if possible to identify) in the files /etc/utmp and /etc/wtmp.
Whenever init senses the termination of a a child process, a power fail signal, or a run level change, it rereads the /etc/inittab to check for instructions. You can make changes to the inittab file (using any ASCII editor) while the system is running, but the changes will not be effective until the system reboots or one of the reread conditions occurs. An alternative is to use the q argument to force init to reexamine the /etc/inittab file. To force a reread of the /etc/inittab file, issue the command

init q
The init process checks how many times it has to restart (respawn) a process. If a process must be restarted more than 10 times in a two minute period, init assumes that there is an error in the command line of /etc/inittab for that process and generates an error message on the system console. The init process then refuses to respawn that process for five minutes or until it's forced to restart by the superuser. This step is useful because it prevents the system from wasting CPU cycles when a typographic error was made in the /etc/inittab file.
Using the rdev Family

The rdev command is a utility not just for identifying the root device, as shown earlier in this chapter (it's used when creating a boot floppy disk), but for obtaining all kinds of information about your Linux system and making some configuration changes. The rdev utility can be cumbersome to use, and many administrators ignore it and its companion utilities completely.
If you use LILO to boot Linux, you can ignore all the rdev commands as these parameters are set in the LILO configuration. The only times you will need rdev is when you change kernels and want to make a boot floppy disk for emergency use, or you want to change the RAM disk size. If you don't use LILO, you may occasionally need to use the rdev commands, although it is rare that they will be necessary as the Linux setup procedures define most of these parameters for you. The exception is changes in RAM disk size.
When run by itself, rdev displays the currently defined root partition and directory:

$dev

/dev/sda3 /
In this example, /dev/sda3 (third partition on the first SCSI hard disk) is the current root partition. You can use rdev to change the root partition and point to the kernel image to be used by Linux by providing both parameters as arguments:

rdev /vmlinuz /dev/sda3
This command changes the kernel image used to vmlinuz in the root directory of the third partition. You usually perform this command only when you create an emergency floppy disk.
The rdev command has several options for changing the way it acts, as shown in the following list:
-h
Displays help
-r
Makes rdev act like the command ramsize (see below)
-R
Makes rdev act like the rootflags command (see below)
-s
Makes rdev act like the swapdev command (see below)
-v
Makes rdev act like the vidmode command (see below)
Although you can use these options to alter rdev's behavior, you can also use the following commands directly:
The ramsize command specifies the size of the RAM disk in kilobytes.
The rootflags command enables you to mount the root directory as read-only.
The swapdev command identifies the swap device.
The vidmode command specifies the video mode.
In order to change many of the parameters, you must specify an offset that indicates the decimal value of the kernel location with the rdev command, which is why many administrators don't like the command. To use rdev or one of the utilities in its family, you must calculate the offsets according to the following rules:
Offset 498
Root flags
Offset 504
RAM disk size
Offset 506
VGA mode
Offset 508
Root device
The rootflags command has many options, only one of which really works to enable you to mount the root directory as read-only. Because this feature is seldom (if ever) necessary, most administrators can effectively ignore the rootflags command. (If you are running off a CD-ROM or from a small hard drive that contains only the binaries, you may want to consider using rootflags, but because you can accomplish the same task using file permissions, there's not much need to use rootflags.)
The vidmode command (or rdev -v) lets you change the video mode. If you issue the vidmode command by itself with some versions of Linux, it displays the current settings. More recent versions (including the one on this book's CD-ROM) show a help screen:

$ vidmode

usage: rdev [ -rsv ] [ -o OFFSET ] [ IMAGE [ VALUE [ OFFSET ] ] ]

rdev /dev/fd0 (or rdev /linux, etc.) displays the current ROOT device

rdev /dev/fd0 /dev/hda2 sets ROOT to /dev/hda2

rdev -R /dev/fd0 1 set the ROOTFLAGS (readonly status)

rdev -s /dev/fd0 /dev/hda2 set the SWAP device

rdev -r /dev/fd0 627 set the RAMDISK size

rdev -v /dev/fd0 1 set the bootup VIDEOMODE

rdev -o N ... use the byte offset N

rootflags ... same as rdev -R

swapdev ... same as rdev -s

ramsize ... same as rdev -r

vidmode ... same as rdev -v

Note: video modes are: -3=Ask, -2=Extended, -1=NormalVga, 1=key1, 2=key2,...

use -R 1 to mount root readonly, -R 0 for read/write.
The legal values for vidmode are as follows:
-3
Prompt
-2
Extended VGA
-1
Normal VGA
0
The same as pressing 0 at the prompt
1
The same as pressing 1 at the prompt
2
The same as pressing 2 at the prompt
n
The same as pressing n at the prompt
You can change the video mode using one of these values on the command line or using a number or letter to emulate pressing a value at the prompt.
Logins

All access to a Linux system is through a user account. Every user account must be set up by the system administrator, with the sole exception of the root account (and some system accounts that users seldom, if ever, use). Although many Linux systems only have one user, that user should not use the root account for daily access. Most systems allow several users to gain access, either through multiple users on the main console, through a modem or network, or over hard-wired terminals. Knowing how to set up and manage users accounts and their associated directories and files is an important aspect of Linux system administration.
This chapter looks at the root login, which is the most powerful user account there is. From there, the chapter examines several aspects of setting up new user accounts on your Linux system. This chapter also looks at groups and how they are involved in the Linux system.
Understanding the Superuser Account

When you install the Linux software, one master login is created automatically. This login, called root, is known as the superuser because there is nothing the login can't access or do. Although most user accounts on a Linux system are set to prevent the user from accidentally destroying all the system files, for example, the root login can blow away the entire Linux operating system with one simple command. The root login has no limitations.
The sheer power of the root login can be addictive. When you log in as root you don't have to worry about file permissions, access rights, or software settings. You can do anything at anytime. This power is very attractive to newcomers to the operating system, who tend to do everything while logged in as root. It's only after the system has been damaged that the root login's problem becomes obvious—there are no safeguards! As a rule, you should only use the root login for system maintenance functions. Do not use the superuser account for daily usage!
The root login should be kept only for those purposes where you really need it. Change the login prompt of the root account to clearly show that you are logged in as root, and think twice about the commands you issue when you use that login. If you are on a stand-alone system and you destroy the entire filesystem, only you are inconvenienced. If you are on a multiuser system and insist on using root for common access, you will have several very mad users after you when you damage the operating system.
So after all those dire warnings, the first thing you should do on a new system is create a login for your normal daily usage. Set the root password to something other users of the system (if there are any) will not easily guess, and change the password frequently to prevent snooping.
You also can create special logins for system administration tasks that do not need wide-open access, such as tape backups. You can set a login to have root read-only access to the entire filesystem to decrease the potential for damage. This login lets you back up the system properly, but prevents you from erasing the kernel by accident. Similar special logins can be set up for e-mail access, gateways to the Internet, and so on. Think carefully about the permissions each task requires and create a special login for that task; your system will be much more secure and have less chance of accidental damage.
The most important thing to note is that the superuser account doesn't have to be called root, although this account is created automatically as root when Linux installs itself. In theory, this account can have any name, but the name root is almost always used. The superuser account is always defined as the account with a user ID number of zero. User ID numbers are defined in the /etc/passwd file.
Establishing User Accounts

Even if you are the only user on your Linux system, you should know about user accounts and managing users. You need to know how to establish a user account because you should have your own account (other than root) for your daily tasks. If your system lets others access the operating system, either directly or through a modem, you should create user accounts for everyone who wants access. You may also want a more generic guest account for friends who just want occasional access.
Every person using your Linux system should have their own unique user name and password. The only exception is a guest account or perhaps an account that accesses a specific application such as a read-only database. By keeping separate accounts for each user, your security is much tighter, and you have a better idea of who is accessing your system and what the user is doing. A one-to-one correspondence between users and accounts makes tracking activities much easier.
The file /etc/passwd contains all the information about user accounts. The /etc/passwd file should be owned only by root and should have its group ID set to zero (which usually indicates a root or system group, as defined in the /etc/group file). Set the permissions of the /etc/passwd file to allow write access by root only; all other accounts can have read access. (Groups and permissions are dealt with later in this section.) The lines in the /etc/passwd file are divided into a strict format:

username:password:user ID:group ID:comment:home directory:login command
To understand this format, look at a sample /etc/passwd file. The following /etc/passwd file is created when a Linux system is newly installed:

root::0:0:root:/root:/bin/bash

bin:*:1:1:bin:/bin:

daemon:*:2:2:daemon:/sbin:

adm:*:3:4:adm:/var/adm:

lp:*:4:7:lp:/var/spool/lpd:

sync:*:5:0:sync:/sbin:/bin/sync

shutdown:*:6:0:shutdown:/sbin:/sbin/shutdown

halt:*:7:0:halt:/sbin:/sbin/halt

mail:*:8:12:mail:/var/spool/mail:

news:*:9:13:news:/usr/lib/news:

uucp:*:10:14:uucp:/var/spool/uucppublic:

operator:*:11:0:operator:/root:/bin/bash

games:*:12:100:games:/usr/games:

man:*:13:15:man:/usr/man:

postmaster:*:14:12:postmaster:/var/spool/mail:/bin/bash

nobody:*:-1:100:nobody:/dev/null:

ftp:*:404:1::/home/ftp:/bin/bash
Each line in the /etc/passwd file is composed of seven fields separated by a colon. If nothing is to be entered in a field, the field is left blank, but the colons are retained to make sure each line has seven fields (which also means each line will have six colons). The seven fields (from left to right on each line) are as follows:
The user name is a unique identifier for the user.
The password is the user's password (encrypted).
The user ID (UID) is a unique number that identifies the user to the operating system.
The group ID (GID) is a unique number that identifies the user's group (for file permissions).
The comment is usually the user's real name, but sometimes it is a phone number, department, or other information.
The home directory is the directory in which the user is placed when he or she logs in.
The login command is the command executed when the user logs in; normally, this command starts a shell program.
You should know what each field does and how other programs on your Linux system use it. Note that this type of user file is used with almost every UNIX system in the world, so once you know it for Linux, you know it for most UNIX versions.
User Names

The user name is a single string, usually eight characters or less, that uniquely identifies each user. Because the user name is the basis of most communications between users and other machines, the user name you use (or assign to others) should be simple and obvious. Usually, this name is a permutation of the user's real name. A typical user name may be a combination of the user's first and last names, such as tparker or timp. A user name composed of the first initial and last name is fairly common in large networks.
Note that the characters in these examples are all lowercase. Case is important in Linux (as with all UNIX versions), so tparker and Tparker are two different logins. Because most Linux commands are lowercase, the convention is to also keep user names lowercase. Underscores, periods, numbers, and some special characters are allowed, but they should be avoided because they make login names look strange and can also cause problems for some applications.
Small systems, such as one comprised of a single machine, may use more familiar names, such as the user's first name. A small system may have users with the names tim, bill, yvonne, and so on. If two users have the same name, there must be some method to differentiate between the two (such as bill and billy).
A few users like to create cryptic user names that reflect their hobbies, nicknames, pets, lifestyle, or personality. You may find user names like vader, grumpy, wizard, and hoops. This type of naming is fine on small systems that are used by one or two users, but it quickly becomes awkward on larger systems where other users may not know their coworker's user names. On the whole, if more than a couple of friends use your system, discourage this type of user name.
Passwords

The system stores the user's encrypted password in the password field. This field is very sensitive to changes, and any modification to it can render the login useless until the system administrator performs a password change. Only the system administrator or the user can change the password by using the passwd command.
Some versions of UNIX do not keep the passwords in the /etc/passwd file because of potential security problems. If the password fields on your system are all set to x, then another file (called a shadow password file) is in use. However, all versions of Linux currently available do use this field by default. Systems running either Yellow Pages or NIS (Network Information Service), both of which rely on a central file of user names and passwords, do not use the password field. Few Linux systems use either YP or NIS, however, so you can ignore this distinction for the moment.
When a user logs in, the login program logically compares the password the user typed to a block of zeros, and then compares that result to the entry in the password field. If they match, the user is granted access. Any deviation causes login to refuse access.
You can use this field to restrict access to the system. If you want to prevent a login from ever being used for access, such as a system login like lp or sync, place an asterisk between the two colons for the password field. This asterisk restricts all access. In the sample /etc/passwd file shown previously, many system logins have an asterisk as their password, effectively blocking access.
You can also use this field to allow unrestricted access by leaving it blank. If no password entry exists (the field has nothing in it), anyone using the user name is granted access immediately, with no password requested. Do not leave passwords open unless you are using your Linux system for your own pleasure and have nothing of value on the filesystem.
Don't attempt to put a password directly in the password field using an editor. You cannot recreate the encryption method, and you'll end up locking the user account out. Then only the system administrator will be able to change the password and allow access.
User ID

Every user name has an associated, unique user ID. Linux uses the user ID, also called the UID, to identify everything associated with the user. The user ID is preferable to the user name because numbers are easier to work with than the characters in a name and take up less space. Linux tracks all processes started by a user, for example, by the user ID and not the user name. Some utilities translate the user ID to display the user name, but utilities generally examine the /etc/passwd file to match the UID to the name.
The user ID numbers are usually assigned in specific ranges. Most UNIX systems, for example, allocate the numbers from 0 to 99 for machine-specific logins and the user ID numbers from 100 and up for users. Using this model will make your system consistent with others. In the sample /etc/passwd file shown previously, you can see that root has a UID of 0, and the other system-created logins have larger numbers. The login nobody is a special login used for NFS (Network File System) and has a UID of -1, an invalid number. When you assign user ID numbers, assign them sequentially so that the first user is 100, the second 101, and so on.