I l@ve RuBoard Previous Section

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal featured on the cover of Essential System Administration, Third Edition, is an armadillo. This insect-eating mammal is native to South America and has spread through the southern United States. Unlike most insectivores, the armadillo has teeth-rootless pegs set far back in its mouth. These teeth allow it to supplement its diet of termites, scorpions, and other insects with snakes, poultry, fruit, and eggs.

The armadillo's name, "little armored thing," was given to it by the Spanish when they invaded the New World. This "armor" is an outer layer consisting of numerous bony plates with a horny covering. This shell is hinged at the middle of the back, allowing the front and hind sections freedom of movement. In some species, this covering extends over the face and tail as well as the torso and limbs.

Armadillos range in size from the great armadillo, at 5 feet in length, to the fairy armadillo, at 5 inches. The most common of the armadillos, the 9-banded armadillo, is about the size of a house cat.

Leanne Soylemez was the production editor and copyeditor for Essential System Administration, Third Edition. Sheryl Avruch, Jane Ellin, Colleen Gorman, and Darren Kelly provided quality control. Æleen Frisch wrote the index.

The cover image is a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

David Futato designed the interior layout. This book was converted to FrameMaker 5.5.6 with a format conversion tool created by Erik Ray, Jason McIntosh, Neil Walls, and Mike Sierra that uses Perl and XML technologies. The text font is Linotype Birka; the heading font is Adobe Myriad Condensed; and the code font is LucasFont's TheSans Mono Condensed. The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand 9 and Adobe Photoshop 6. The note and warning icons were drawn by Christopher Bing.

The book also still benefits from the work that Sheryl Avruch, Nicole Gipson, Seth Maislin, Kismet McDonough, Lenny Muellner, Kiersten Nauman, Dominic Newman, Clairemarie Fisher O'Leary, Chris Reilley, Mike Sierra, Ellen Siever, Mary Anne Weeks Mayo, Norm Walsh, and Frank Willison did on the second edition, and that Kismet McDonough and Ellie Cutler performed on the first edition. Edie Freedman designed the cover of the book, forever linking system administration and armadillos.

The online edition of this book was created by the Safari production group (John Chodacki, Becki Maisch, and Madeleine Newell) using a set of Frame-to-XML conversion and cleanup tools written and maintained by Erik Ray, Benn Salter, John Chodacki, and Jeff Liggett.
    I l@ve RuBoard Previous Section


I l@ve RuBoard

Dedication

For Frank Willison

"Part of the problem is passive-aggressive behavior, my pet peeve and bête noire, and I don't like it either. Everyone should get off their high horse, particularly if that horse is my bête noire. We all have pressures on us, and nobody's pressure is more important than anyone else's."

***

"Thanks also for not lending others your O'Reilly books. Let others buy them. Buyers respect their books. You seem to recognize that `lend' and `lose' are synonyms where books are concerned. If I had been prudent like you, I would still have Volume 3 (Cats-Dorc) of the Encyclopedia Britannica."
    I l@ve RuBoard


Appendix A. Administrative Shell Programming

The purpose of this appendix is to review major Bourne shell (sh) programming features. It is not intended as a comprehensive treatment of shell programming or of the features of the various shells. Rather, it will enable you to understand and modify the system administration scripts on your system, most of which are Bourne shell scripts (although this is slowly changing).

In the course of this appendix, we will look at many examples drawn from actual system scripts, as well as some other simple examples to illustrate basic features. Some of the latter examples use shell commands executed at the command prompt (although the corresponding commands could obviously appear just as easily in scripts).[1]

[1] Not all examples will necessarily run in every sh implementation.

With the exception of AIX and Linux, the Unix versions we are considering use the Bourne shell for system scripts. AIX uses the Korn shell (ksh), and Linux uses the Bourne-Again shell (bash). Linux system scripts also frequently use bash features that are not part of the standard shell. Since they are extensions to sh, however, the most important of these features are now described in this appendix.[2] When I mention bash features here, I am doing so in a descriptive sense only—not in an historical sense—in comparison to what is offered in the standard Bourne shell. The feature in question may also be present in other shells and may very well have originated in a shell other than bash.

[2] This discussion covers bash Version 2.04 or later.

The books UNIX is a Nutshell: System V Edition, by Arnold Robbins, and Learning the bash Shell, by Cameron Newham and Bill Rosenblatt (both published by O'Reilly & Associates) are excellent references for sh and bash, respectively.

Discussing Korn shell features is beyond the scope of this appendix; consult the book Learning the Korn Shell by Bill Rosenblatt and Arnold Robbins (O'Reilly & Associates) for a detailed discussion of this shell.

As much as possible, the examples in this appendix come from actual system scripts. Thus, while there are many useful techniques illustrated in the examples, they should not generally be viewed as recommendations of shell programming style, and many readers may quibble or disagree with them at some points.


A.1 Basic Syntax

This section reviews some basic syntactic features of the Bourne shell, in a somewhat arbitrary order.

Lines in shell scripts beginning with number signs are comments:

# Start or stop the lp scheduler

In fact, comments can begin anywhere on a line:

grep ':00*:' /etc/passwd       # Check for UID=0 accounts

The first line of a shell script usually looks like this:

#!/bin/sh

This identifies the shell that should run the script, in this case, the Bourne shell. The path location can vary.

NOTE

The best practice is to begin every shell script with a line identifying the shell to be used to run it. If this line is not present, /bin/sh is assumed.

The Bourne shell offers some syntactic flexibility over other shells. For example, quotes remain in effect across physical lines, as in this example we looked at in Chapter 7:

echo "*** Non-root UID=0 or GID=0 accounts:"
grep ':00*:' /etc/passwd | \
  awk -F: 'BEGIN        {n=0}
           $1!="root"   {print $0 ; n=1}
           END          {if (n==0) print "None found."}'

Note that the arguments to the awk command extend across three lines, which is much more readable than forcing them onto a single line.

A.1.1 I/O Redirection

Another construct you'll see quite often is this redirection of standard output to a file and of standard error to standard output (and thus to the same file):

/usr/lib/lpshut > /dev/null 2>&1

In this case the file is /dev/null, but the concept applies whether output goes to a real disk file, to /dev/console, or gets thrown out.

Note that standard output and error can also be redirected to separate destinations:

/sbin/rc.local  1>> boot.log  2> /dev/console

In general, the form n> file redirects file descriptor n to the specified file; file may also be replaced by a second file description, as in the form n1>&n2.

Some Bourne shells and bash support more complex I/O-redirection syntax. For example, the following command redirects all future standard input and all output to the system console (which is the target of the CONSOLE environment variable):

exec 0<> $CONSOLE 1>&0 2>&0

bash also offers additional I/O-redirection features. One of the most useful is illustrated in this example:

/etc/shutdown.local >| /var/adm/shutdown.log 2>&1

This command runs the specified script, placing all of its output into the indicated file even if the file already exists and the noclobber shell variable, which inhibits accidental overwriting of existing files, is set.

A.1.2 The dot Command

The so-called dot command—consisting of a single period—is used to run commands from a file in the same shell as the script itself. The file specified as a dot command's argument thus functions as an include file. For example, the following command executes the contents of /etc/rc.config as if they were part of the calling script:

. /etc/rc.config

Placing some commands in a separate file can have many purposes: isolating their function, allowing them to be used in multiple scripts, and so on.

bash provides source as a synonym for the dot command. The return command may be used to return to the calling script at any point within a script executed with the dot command.

A.1.3 Return Codes and the exit Command

On Unix systems, commands return a value of zero when they terminate normally and a nonzero value when they don't. The exit command may be used in scripts to return an explicit value; it takes the return value as its argument.

Here is a typical use of exit:

echo "configure network FAILED"
exit 1

This command, from a TCP/IP startup file, terminates the script and returns a non-zero value (indicating an error).

A.1.4 Compound Commands

The forms && and || are used to create conditional compound commands. When the shell encounters one of these operators, it checks the exit value of the command on the left of the operator before deciding whether to execute the command on the right. For &&, the second command is executed only if the first one completed successfully; for ||, the second command executes when the first one fails. Here is an example with &&:

grep chavez /etc/passwd && grep chavez /etc/group

If the string "chavez" is found in the password file, the same string is searched for in the group file; if it isn't found, the second command doesn't execute.

The two constructs can be used together:

/usr/local/cksecret && echo "Everything ok." || mail root < slog

If the script cksecret returns 0, a message is sent to standard output; otherwise, the contents of the slog file are mailed to root. The && has to come before the || for this to work correctly.

A.1.5 Command Substitution

Back quotes may be used to place the output of one command into a separate command. For example, this command defines the variable otty as the output of the stty command:

otty=`stty -g`

bash and some Bourne shells also support the following more readable syntax:

otty=$(stty -g)

A.1.6 Argument Symbols and Other $ Abbreviations

Bourne shell scripts can be passed arguments like any Unix command. The first nine arguments can be referred to by the abbreviations $1 through $9. The shift command is one way to access later arguments. Here is an example of how it works:

$ cat show_shift
#!/bin/sh
echo $1 $2 $3
shift
echo $1 $2 $3
$ show_shift a1 a2 a3 a4
a1 a2 a3
a2 a3 a4

After the shift command, all parameters are shifted one parameter position to the left (or down, depending on how you want to look at it), and their parameter numbers are reduced by one.

bash provides a simplified syntax for accessing arguments beyond the ninth: ${n}. Thus, echo ${12} would display the value of the twelfth argument.

$0 refers to the command or script name, as in this example:

restart)
  $0 stop && $0 start
  ;;

These lines are from a boot script. They are part of a case statement in which the various options correspond to possible arguments that may be passed to the script. In this case, when the script argument is "restart", it calls itself with the argument "stop" and then calls itself again with the argument "start", provided that the first command was successful.

The form $# is a shorthand for the number of arguments. Thus, for the show_shift command in the previous example, $# was 4 before the shift command was executed and 3 afterwards.

There are two shorthand forms for all the arguments passed to a script: $@ and $*. $@ keeps the individual arguments as separate entities; $* merges them into a single item. Quoting the two of them illustrates this clearly:

"$*" = "$1 $2 $3 $4 ... $n"
"$@" = "$1" "$2" "$3" "$4" ... "$n"

You'll usually see the $@ form in system scripts.

There are a few other dollar-sign abbreviations that appear from time to time. Although they're not related to script arguments, I'll list them here:

$?

Exit status of previous command

$$

PID of this shell's process

$!

PID of the most recently started background job.

We'll see examples of some of these later in this appendix.

A.1.7 Variable Substitution

Shell scripts can also define variables, using the same syntax as environment variables:

name=value     No spaces allowed around the = sign.

Variables are dereferenced by putting a dollar sign in front of their name: $name. The variable name may be surrounded with braces to protect it from surrounding text. For example:

$ cat braces
#!/bin/sh
item=aaaa
item1=bbbb
echo $item1 ${item}1
$ braces
bbbb aaaa1

The first command displays the value of the variable item1, while the second command displays the value of the variable item, followed by a 1.

There are more complex ways of conditionally substituting variable values. They are summarized in Table A-1.

Table A-1. Conditional variable substitution

Return Value (Action Taken)

Form

If var is set[3]

If var is unset

${var-string}

$var

string

${var+string}

string

null

${var=string}

$var

string (set var=string)

${var?string}

$var

(display var:string only)

[3] "Set" means "defined," regardless of value (i.e., even if null).

Here are some examples:

$ name=rachel                        Assign value to variable name.
$ echo ${name-tatiana}               name is set, so use its value.
rachel
$ echo ${name2-tatiana}              name2 is unset, so use "tatiana".
tatiana
$ echo ${name=tatiana}               name is set, so use it.
rachel
$ echo ${n2=tatiana}; echo $n2       n2 is unset, so use "tatiana" . . .
tatiana
tatiana                               . . . and give n2 that value too:
$ echo ${name+tatiana}               name is set, so use "tatiana".
tatiana
$ echo name3=${name3+tatiana}        name3 is unset, so return nothing.
name3=
$ name4=${name3?"no name given"}     name3 is unset, so display message . . .
name3: no name given
$ echo name4=$name4                   . . . note name4 is not set.
name4=
$ dir=${name-`pwd`}; echo $dir       name is set, so use it (pwd not run).
rachel
$ dir=${name3-`pwd`}; echo $dir      name3 is unset, so set dir to `pwd`.
/home/chavez

As the final two examples indicate, commands can be included in the string, and they will be executed only if that portion of the construct is actually used.

A.1.7.1 bash variable substitution extensions

The bash shell and some Bourne shell implementations provide additional variable substitution possibilities:

  • Placing a colon before the operator character in the various items in Table A-1 tests whether the variable is set to a non-null value. Thus, echo ${var:-apple} displays the value of variable var if it is set to something other than an empty string (null value); it displays "apple" otherwise.

  • The form ${var:offset:length} may be used to extract substrings from a variable. offset indicates which character to start with (numbering begins at 0); if offset is negative, character counting begins from the end of the string (e.g., -1 starts extracting at the penultimate character). length indicates how many characters to extract, and it is optional; if it is omitted, all remaining characters are extracted. It must be greater than zero.

    Here are some examples:

    $ names="applepearplum"
$ echo ${names:5}
pearplum
$ echo ${names:5:4}
pear
$ echo ${names:(-4):4}      Negative numbers must be parenthesized to
plum                           avoid confusion with the :- operator.

  • The form ${#var} may be used to determine the length of the specified variable's value. For example, ${#names} is 13.

  • The form ${var#pattern} may be used to remove substrings from a variable, returning the remaining string. The following commands illustrate its use:

    $ names="applepearplum"
$ echo ${names#apple}
pearplum
$ echo ${names#a*p}       The pattern can include wildcards.
       plepearplum
$ echo ${names#pear}      Patterns only match the beginning of the string.
applepearplum

    Note that the pattern must match the beginning of the string.

    There are several variations on this form: ${var##pattern}, ${var%pattern} and ${var%%pattern}. The number sign says to match the beginning of the string, and the percent sign says to match the end of the string. The single character forms remove the shortest matching substring, and the double character forms remove the longest matching substring, as in these examples:

    $ echo ${names##a*p}    Remove longest match.
       lum
$ echo ${names%%e*m}
appl

    Here is a real-world example:

    rex="[0-9][0-9]"
for i in $prerc/K${rex}*; do
  service=${i#*/K$rex}           # extract service name
  ...
done

    This loop runs over the K-file boot scripts in whatever directory prerc resolves to. For each script, the variable service is set to the name of the facility being started by removing the initial path and Knn portion from the variable i.

  • The preceding syntax can be extended to perform general search-and-replace operations within strings, using constructs of the form: ${var/pattern/repstr}. This form replaces the longest string matching the pattern with repstr. If the initial slash is replaced by two slashes, all matching substrings are replaced. If repstr is null, the matching substrings are simply deleted.

    By default, matching occurs anywhere within the string. Precede the pattern with a number sign or percent sign to force matches to be at the beginning/end of the string.

    Here are some examples:

    $ names="applepearplum"
$ echo ${names/p/X}
aXplepearplum
$ echo ${names//p/X}
aXXleXearXlum
$ echo ${names/%plum/kumquat}
applepearkumquat

    You can do such pattern matching and replacement on the script argument list by using @ as the variable name.

A.1.8 Variable Double Dereferencing

It's very common to come across code like this:

netdev="NETDEV_"
iconfig="IFCONFIG_"

# Set up environment variables for each network device
. /etc/rc.config

num=0
while [ $num -le $NUM_NETDEVS ]; do
   curr_dev=`eval echo $netdev$num`          # NETDEV_n
   eval device=\$$curr_dev                   # value of NETDEV_n
   if [ "$device" != '' ]; then
      curr_opts=`eval echo $iconfig$num`     # IFCONFIG_n
      eval options=\$$curr_opts              # value of IFCONFIG_n
      /sbin/ifconfig $device $options up
   fi
   num=`expr $num + 1`
done

This script fragment initializes all the network interfaces on a system. The device names are stored in a series of environment variables named NETDEV_0, NETDEV_1, and so on, and the corresponding ifconfig options are stored in IFCONFIG_n. The while loop configures each interface in turn. The variable num holds the number of the current interface, and the variables netdev and iconfig hold the beginning part of the environment variable names. The value of the proper environment variable is extracted into the variables device and options (which are used in the ifconfig command) via a two-step process: for the NETDEV case, the name of the environment variable is constructed first and saved in the variable curr_dev. Then curr_dev is itself dereferenced, and its value—which is the value stored in NETDEV_n—is assigned to the variable device. If you've ever wondered how to get to the value of the value of variable, this is one way.

Here is a similar example from a Linux system:

. /etc/rc.config
locale_vars="\
  LANG       \
  LC_ALL     \
  ...        \
  LC_MONETARY"

for var in $locale_vars; do     Loop over locale-related environment variables.
  if eval test -z "\$$var"      Is the variable's value  undefined or null?
  then
     eval $var="\$RC_$var"      If so, set its value to the same RC_ variable.
     export $var
  fi
done

Consider the first trip through the loop. The loop variable var is set to LANG. If the LANG environment variable is not set, then LANG's value is set to that of RC_LANG variable (defined in /etc/rc.config) via the second eval command, and the environment variable is exported.


A.2 The if Statement

In this section, we begin looking at Bourne shell control structures: programming features seldom used on the command line. The first construct we will consider is if, used for conditional command execution. Here is the simplest syntax of an if statement and a simple if example:

if condition
then
   commands
fi

if test -x /sbin/sendmail ; then
   /sbin/sendmail $SENDMAIL_OPTIONS
fi

The if command runs the commands in condition. If they return a true value (zero exit status), the commands are executed; on a false, nonzero status, the script jumps to the command after fi.

The preceding example uses the test command to check for the file /sbin/sendmail and starts the daemon if it's present and executable. We'll look at constructing conditions more closely a little later. For now, notice the placement of the then command. then must appear to the shell as a separate command, or you'll get an error. So it must be on a new line after the if command, or it must be separated from the if command by a semicolon. The same rules hold true for the fi command that ends the if construct.

There are more complex forms of if:

strings /vmunix | grep Unix > /tmp/motd
i=`head -1 /etc/motd | grep -c Unix`
if [ $i -eq 0 ]
then
   cat /etc/motd >>/tmp/motd
else
   tail +2 /etc/motd >>/tmp/motd
fi
mv /tmp/motd /etc/motd

This example illustrates the if-then-else construct. It updates the Unix version string in the message-of-the-day file. First, it gets the current Unix version string out of the kernel file /vmunix and puts it in the file /tmp/motd. Then, it checks whether the string "Unix" appears in the first line of /etc/motd. If it doesn't, the entire contents of /etc/motd are appended to /tmp/motd by the tail command. Otherwise—when "Unix" does appear in the first line of /etc/motd—all but its first two lines are appended to /tmp/motd. Finally, the new message file replaces the current one.

Here is an example of the most complex form of if:

set `who -r`                           Determine previous run level.
if [ "$9" = "S" ]                      Previous level was single-user mode.
then
   echo "The system is coming up."
elif [ "$7" = "2" ]; then              Target  run level is level 2.
   echo "Changing to state 2."
else
   echo "Changing to state 3."
fi

The elif command allows if statements to be chained together. It functions as an else for the current if and as the beginning of a new if. The final else covers the case of all false conditions and ends the entire chain.

A.2.1 The test Command (a.k.a. [ )

The most common way to construct a condition for an if command is with the test command. It has two forms:

test condition
[ condition ]

test evaluates condition and returns 0 or 1, depending on whether the condition is true (0) or false (1). (This polarity matches up with if's sense of true and false.)

The open bracket ([) command is a link to test and works in exactly the same way. It makes for more readable scripts, so you'll seldom see test. If the [ form is used, a final closed bracket (]) is included to keep test from complaining. Note that there must be spaces after [ and before ].

Table A-2 lists the various options and operators that may be used to construct conditions with test and [.

Table A-2. Constructing conditions

Construct

Meaning

-s file

File has greater than 0 length.

-r file

File is readable.

-w file

File is writable.

-x file

File/directory is executable.

-f file

File exists and is a regular file.

-d file

File is a directory.

-c file

File is a character special file.

-b file

File is a block special file.

-p file

File is a named pipe.

-u file

File has SETUID bit set.

-g file

File has SETGID bit set.

-k file

File has sticky bit set.

-t n

File descriptor n refers to a terminal.

-e file

File exists.

-O file[a]

You own the file.

-Gfile[a]

Your group owns the file.

-L file[a]

File is a symbolic link.

-S file[a]

File is a socket.

-N file[a]

File has been modified since it was last read.

file1 -effile2[a]

Files reside on the same device and refer to the same inode number.

file1 -otfile2[a]

First file is older than second file.

file1 -ntfile2[a]

First file is newer than second file.

-z string

String's length is 0.

-n string

String's length is greater than 0.

string1 =string2

The two strings are identical.

string1 !=string2

The two strings are different.

string

String is not null.

string1>string2[a]

First string is lexically before second string.

string1<string2[a]

First string is lexically after second string.

int1-eq int2

The two integers are equal.

int1 -ne int2

The two integers are not equal.

int1 -gt int2

int1 is greater than int2.

int1 -ge int2

int1 is greater than or equal to int2.

int1 -lt int2

int1 is less than int2.

int1 -le int2

int1 is less than or equal to int2.

! condition

NOT logical operator: negates the condition.

cond1 -a cond2

AND logical operator: returns true only if both conditions are true.

cond1 -o cond2

OR logical operator: returns true if either condition is true.

( )

Used for grouping conditions.

[a] This item is an extension available in only some shell implementations.

Many of the items in Table A-2 require quoting to protect them from the shell (as we'll see).

Here are some simple examples:

if [ "$9" = "S" ]             If the 9th argument is S
if [ -s /etc/ptmp ]           If /etc/ptmp is not empty
if [ $# -lt 4 ]               If the number of arguments is  < 4
if [ ! -f /etc/.fsckask ]     If the plain file /etc/.fcskask does not exist
if [ $? -eq 0 ]               If the last command succeeded
if [ $? -ne 0 ]               If the last command failed

Here are some examples placed in context:

# get pid of lpsched
pid=`/bin/ps -e | grep ' lpsched$' | sed -e 's/^ *//' -e 's/ .*//'`
if [ $(pid) != "" ]           If we found an lpsched process ...
then
   /bin/kill $(pid)           ... kill it.
fi

if [ $lx = autobootx ]        If script  argument was "autoboot",
  run fsck
fi

if [ -d /etc/rc0.d ]          If there is a directory named /etc/rc0.d
then
   run the K files
fi

if [ -x /sbin/inetd ]; then   If the file /sbin/inetd is executable . . .
   /sbin/inetd                 . . . start the daemon
   echo inetd started
fi

if [ "$(BOOT)" = "yes" -a -d /etc/rc0.d ]
then                          If this is a boot and there is an rc0.d directory
   Run the files in /etc/rc0.d
fi

Note that constructs such as the following are used to prevent errors from occurring when a script's expected argument turns out to be null:

if [ $lx = autobootx ]

There are, of course, other ways of handling this contingency, but this approach is quite common in system scripts, especially older ones.

Here's a tricky one; try to figure out what this does:

interface_names="`echo /etc/dhcp.*[0-9] 2>/dev/null`"
if [ "$interface_names" != '/etc/dhcp.*[0-9]' ]; then
  Configure the network interfaces with DHCP
fi

A common mistake to make is to think the interface_name must always be the same as the filename string. The key here is to notice that the second operand to the not-equal operator in the if condition is a literal value: specifically, a string of characters and not a wildcarded filename. If there are any files of the form dhcp.xxxn in /etc (where xxx is a string and n is a number), the echo command returns the list of filenames. Otherwise, the literal string "/etc/dhcp.*[0-9]" is returned and becomes the value of interface_names.

The if command figures out which of these has happened. If interface_names has any value other than the literal wildcard string, the variable can be assumed to contain a list of filenames to be processed. On the other hand, if the variable holds only the wildcard string, then no files were found, and nothing needs to be done, so the commands in the body of the if block are skipped.


A.3 Other Control Structures

This section describes other important Bourne shell and bash control structures.

A.3.1 The while and until Commands

The while statement is one way to create a loop. It has two forms:

while condition
do
   commands
done

until condition
do
   commands
done

In the while form, the commands are executed until the condition becomes false. In the until form, they are executed until the condition becomes true. Here is an example of while:

cat /etc/fstab |
while read DEVICE MOUNT_DIR READONLY FS DUMMY1 DUMMY2
do
  fsck (if required) and mount the device
done

This loop takes each line of /etc/fstab in turn (sent to it via cat) and performs an appropriate action for the corresponding device. The while loop will end when read (described later) returns a nonzero status, indicating an end-of-file.

Here is another very similar example, taken from a recent Linux system:

while read des fs type rest; do
  case "$fs" in
    /) break;;
    *)      ;;
  esac
done < /etc/fstab
if [ -e "$des" -a "$type" != "resiserfs" ]
then
  run fsck
fi

Note that the input to the while loop is provided via I/O redirection following the done statement.

A.3.2 The case Command

The case command is a way to perform a branching operation. Here is its syntax:

case str in
   pattern_1)
     commands
     ;;

   pattern_2)
     commands
     ;;
   ...
   pattern_n)
     commands
     ;;

   *)
     commands
     ;;
esac

The value in str is compared against each of the patterns. The corresponding commands are executed for the first match that is found. The double semicolons are used to end each section. Wildcards are allowed in the patterns, and a pattern consisting of a single asterisk can serve as a default if no other pattern is matched; it must be placed at the end of the case command.

Here is an example of the case command:

/etc/fsck -p >/dev/console
case $? in                     Select action based on fsck return value.
  0)
    date >/dev/console
    ;;
  2)
    exit 1
    ;;
  4)
    /sbin/reboot -n
    ;;
  *)
    echo "Unknown error in reboot" > /dev/console
    exit 1
    ;;
esac

In this example, different commands are run depending on the return value from fsck.

Another typical use of case is found in the files in /etc/init.d on systems with System V-style boot scripts. Here is an abbreviated example:

#! /bin/sh
# Start or stop the lp scheduler

case "$1" in
  'start')
     /usr/lib/lpsched # and other commands
     ;;

  'stop')
     /usr/lib/lpshut > /dev/null 2>&1
     ;;

  'restart')
     $0 stop && $0 start
     ;;

  *)
     echo "usage: $0 {start|stop}"
     ;;
esac

This script takes different actions depending on the keyword specified as its argument. The argument it gets at boot time depends on whether it is invoked as an S-file or a K-file (as we noted in Chapter 4).

A.3.3 The for Command

The for command is another way to create loops. Here is its syntax:

for var [ in list ]
do
   commands
done

If a list is included, the variable var is set to each value in turn, and the command in the loop are executed. If no list of values is specified, $@ (all script arguments) is used.

Here is an example:

for d in /tmp /usr/tmp /chem/tmp ; do
   find $d ! -name tmp -type d -exec rmdir {} \;
done

This loop removes empty subdirectories from under /tmp, /usr/tmp, and /chem/tmp in turn, while not removing those directories themselves (via ! -name tmp—of course, it won't remove /tmp/tmp either).

A.3.3.1 The bash arithmetic for loop

bash also offers an arithmetic-style for loop, with the following syntax:

for (( start ; test ; incr )) ; do
   commands
done

start is an expression evaluated when the loop starts, test is an expression evaluated at the end of each loop iteration, and incr is an expression evaluated whenever the test condition is false. The loop terminates when the test condition is true.

Here is a simple example:

for (( i=1 ; i<10 ; i++ )); do
   echo $i
done

This loop displays the numbers 0 through 9.

A.3.4 The Null Command

Occasionally, you'll run across a command consisting of just a colon:

:

This null command is typically used when all the work is done in the control statement, and the body of the loop is empty.

Sometimes this command is used as a comment character (since its arguments will be ignored), as in this ancient example:

: attempt to ship remaining files
uucico -r

However, this practice is not recommended, because a line such as the following:

: Hourly cleanup script @(#)cleanup.hourly 2/4/90

(part of which was produced by a source-code control system) produces an error:

./cleanup.hourly: syntax error at line 2: `(' unexpected

This is because syntax checking is still done on the arguments to the null command.


A.4 Getting Input: The read Command

The read command reads one line from standard input and assigns the next word in the line to each successive variable specified as its arguments; extra words are assigned to its final argument. For example, these commands:

cat file.dat | \
while read x y z
do
   echo $x $y $z
done

produce output like this:

a b c
d e f
...

read can be used either for reading sequentially through a file (as in the earlier example with while) or for getting runtime input from the user. Here is an example using read for command input:

echo "fsck all disks? [y] \c"
read ans < /dev/console

A.4.1 The bash select command

bash provides the select command for prompting the user to select an item from a menu, as in this example:

$ cat choose.bash
#!/bin/bash

PS3="Choose an operating system: "
select os in "aix" "hp-ux" "solaris" "tru64" "linux" "freebsd"
do                                Loop until a valid choice is entered.
  if [ $os ]; then
    echo You chose $os which was choice number $REPLY
    break
  else
    echo -e "\nInvalid choice -- try again.\n"
  fi
done
$ choose.bash
1) aix
2) hp-ux
3) solaris
4) tru64
5) linux
6) freebsd
Choose an operating system: 2
You chose hp-ux which was choice number 2

This code fragment also illustrates the bash echo command's -e option, which allows you to include backslash escape sequences such as \n.


A.5 Other Useful Commands

This section briefly describes other commands that you may encounter in system scripts.

A.5.1 set

The set command sets the values of $1 through $n to the words given as its arguments. It is often used with a backquoted command to assign the argument identifiers to the command's output. Here is an example of its use:

$ who -r
.  run-level 2  Aug 21 16:58   2   0    S
$ set `who -r`
$ echo $6
16:58

The unset command may be used to remove a defined variable.

A.5.2 eval

The eval command executes its argument as a shell command. It is used to execute commands generated by multiple levels of indirection. Here is a silly example:

$ a=c; b=m; c=d; cmd=date
$ echo $a$b$c
cmd
$ eval $`echo $a$b$c`
Sun Jun  3 19:37:30 EDT 2001

Here is a real example that we looked at in Chapter 12:

$ eval `tset -sQ -m ":?vt100"`

This eval command runs the commands generated by tset -s. As we say, they are used to set the TERM and TERMCAP environment variables.

The command eval resize provides a similar example for xterm windows.

A.5.3 printf

The printf command is used to produce formatted output strings, and you will occasionally see it used in system scripts. It takes two arguments: a format-specification string and a list of items to be printed using that format. Here is an example command used to create a record in a printer accounting file:

# pages=21; host=hamlet; user=chavez
# printf '%7.2f\t%s:%s\n' "$pages" "$host" "$user"
   21.00       hamlet:chavez

This command creates a line in which the number of pages is printed as a floating point number containing two decimal places, followed by a tab and then the hostname and username joined by a colon.

Format specification strings are comprised of field definitions and literal characters, and each successive item in the print list is formatted according to the corresponding field in the format string. In our example, %7.2f and %s (twice) were the field definitions, and the tab (\t), colon, and newline character (\n) were literal characters.

Field definitions always begin with a percent sign. Their simplest syntax is:

%n[.m]z

n indicates the minimum width of the field, m indicates the number of decimal places (if applicable), and z is a code letter indicating the type of field data. The most important codes are d for signed integer, f for floating point, c for the first character of the argument, s for a character string and x or X for a hexadecimal number (depending on whether you want the alphabetic digits to appear in lowercase or uppercase). A percent sign is specified with %%.

At output time, field widths are automatically expanded when more space is needed, and output that is smaller than the specified width is padded on the left.

The printf command also allows some optional flags to be placed between the percent sign and the field width:

  • The minus-sign flag tells the command to pad the output on the right rather than the left (in other words, make the field left-aligned rather than right-aligned).

  • The plus-sign flag indicates that positive numbers should be preceded by an explicit plus sign. The space flag similarly indicates that positive numbers should be preceded by a space. These flags are useful for creating columns of aligned numbers regardless of sign (the default is not to place any character in front of a positive number). Note that this is an issue only when items are left-aligned.

  • The 0 flag indicates that zeros should be used for padding instead of blanks.

Here are some examples illustrating some of these flags:

# n=27; n1=-23
# printf '*%7.1f*  *%-7.1f* \n' $n $n
*   27.0*  *27.0   *
# printf '%-5.1f\n%-5.1f\n%-+5.1f\n%- 5.1f\n' $n $n1 $n $n
27.0
-23.0
+27.0
 27.0

A.5.4 expr

The expr command is used to evaluate various expressions. It has a lot of uses, but one common one in shell scripts is integer arithmetic. Here is a very simple example of its use in this mode:

$ cat count_to_5
#!/bin/sh
i=1
while [ $i -le 5 ] ; do
  echo $i
  i=`expr $i + 1`           # add one to i
done
$ count_to_5
1
2
3
4
5

See the manual page for full details on expr.

A.5.4.1 bash integer arithmetic

Integer arithmetic is included within the bash shell (so we can hope that constructions like the preceding will eventually go away). Here are some simple examples:

$ echo $(( 5+8/2-1 ))
8
$ a='1+2'; echo $a
1+2
$ let a='1+2'; echo $a
3
$ declare -i a; a='1+2'; echo $a
3

The first command illustrates the $(( )) operator, which forces the enclosed expression to be interpreted as integer arithmetic. Note that the usual operator precedence rules apply.

The second command illustrates that simply constructing an integer expression is not sufficient for it to be evaluated. You must use the $(( )) operator, precede the variable with let, or declare the variable to be of type integer (indicated by -i). The declare command may also be used to specify other variable types (see the documentation for details).

Table A-3 lists the supported arithmetic operators.

Table A-3. bash integer operators

Math operator

Meaning

Bitwise operator

Meaning

Logical operator

Meaning

+

add

>>

shift right

&&

logical AND

-

subtract

<<

shift left

||

logical OR

*

multiply

&

bitwise AND

==

equals

/

divide

|

bitwise OR

!=

not equals

%

modulus

~

bitwise NOT

<, <=

less than (or =)

**

exponentiation

^

bitwise XOR

>, >=

greater than (or =)

++

increment

!

logical NOT

--

decrement

c?t:f

conditional assignment

A few notes on these operators:

  • In general, the operators have the same meanings and precedence as they do in C. Parentheses should be used for explicit grouping.

  • The increment and decrement operators (++ and --) may either precede or follow the variable to which they are applied: var++ or ++var. Their placement determines whether the variable is modified before or after it is used.

  • The conditional assignment operator tests the condition (c), returning the value t if it is true or f if it is false.

  • Finally, the unary and bitwise operators can precede the equal sign in an assignment statement. For example, this statement adds three to the current value of counter:

    counter += 3

  • Note that only integer values are returned by integer expressions. Thus, 5 / 10 = 0.

A.5.4.2 bash arrays

The bash shell also supports array variables. They are not very prevalent in system scripts at present, so we will present just a brief overview of their use via some examples:

$ a=(aaa bbb [5]=eee ddd)                Define an array and some values.
$ echo ${a[4]} ${a[5]}
ddd eee
$ echo ${a[3]:-undefined}
undefined                                Arrays can have "holes": undefined elements.
$ a=(x y z); echo ${a[4]:-undefined}
undefined                                Redefining an array replaces all elements.
$ for i in ${a[@]}; do                   Loop over array elements.
> echo $i; done
x
y
z
$ echo ${#a[@]}                          Number of non-null elements in array a.
3

See the bash documentation for more information about arrays.


A.6 Shell Functions

Bourne shell scripts can define functions. Functions have all the same syntactic features as the scripts themselves, including their own arguments. Within a function, the argument and other shorthand forms refer to its own arguments.

The basic function syntax is:

name (  )
{
   commands
}

Here is a sample function from an AIX system, followed by an example of its use:

sserv(  )
{
# sserv: function to start a server
# args: $1=daemon pathname; $2!="" means use startsrc
#
if [ $# = 0 ] ; then
  echo "sserv: server name required."; return 1
fi
if [ ! -x $1 ] ; then return 1 ; fi
if [ -n "$2" ] ; then
   startsrc -s `basename $1`
else
$1
fi
}

...

sserv /sbin/syslogd $USE_SRC

The sserv function starts a server process on an AIX system, either conventionally from the command line or via the startsrc command (which uses the system resource controller subsystem, a general server management facility). The pathname of the server to start is specified as sserv's first argument, and whether to use startsrc is specified by the second argument (any non-null value uses it).

The function begins by making sure it was passed one argument; the function exits this is not the case. Note that return is used instead of exit in functions. Then the function makes sure the pathname it was passed is executable, and then finally it starts the daemon.

The example invocation of sserv uses an environment variable USE_SRC as its second argument. If USE_SRC is defined, then startsrc will be used; otherwise, only one argument will be passed to sserv.

A.6.1 bash Local Variables

bash functions may define local variables—variables whose scope is limited to the function and have no meaning in or effect on the script as a whole—via its local command, which takes the desired variable names as its arguments. Note also that any variables declared within a function are automatically local variables.


Chapter 1. Introduction to System Administration

The traditional way to begin a book like this is to provide a list of system administration tasks—I've done it several times myself at this point. Nevertheless, it's important to remember that you have to take such lists with a grain of salt. Inevitably, they leave out many intangibles, the sorts of things that require lots of time, energy, or knowledge, but never make it into job descriptions. Such lists also tend to suggest that system management has some kind of coherence across the vastly different environments in which people find themselves responsible for computers. There are similarities, of course, but what is important on one system won't necessarily be important on another system at another site or on the same system at a different time. Similarly, systems that are very different may have similar system management needs, while nearly identical systems in different environments might have very different needs.

But now to the list. In lieu of an idealized list, I offer the following table showing how I spent most of my time in my first job as full-time system administrator (I managed several central systems driving numerous CAD/CAM workstations at a Fortune 500 company) and how these activities have morphed in the intervening two decades.

Table 1-1. Typical system administration tasks

Then: early 1980s

Now: early 2000s

Adding new users.

I still do it, but it's automated, and I only have to add a user once for the entire network. Converting to LDAP did take a lot of time, though.

Adding toner to electrostatic plotters.

Printers need a lot less attention—just clearing the occasional paper jam—but I still get my hands dirty changing those inkjet tanks.

Doing backups to tape.

Backups are still high priority, but the process is more centralized, and it uses CDs and occasionally spare disks as well as tape.

Restoring files from backups that users accidentally deleted or trashed.

This will never change.

Answering user questions ("How do I send mail?"), usually not for the first or last time.

Users will always have questions. Mine also whine more: "Why can't I have an Internet connection on my desk?" or "Why won't IRC work through the firewall?"

Monitoring system activity and trying to tune system parameters to give these overloaded systems the response time of an idle system.

Installing and upgrading hardware to keep up with monotonically increasing resource appetites.

Moving jobs up in the print queue, after more or less user whining, pleading, or begging, contrary to stated policy (about moving jobs, not about whining).

This is one problem that is no longer an issue for me. Printers are cheap, so they are no longer a scare resource that has to be managed.

Worrying about system security, and plugging the most noxious security holes I inherited.

Security is always a worry, and keeping up with security notices and patches takes a lot of time.

Installing programs and operating system updates.

Same.

Trying to free up disk space (and especially contiguous disk space).

The emphasis is more on high performance disk I/O (disk space is cheap): RAID and so on.

Rebooting the system after a crash (always at late and inconvenient times).

Systems crash a lot less than they used to (thankfully).

Straightening out network glitches ("Why isn't hamlet talking to ophelia?"). Occasionally, this involved physically tracing the Ethernet cable around the building, checking it at each node.

Last year, I replaced my last Thinnet network with twisted-pair cabling. I hope never to see the former again. However, I now occasionally have to replace cable segments that have malfunctioned.

Rearranging furniture to accommodate new equipment; installing said equipment.

Machines still come and go on a regular basis and have to be accommodated.

Figuring out why a program/command/account suddenly and mysteriously stopped working yesterday, even though the user swore he changed nothing.

Users will still be users.

Fixing—or rather, trying to fix—corrupted CAD/CAM binary data files.

The current analog of this is dealing with email attachments that users don't know how to access. Protecting users from potentially harmful attachments is another concern.

Going to meetings.

No meetings, but lots of casual conversations.

Adding new systems to the network.

This goes without saying: systems are virtually always added to the network.

Writing scripts to automate as many of the above activities as possible.

Automation is still the administrator's salvation.

As this list indicates, system management is truly a hodgepodge of activities and involves at least as many people skills as computer skills. While I'll offer some advice about the latter in a moment, interacting with people is best learned by watching others, emulating their successes, and avoiding their mistakes.

Currently, I look after a potpourri of workstations from many different vendors, as well as a couple of larger systems (in terms of physical size but not necessarily CPU power), with some PCs and Macs thrown in to keep things interesting. Despite these significant hardware changes, it's surprising how many of the activities from the early 1980s I still have to do. Adding toner now means changing a toner cartridge in a laser printer or the ink tanks in an inkjet printer; backups go to 4 mm tape and CDs rather than 9-track tape; user problems and questions are in different areas but are still very much on the list. And while there are (thankfully) no more meetings, there's probably even more furniture-moving and cable-pulling.

Some of these topics—moving furniture and going to or avoiding meetings, most obviously—are beyond the scope of this book. Space won't allow other topics to be treated exhaustively; in these cases, I'll point you in the direction of another book that takes up where I leave off. This book will cover most of the ordinary tasks that fall under the category of "system administration." The discussion will be relevant whether you've got a single PC (running Unix), a room full of mainframes, a building full of networked workstations, or a combination of several types of computers. Not all topics will apply to everyone, but I've learned not to rule out any of them a priori for a given class of user. For example, it's often thought that only big systems need process-accounting facilities, but it's now very common for small businesses to address their computing needs with a moderately-sized Unix system. Because they need to be able to bill their customers individually, they have to keep track of the CPU and other resources expended on behalf of each customer. The moral is this: take what you need and leave the rest; you're the best judge of what's relevant and what isn't.


1.1 Thinking About System Administration

I've touched briefly on some of the nontechnical aspects of system administration. These dynamics will probably not be an issue if it really is just you and your PC, but if you interact with other people at all, you'll encounter these issues. It's a cliché that system administration is a thankless job—one widely-reprinted cartoon has a user saying "I'd thank you but system administration is a thankless job"—but things are actually more complicated than that. As another cliché puts it, system administration is like keeping the trains on time; no one notices except when they're late.

System management often seems to involve a tension between authority and responsibility on the one hand and service and cooperation on the other. The extremes seem easier to maintain than any middle ground; fascistic dictators who rule "their system" with an iron hand, unhindered by the needs of users, find their opposite in the harried system managers who jump from one user request to the next, in continual interrupt mode. The trick is to find a balance between being accessible to users and their needs—and sometimes even to their mere wants—while still maintaining your authority and sticking to the policies you've put in place for the overall system welfare. For me, the goal of effective system administration is to provide an environment where users can get done what they need to, in as easy and efficient a manner as possible, given the demands of security, other users' needs, the inherent capabilities of the system, and the realities and constraints of the human community in which they all are located.

To put it more concretely, the key to successful, productive system administration is knowing when to solve a CPU-overuse problem with a command like:[1]

[1] On HP-UX systems, the command is ps -ef. Solaris systems can run either form depending on which version of ps comes first in the search path. AIX and Linux can emulate both versions, depending on whether a hyphen is used with options (System V style) or not (BSD style).

# kill -9 `ps aux | awk '$1=="chavez" {print $2}'

(This command blows away all of user chavez's processes.) It's also knowing when to use:

$ write chavez
You've got a lot of identical processes running on dalton.
Any problem I can help with?
^D

and when to walk over to her desk and talk with her face-to-face. The first approach displays Unix finesse as well as administrative brute force, and both tactics are certainly appropriate—even vital—at times. At oth er times, a simpler, less aggressive approach will work better to resolve your system's performance problems in addition to the user's confusion. It's also important to remember that there are some problems no Unix command can address.

To a great extent, successful system administration is a combination of careful planning andhabit, however much it may seem like crisis intervention at times. The key to handling a crisis well lies in having had the foresight and taken the time to anticipate and plan for the type of emergency that has just come up. As long as it only happens once in a great while, snatching victory from the jaws of defeat can be very satisfying and even exhilarating.

On the other hand, many crises can be prevented altogether by a determined devotion to carrying out all the careful procedures you've designed: changing the root password regularly, faithfully making backups (no matter how tedious), closely monitoring system logs, logging out and clearing the terminal screen as a ritual, testing every change several times before letting it loose, sticking to policies you've set for users' benefit—whatever you need to do for your system. (Emerson said, "A foolish consistency is the hobgoblin of little minds," but not a wise one.)

My philosophy of system administration boils down to a few basic strategies that can be applied to virtually any of its component tasks:

  • Know how things work. In these days, when operating systems are marketed as requiring little or no system administration, and the omnipresent simple-to-use tools attempt to make system administration simple for an uninformed novice, someone has to understand the nuances and details of how things really work. It should be you.

  • Plan it before you do it.

  • Make it reversible (backups help a lot with this one).

  • Make changes incrementally.

  • Test, test, test, before you unleash it on the world.

I learned about the importance of reversibility from a friend who worked in a museum putting together ancient pottery fragments. The museum followed this practice so that if better reconstructive techniques were developed in the future, they could undo the current work and use the better method. As far as possible, I've tried to do the same with computers, adding changes gradually and preserving a path by which to back out of them.

A simple example of this sort of attitude in action concerns editing system configuration files. Unix systems rely on many configuration files, and every major subsystem has its own files (all of which we'll get to). Many of these will need to be modified from time to time.

I never modify the original copy of theconfiguration file, either as delivered with the system or as I found it when I took over the system. Rather, I always make a copy of these files the first time I change them, appending the suffix .dist to the filename; for example:

# cd /etc
# cp inittab inittab.dist
# chmod a-w inittab.dist

I write-protect the .dist file so I'll always have it to refer to. On systems that support it, use the cp command's -p option to replicate the file's current modification time in the copy.

I also make a copy of the current configuration file before changing it in any way so undesirable changes can be easily undone. I add a suffix like .old or .sav to the filename for these copies. At the same time, I formulate a plan (at least in my head) about how I would recover from the worst consequence I can envision of an unsuccessful change (e.g., I'll boot to single-user mode and copy the old version back).

Once I've made the necessary changes (or the first major change, when several are needed), I test the new version of the file, in a safe (nonproduction) environment if possible. Of course, testing doesn't always find every bug or prevent every problem, but it eliminates the most obvious ones. Making only one major change at a time also makes testing easier.

NOTE

Some administrators use the a revision control system to track the changes to important system configuration files (e.g., CVS or RCS). Such packages are designed to track and manage changes to application source code by multiple programmers, but they can also be used to record changes to configuration files. Using a revision control system allows you to record the author and reason for any particular change, as well as reconstruct any previous version of a file at any time.

The remaining sections of this chapter discuss some important administrative tools. The first describes how to become the superuser (the Unix privileged account). Because I believe a good system manager needs to have both technical expertise and an awareness of and sensitivity to the user community of which he's a part, this first chapter includes a section on Unix communication commands. The goal of these discussions—as well as of this book as a whole—is to highlight how a system manager thinks about system tasks and problems, rather than merely to provide literal, cookbook solutions for common scenarios.

Important administrative tools of other kinds are covered in later chapters of this book.


1.2 Becoming Superuser

On a Unix system, the superuser refers to a privileged account with unrestricted access to all files and commands. The username of this account is root. Many administrative tasks and their associated commands require superuser status.

There are two ways to become the superuser. The first is to log in as root directly. The second way is to execute the command su while logged in to another user account. The su command may be used to change one's current account to that of a different user after entering the proper password. It takes the username corresponding to the desired account as its argument; root is the default when no argument is provided.

After you enter the su command (without arguments), the system prompts you for the root password. If you type the password correctly, you'll get the normal root account prompt (by default, a number sign: #), indicating that you have successfully become superuser and that the rules normally restricting file access and command execution do not apply. For example:

$ su
Password:   Not echoed
#

If you type the password incorrectly, you get an error message and return to the normal command prompt.

You may exit from the superuser account with exit or Ctrl-D. You may suspend the shell and place it in the background with the suspend command; you can return to it later using fg.

When you run su, the new shell inherits the environment from your current shell environment rather than creating the environment that root would get after logging in. However, you can simulate an actual root login session with the following command form:

$ su -

Unlike some other operating systems, the Unix superuser has all privileges all the time: access to all files, commands, etc. Therefore, it is entirely too easy for a superuser to crash the system, destroy important files, and create havoc inadvertently. For this reason, people who know the superuser password (including the system administrator) should not do their routine work as superuser. Only use superuser status when it is needed.

The root account should always have a password, and this password should be changed periodically. Only experienced Unix users with special requirements should know the superuser password, and the number of people who know it should be kept to an absolute minimum.

To set or change the superuser password, become superuser and execute one of the following commands:

# passwd        Works most of the time.
# passwd root   Solaris and FreeBSD systems when su'd to root.

Generally, you'll be asked to type the old superuser password and then the new password twice. The root password should also be changed whenever someone who knows it stops using the system for any reason (e.g., transfer, new job, etc.), or if there is any suspicion that an unauthorized user has learned it. Passwords are discussed in detail in Chapter 6.

I try to avoid logging in directly as root. Instead, I su to root only as necessary, exiting from or suspending the superuser shell when possible. Alternatively, in a windowing environment, you can create a separate window in which you su to root, again executing commands there only as necessary.

For security reasons, it's a bad idea to leave any logged-in session unattended; naturally, that goes double for a root session. Whenever I leave a workstation where I am logged in as root, I log out or lock the screen to prevent anyone from sneaking onto the system. The xlock command will lock an X session; the password of the user who ran xlock must be entered to unlock the session (on some systems, the root password can also unlock sessions locked by other users).[2] While screen locking programs may have security pitfalls of their own, they do prevent opportunistic breaches of system security that would otherwise be caused by a momentary lapse into laziness.

[2] For some unknown reason, FreeBSD does not provide xlock. However, the xlockmore (see http://www.tux.org/~bagleyd/xlockmore.html) utility provides the same functionality (it's actually a follow-on to xlock).

If you are logged in as root on a serial console, you should also use a locking utility provided by the operating system. In some cases, if you are using multiple virtual consoles, you will need to lock each one individually.

1.2.1 Controlling Access to the Superuser Account

On many systems, any user who knows the root password may become superuser at any time by running su. This is true for HP-UX, Linux, and Solaris systems in general.[3] Solaris allows you to configure some aspects of how the command works via settings in the /etc/default/su configuration file.

[3] When the PAM authentication facility is in use, it controls access to su (see Section 6.5).

Traditionally, BSD systems limited access to su to members of group 0 (usually named wheel); under FreeBSD, if the wheel group has a null user list in the group file (/etc/group), any user may su to root; otherwise, only members of the wheel group can use it. The default configuration is a wheel group consisting of just root.

AIX allows the system administrator to specify who can use su on an account-by-account basis (no restrictions are imposed by default). The following commands display the current groups that are allowed to su to root and then limit that same access to the system and admins groups:

# lsuser -a sugroups root
root sugroups=ALL
# chuser sugroups="system,admins" root

Most Unix versions also allow you to restrict direct root logins to certain terminals. This topic is discussed in Chapter 12.

An Armadillo?

The armadillo typifies one attribute that a successful system administrator needs: a thick skin. Armadillos thrive under difficult environmental conditions through strength and perseverance, which is also what system administrators have to do a lot of the time (see the colophon at the back of the book for more information about the armadillo). System managers will find other qualities valuable as well, including the quickness and cleverness of the mongoose (Unix is the snake), the sense of adventure and playfulness of puppies and kittens, and at times, the chameleon's ability to blend in with the surroundings, becoming invisible even though you're right in front of everyone's eyes.

Finally, however, as more than one reader has noted, the armadillo also provides a cautionary warning to system administrators not to become so single-mindedly or narrowly focused on what they are doing that they miss the big picture. Armadillos who fail to heed this advice end up as roadkill.

1.2.2 Running a Single Command as root

su also has a mode whereby a single command can be run as root . This mode is not a very convenient way to interactively execute superuser commands, and I tend to see it as a pretty unimportant feature of su. Using su -c can be very useful in scripts, however, keeping in mind that the target user need not be root.

Nevertheless, I have found that it does have one important use for a system administrator: it allows you to fix something quickly when you are at a user's workstation (or otherwise not at your own system) without having to worry about remembering to exit from an su session.[4] There are users who will absolutely take advantage of such lapses, so I've learned to be cautious.

[4] Another approach is always to open a new window when you need to do something at a user's workstation. It's easy to get into the habit of always closing it down as you leave.

You can run a single command as root by using a command of this form:

$ su root -c "command"

where command is replaced by the command you want to run. The command should be enclosed in quotation marks if it contains any spaces or special shell characters. When you execute a command of this form, su prompts for the root password. If you enter the correct password, the specified command runs as root, and subsequent commands are run normally from the original shell. If the command produces an error or is terminated (e.g. with CTRL-C), control again returns to the unprivileged user shell.

The following example illustrates this use of su to unmount and eject the CD-ROM mounted in the /cdrom directory:

$ su root -c "eject /cdrom"
Password:   root password entered

Commands and output would be slightly different on other systems.

You can start a background command as root by including a final ampersand within the specified command (inside the quotation marks), but you'll want to consider the security implications of a user bringing it to the foreground before you do this at a user's workstation.

1.2.3 sudo: Selective Access to Superuser Commands

Standard Unix takes an all-or-nothing approach to granting root access, but often what you actually want is something in between. The freely available sudo facility allows specified users to run specific commands as root without having to know the root password (available at http://www.courtesan.com/sudo/).[5]

[5] Administrative roles are another, more sophisticated way of partitioning root access. They are discussed in detail in Section 7.5.

For example, a non-root user could use this sudo command to shut down the system:

$ sudo  /sbin/shutdown ...
Password:

sudo requires only the user's own password to run the command, not the root password. Once a user has successfully given a password to sudo, she may use it to run additional commands for a limited period of time without having to enter a password again; this period defaults to five minutes. A user can extend the time period by an equal amount by running sudo -v before it expires. She can also terminate the grace period by running sudo -K.

sudo uses a configuration file, usually /etc/sudoers , to determine which users may use the sudo command and the other commands available to each of them after they've started a sudo session. The configuration file must be set up by the system administrator. Here is the beginning of a sample version:

# Host alias specifications: names for host lists
Host_Alias    PHYSICS = hamlet, ophelia, laertes
Host_Alias    CHEM = duncan, puck, brutus

# User alias specifications: named groups of users
User_Alias    BACKUPOPS = chavez, vargas, smith

# Command alias specifications: names for command groups
Cmnd_Alias    MOUNT = /sbin/mount, /sbin/umount
Cmnd_Alias    SHUTDOWN = /sbin/shutdown
Cmnd_Alias    BACKUP = /usr/bin/tar, /usr/bin/mt
Cmnd_Alias    CDROM = /sbin/mount /cdrom, /bin/eject

These three configuration file sections define sudo aliases—uppercase symbolic names—for groups of computers, users and commands, respectively. This example file defines two sets of hosts (PHYSICS and CHEM), one set of users (BACKUPOPS), and four command aliases. For example, the MOUNT command alias is defined as the mount and umount commands. Following good security practice, all commands include the full pathname for the executable.

The final command alias illustrates the use of arguments within a command list. This alias consists of a command to mount a CD at /cdrom and to eject the media from the drive. Note, however, that it does not grant general use of the mount command.

The final section of the file (see below) specifies which users may use the sudo command, as well as what commands they can run with it and which computers they may run them on. Each line in this section consists of a username or alias, followed by one or more items of the form:

host=command(s)

where host is a hostname or a host alias, and command(s) are one or more commands or command aliases, with multiple commands or hosts separated by commas. Multiple access specifications may be included for a single user, separated by colons. The alias ALL stands for all hosts or commands, depending on its context.

Here is the remainder of our example configuration file:

# User specifications: who can do what where
root          ALL = ALL
%chem         CHEM = SHUTDOWN, MOUNT
chavez        PHYSICS = MOUNT, achilles: /sbin/swapon
harvey        ALL = NOPASSWD: SHUTDOWN
BACKUPOPS     ALL, !CHEM = BACKUP: /usr/local/bin

The first entry after the comment grants root access to all commands on all hosts. The second entry applies to members of the chem group (indicated by the initial percent sign), who may run system shutdown and mounting commands on any computer in the CHEM list.

The third entry specifies that user chavez may run the mounting commands on the hosts in the PHYSICS list and may also run the swapon command on host achilles. The next entry allows user harvey to run the shutdown command on any system, and sudo will not require him to enter his password (via the NOPASSWD: preceding the command list).

The final entry applies to the users specified for the BACKOPS alias. On any system except those in the CHEM list (the preceding exclamation point indicates exclusion), they may run the command listed in the BACKUP alias as well as any command in the /usr/local/bin directory.

Users can use the sudo -l command form to list the commands available to them via this facility.

Commands should be selected for use with sudo with some care. In particular, shell scripts should not be used, nor should any utility which provides shell escapes —the ability to execute a shell command from within a running interactive program (editors, games, and even output display utilities like more and less are common examples). Here is the reason: when a user runs a command with sudo, that command runs as root, so if the command lets the user execute other commands via a shell escape, any command he runs from within the utility will also be run as root, and the whole purpose of sudo—to grant selective access to superuser command—will be subverted. Following similar reasoning, because most text editors provide shell escapes, any command that allows the user to invoke an editor should also be avoided. Some administrative utilities (e.g., AIX's SMIT) also provide shell escapes.

The sudo package provides the visudo command for editing /etc/sudoers. It locks the file, preventing two users from modifying the file simultaneously, and it performs syntax checking when editing is complete (if there are errors, the editor is restarted, but no explicit error messages are given).

There are other ways you might want to customize sudo. For example, I want to use a somewhat longer interval for password-free use. Changes of this sort must be made by rebuilding sudo from source code. This requires rerunning the configure script with options. Here is the command I used, which specifies a log file for all sudo operations, sets the password-free period to ten minutes, and tells visudo to use the text editor specified in the EDITOR environment variable:

# cd sudo-source-directory
# ./configure --with-logpath=/var/log/sudo.log \
            --with-timeout=10 --with-env-editor

Once the command completes, use the make command to rebuild sudo.[6]

[6] A couple more configuration notes: sudo can also be integrated into the PAM authentication system (see Section 6.5). Use the - -use-pam option to configure. On the other hand, if your system does not use a shadow password file, you must use the - -disable-shadow option.

sudo's logging facility is important and useful in that it enables you to keep track of privileged commands that are run. For this reason, using sudo can sometimes be preferable to using su even when limiting root-level command access is not an issue.

The one disadvantage of sudo is that it provides no integrated remote-access password protection. Thus, when you run sudo from an insecure remote session, passwords are transmitted over the network for any eavesdropper to see. Of course, using SSH can overcome this limitation.


1.3 Communicating with Users

The commands discussed in this section are simple and familiar to most Unix users. For this reason, they're often overlooked in system administration discussions. However, I believe you'll find them to be an indispensable part of your repertoire. One other important communications mechanism is electronic mail (see Chapter 9).

1.3.1 Sending a Message

A system administrator frequently needs to send a message to a user's screen (or window). write is one way to do so:

$ write username [tty]

where username indicates the user to whom you wish to send the message. If you want to write to a user who is logged in more than once, the tty argument may be used to select the appropriate terminal or window. You can find out where a user is logged in using the who command.

Once the write command is executed, communication is established between your terminal and the user's terminal: lines that you type on your terminal will be transmitted to him. End your message with a CTRL-D. Thus, to send a message to user harvey for which no reply is needed, execute a command like this:

$ write harvey
The file you needed has been restored.
Additional lines of message text
^D

In some implementations (e.g., AIX, HP-UX and Tru64), write may also be used over a network by appending a hostname to the username. For example, the command below initiates a message to user chavez on the host named hamlet:

$ write chavez@hamlet

When available, the rwho command may be used to list all users on the local subnet (it requires a remote who daemon be running on the remote system).

The talk command is a more sophisticated version of write. It formats the messages between two users in two separate spaces on the screen. The recipient is notified that someone is calling her, and she must issue her own talk command to begin communication. Figure 1-1 illustrates the use of talk.

Figure 1-1. Two-way communication with talk

Users may disable messages from both write and talk by using the command mesg n (they can include it in their .login or .profile initialization file). Sending messages as the superuser overrides this command. Be aware, however, that sometimes users have good reasons for turning off messages.

NOTE

In general, the effectiveness of system messages is inversely proportional to their frequency.

1.3.2 Sending a Message to All Users

If you need to send a message to every user on the system, you can use the wall command. wall stands for "write all" and allows the administrator to send a message to all users simultaneously.

To send a message to all users, execute the command:

$ wall
Followed by the message you want to send, terminated with CTRL-D on a separate line
^D

Unix then displays a phrase like:

Broadcast Message from root on console ...

to every user, followed by the text of your message. Similarly, the rwall command sends a message to every user on the local subnet.

Anyone can use this facility; it does not require superuser status. However, as with write and talk, only messages from the superuser override users' mesg n commands. A good example of such a message would be to give advance warning of an imminent but unscheduled system shutdown.

1.3.3 The Message of the Day

Login time is a good time to communicate certain types of information to users. It's one of the few times that you can be reasonably sure of having a user's attention (sending a message to the screen won't do much good if the user isn't at the workstation). The file /etc/motd is the system's message of the day. Whenever anyone logs in, the system displays the contents of this file. You can use it to display system-wide information such as maintenance schedules, news about new software, an announcement about someone's birthday, or anything else considered important and appropriate on your system. This file should be short enough so that it will fit entirely on a typical screen or window. If it isn't, users won't be able to read the entire message as they log in.

On many systems, a user can disable the message of the day by creating a file named .hushlogin in her home directory.

1.3.4 Specifying the Pre-Login Message

On Solaris, HP-UX, Linux and Tru64 systems, the contents of the file /etc/issue is displayed immediately before the login prompt on unused terminals. You can customize this message by editing this file.

On other systems, login prompts are specified as part of the terminal-related configuration files; these are discussed in Chapter 12.


1.4 About Menus and GUIs

For several years now, vendors and independent programmers have been developing elaborate system administration applications. The first of these were menu-driven, containing many levels of nested menus organized by subsystem or administrative task. Now, the trend is toward independent GUI-based tools, each designed to manage some particular system area and perform the associated tasks.

Whatever their design, all of them are designed to allow even relative novices to perform routine administrative tasks. The scope and aesthetic complexity of these tools vary considerably, ranging from shell scripts employing simple selections lists and prompts to form-based utilities running under X. A few even offer a mouse-based interface with which you perform operations by dragging icons around (e.g., dropping a user icon on top of a group icon adds that user to that group, dragging a disk icon into the trash unmounts a filesystem, and the like).

In this section, we'll take a look at such tools, beginning with general concepts and then going on to a few practical notes about the tools available on the systems we are considering (usually things I wish I had known about earlier). The tools are very easy to use, so I won't be including detailed instructions for using them (consult the appropriate documentation for that).

1.4.1 Ups and Downs

Graphical and menu-based system administration tools have some definite good points:

  • They can provide a quick start to system administration, allowing you to get things done while you learn about the operating system and how things work. The best tools include aids to help you learn the underlying standard administrative commands.

    Similarly, these tools can be helpful in figuring out how to perform some task for the first time; when you don't know how to begin, it can be hard to find a solution with just the manual pages.

  • They can help you get the syntax right for complex commands with lots of options.

  • They make certain kinds of operations more convenient by combining several steps into a single menu screen (e.g., adding a user or installing an operating system upgrade).

On the other hand, they have their down side as well:

  • Typing the equivalent command is usually significantly faster than running it from an administrative tool.

  • Not all commands are always available through the menu system, and sometimes only part of the functionality is implemented for commands that are included. Often only the most frequently used commands and/or options are available. Thus, you'll still need to execute some versions of commands by hand.

  • Using an administrative tool can slow down the learning process and sometimes stop it altogether. I've met inexperienced administrators who had become convinced that certain operations just weren't possible simply because the menu system didn't happen to include them.

  • The GUI provides unique functionality accessible only through its interface, so creating scripts to automate frequent tasks becomes much more difficult or impossible, especially when you want to do things in a way that the original author did not think of.

In my view, an ideal administrative tool has all of these characteristics:

  • The tool must run normal operating system commands, not opaque, undocumented programs stored in some obscure, out-of-the-way directory. The tool thus makes system administration easier, leaving the thinking to the human using it.

  • You should be able to display the commands being run, ideally before they are executed.

  • The tool should log of all its activities (at least optionally).

  • As much as possible, the tool should validate the values the user enters. In fact, novice administrators frequently assume that the tools do make sure their selections are reasonable, falsely thinking that they are protected from anything harmful.

  • All of the options for commands included in the tool should be available for use, except when doing so would violate the next item.

  • The tool should not include every administrative command. More specifically, it should deliberately omit commands that could cause catastrophic consequences if they are used incorrectly. Which items to omit depends on the sort of administrators the tool is designed for; the scope of the tool should be directly proportional to the amount of knowledge its user is assumed to have. In the extreme case, dragging a disk icon into a trash can icon should never do anything other than dismount it, and there should not be any way to, say, reformat an existing filesystem. Given that such a tool is consciously designed for minimally-competent administrators, including such capabilities is just asking for trouble.

In addition, these features make using an administrative tool much more efficient, but they are not absolutely essential:

  • A way of specifying the desired starting location within a deep menu tree when you invoke the tool.

  • A one-keystroke exit command that works at every point within menu system.

  • Context-sensitive help.

  • The ability to limit access to subsections of the tool by user.

  • Customization features.

If one uses these criteria, AIX's SMIT comes closest to an ideal administrative tool, a finding that many have found ironic.

As usual, using menu interfaces in moderation is probably the best approach. These applications are great when they save you time and effort, but relying on them to lead you through every situation will inevitably lead to frustration and disappointment somewhere down the line.

The Unix versions we are considering offer various system administration facilities. They are summarized and compared in Table 1-2. The table columns hold the Unix version, tool command or name, tool type, whether or not the command to be run can be previewed before execution, whether or not the facility can log its actions and whether or not the tool can be used to administer remote systems.

Table 1-2. Some system administration facilities

Unix Version

Command/tool

Type

Command preview?

Creates logs?[7]

Remote admin?

AIX

smit

WSM

menu

GUI

yes

no

yes

no

no

yes

FreeBSD

sysinstall

menu

no

no

no

HP-UX

sam

both

no

yes

yes

Linux

linuxconf

both

no

no

no

Red Hat Linux

redhat-config-*

GUI

no

no

no

SuSE Linux

yast

yast2

menu

GUI

no

no

no

no

no

no

Solaris

admintool

CDE admin tools

AdminSuite/SMC

menu

GUI

menu

no

no

no

no

no

yes

no

no

yes

Tru64

sysman

sysman -station

menu

menu

no

no

no

no

no

yes

[7] Some tools do some rather half-hearted logging to the syslog facility, but it's not very useful.

There are also some other tools on some of these systems that will be mentioned in this book when appropriate, but they are ignored here.

Why Menus and Icons Aren't Enough

Every site needs at least one experienced system administrator who can perform those tasks that are beyond the abilities of the administrative tool. Not only does every current tool leave significant amounts of uncovered territory, but they also all suffer from limitations inherent in programs designed for routine operations under normal system conditions. When the system is in trouble, and these assumptions no longer hold, the tools don't work.

For example, I've been in a situation where the administrative tool couldn't configure a replacement because the old disk hadn't been unconfigured properly before being removed. One part of the tool thought the old disk was still on the system and wouldn't replace it, while another part wouldn't delete the old configuration data because it couldn't access the corresponding physical disk.

I was able to solve this problem because I understood enough about the device database on that system to fix things manually. Not only will such things happen to every system from time to time, they will happen to everyone, sooner or later. It's a lot easier to coax a system back to life from single user mode after a power failure when you understand, for example, what the Check Filesystem Integrity menu item actually does. In the end, you need to know how things really work.

1.4.2 AIX: SMIT and WSM

AIX offers two main system admini stration facilities: the System Management Interface Tool (SMIT) and the Workspace System Manager (WSM) facility. Both of them run in both graphical and text mode.

SMIT consists of a many-leveled series of nested menus. Its main menu is illustrated in Figure 1-2.

Figure 1-2. The AIX SMIT facility

One of SMIT's most helpful features is command preview: if you click on the Command button or press F6, SMIT displays the command to be executed by the current dialog. This feature is illustrated in the window on the right in Figure 1-2.

You can also go directly to any screen by including the corresponding fast path keyword on the smit command line. Many SMIT fast paths are the same as the command executed from a particular screen. Many other fast paths fall into a predictable pattern, beginning with one of the prefixes mk (make or start), ch (change or reconfigure), ls (list), or rm (remove or stop), to which an object code is appended: mkuser, chuser, lsuser, rmuser for working with user accounts; mkprt, chprt, lsprt, rmprt for working with printers, and so on. Thus, it's often easy to guess the fast path you want.

You can display the fast path for any SMIT screen by pressing F8 in the ASCII version of the tool:

Current fast path:
     "mkuser"

If the screen doesn't have a fast path, the second line will be blank. Other useful fast paths that are harder to guess include the following:

chgsys

View/change AIX parameters.

configtcp

Reconfigure TCP/IP.

crfs

Create a new filesystem.

lvm

Main Logical Volume Manager menu.

_nfs

Main NFS menu.

spooler

Manipulate print jobs.

Here are a few additional SMIT notes:

  • The smitty command may be used to start the ASCII version of SMIT from within an X session (where the graphical version is invoked by default).

  • Although I like them, many people are annoyed by the SMIT log files. You can use a command like this one to eliminate the SMIT log files:

    $ smit -s /dev/null -l /dev/null ...

    You can define an alias in your shell initialization file to get rid of these files permanently (C shell users would omit the equals sign):

    alias smit="/usr/sbin/smitty -s /dev/null -l /dev/null"

  • smit -x provides a command preview mode. The commands that would be run are written to the log file but not executed.

  • Newer versions of smit have the following annoying feature: when a command has successfully completed, and you click Done to close the output window, you are taken back to the command setup window. At this point, to exit, you must click Cancel, not OK. Doing the latter will cause the command to run again, which is not what you want and is occasionally quite troublesome!

The WSM facility contains a variety of GUI-based tools for managing various aspects of the system. Its functionality is a superset of SMIT's, and it has the advantage of being able to administer remote systems (it requires that remote systems be running a web server). You can access WSM via the Common Desktop Environment's Applications area: click on the file cabinet icon (the one with the calculator peeking out of it); the system administration tools are then accessible under the System_Admin icon. You can also run a command-line version of WSM via the wsm command.

The WSM tools are run on a remote system via a Java-enabled web browser. You can connect to the tools by pointing the browser at http://hostname/wsm.html, where hostname corresponds to the desiredremote system. Of course, you can also run the text version by entering the wsm command into a remote terminal session.

1.4.3 HP-UX: SAM

HP-UX provides the System Administration Manager, also known as SAM. SAM is easy to use and can perform a variety of system management tasks. SAM operates in both menu-based and GUI mode, although the latter requires support for Motif.

The items on SAM's menus invoke a combination of regular HP-UX commands and special scripts and programs, so it's not always obvious what they do. One way to find out more is to use SAM's built-in logging feature. SAM allows you to specify the level of detail in log file displays, and you can optionally keep the log open as you are working in order to monitor what is actually happening. The SAM main window and log display are illustrated in Figure 1-3.

Figure 1-3. The HP-UX SAM facility

If you really want to know what SAM is doing, you'll need to consult its configuration files, stored in the subdirectories of /usr/sam/lib. Most subdirectories have two-character names, closely related to a top-level icon or menu item. For example, the ug subdirectory contains files for the Users and Groups module, and the pm subdirectory contains those for Process Management. If you examine the .tm file there, you can figure out what some of the menu items do. This example illustrates the kinds of items to look for in these files:

#egrep '^task [a-z]|^ *execute' pm.tm
task pm_get_ps {
   execute "/usr/sam/lbin/pm_parse_ps"
task pm_add_cron {
   execute "/usr/sam/lbin/cron_change ADD /var/sam/pm_tmpfile"
task pm_add_cron_check {
   execute "/usr/sam/lbin/cron_change CHECK /var/sam/pm_tmpfile"
task pm_mod_nice {
   execute "unset UNIX95;/usr/sbin/renice -n %$INT_ID% %$STRING_ID%"
task pm_rm_cron {
   execute "/usr/sam/lbin/cron_change REMOVE /var/sam/pm_tmpfile"

The items come in pairs, relating a menu item or icon and an actual HP-UX command. For example, the fourth pair in the previous output allows you to figure out what the Modify Nice Priority menu item does (runs the renice command). The second pair indicates that the item related to adding cron entries executes the listed shell script; you can examine that file directly to get further details.

There is another configuration file for each main menu item in the /usr/sam/lib/C subdirectory, named pm.ui in this case. Examining the lines containing "action" and "do" provides similar information. Note that "do" entries that end with parentheses (e.g., do pm_forcekill_xmit( )) indicate a call to a routine in one of SAM's component shared libraries, which will mean the end of the trail for your detective work.

SAM allows you to selectively grant access to its functional areas on a per-user basis. Invoke it via sam -r to set up user privileges and restrictions. In this mode, you select the user or group for which you want to define allowed access, and then you navigate through the various icons and menus, enabling or disabling items as appropriate. When you are finished, you can save these settings and also save groups of settings as named permission templates that can subsequently be applied to other users and groups.

In this mode, the SAM display changes, and the icons are colored indicating the allowed access: red for prohibited, green for allowed, and yellow when some features are allowed and others are prohibited.

You can use SAM for remote administration by selecting the Run SAM on Remote System icon from the main window. The first time you connect to a specific remote system, SAM automatically sets up the environment.

1.4.4 Solaris: admintool and Sun Management Console

From a certain point of view, current versions of Solaris actually offer three distinct tool options:

  • admintool, the menu-based system administration package available under Solaris for many years. You must be a member of the sysadmin group to run this program.

  • A set of GUI-based tools found under the System_Admin icon of the Applications Manager window under the Common Desktop Environment (CDE), which is illustrated on the left in Figure 1-4. Select the Applications [image] Application Manager menu path from the CDE's menu to open this window. Most of these tools are very simple, one-task utilities related to media management, although there is also an icon there for admintool.

  • The Solaris AdminSuite, whose components are controlled by the Sun Management Console (SMC). The facility's main window is illustrated on the right in Figure 1-4.

    In some cases, this package is included with the Solaris operating system. It is also available for (free) download (from http://www.sun.com/bigadmin/content/adminpack/). In fact, it is well worth the overnight download required if you have only a slow modem (two nights if you want the documentation as well).

    This tool can be used to perform administrative tasks onremote systems. You specify the system on which you want to operate when you log in to the facility.

Figure 1-4. Solaris system administration tools

1.4.5 Linux: Linuxconf

Many Linux systems, including some Red Hat versions, offer theLinuxconf graphical administrative tool written by Jacques Gélinas. This tool can also be used with other Linux distributions (see http://www.solucorp.qc.ca/linuxconf/). It is illustrated in Figure 1-5.

Figure 1-5. The Linuxconf facility

The tool's menu system is located in the area on the left, and forms related to the current selection are displayed on the right. Several of the program's subsections can be accessed directly via separate commands (which are in fact just links to the main linuxconf executable): fsconf, mailconf, modemconf, netconf, userconf, and uucpconf, which administer filesystems, electronic mail, modems, networking parameters, users and groups and UUCP, respectively.

Early versions of Linuxconf were dreadful: bug-rich and unbelievably slow. However, more recent versions have improved quite a bit, and the current version is pretty good. Linuxconf leans toward supporting all available options at the expense of novice's ease-of-use at times (a choice with which I won't quarrel). As a result, it is a tool that can make many kinds of configuration tasks easier for an experienced administrator; less expert users may find the number of settings in some dialogs to be somewhat daunting. You can also specify access to Linuxconf and its various subsections on a per-user basis (this is configured via the user account settings).

1.4.6 Red Hat Linux: redhat-config-*

Red Hat Linux provides several GUI-based administration tools, including these:

redhat-config-bindconf

Configure the DNS server (redhat-config-bind under Version 7.2).

redhat-config-network

Configure the networking on the local host (new with Red Hat Version 7.3).

redhat-config-printer-gui

Configure and manage print queues and the print server.

redhat-config-services

Select servers to be started at boot time.

redhat-config-date and redhat-config-time

Set the date and/or time.

redhat-config-users

Configure user accounts and groups.

There are often links to some of these utilities with different (shorter) names. They can also be accessed via icons from the System Settings icon under Start Here. Figure 1-6 illustrates the dialogs for creating a new user account (left) and specifying the local system's DNS server (right).

Figure 1-6. Red Hat Linux system configuration tools

1.4.7 SuSE Linux: YaST2

The "YaST" in YaST2 stands for "yet another setup tool." It is a follow-on to the original YaST, and like the previous program (which is also available), it is a somewhat prettied up menu-based administration facility. The program's main window is illustrated in Figure 1-7.

Figure 1-7. The SuSE Linux YaST2 facility

The yast2 command is used to start the tool. Generally, the tool is easy to use and does its job pretty well. It does have one disadvantage, however. Whenever you add a new package or make other kinds of changes to the system configuration, the SuSEconfig script runs (actually, a series of scripts in /sbin/conf.d). Before SuSE Version 8, this process was fiendishly slow.

SuSEconfig 's actions are controlled by the settings in the /etc/rc.config configuration file, as well as those in /etc/rc.config.d (SuSE Version 7) or /etc/sysconfig (SuSE Version 8). Its slowness stems from the fact that every action is performed every time anything changes on the system; in other words, it has no intelligence whatsoever that would allow it to operate only on items and areas that were modified.

Even worse, on SuSE 7 systems, SuSEconfig's actions are occasionally just plain wrong. A particularly egregious example occurs with the Postfix electronic mail package. By default, the primary Postfix configuration file, main.cf, is overwritten every time the Postfix SuSEconfig subscript is executed.[8] The latter happens every time SuSEconfig runs, which is practically every time you change anything on the system with YaST or YaST2 (regardless of its lack of relevance to Postfix). The net result is that any local customizations to main.cf get lost. Clearly, adding a new game package, for example, shouldn't clobber a key electronic-mail configuration file.

[8] You can prevent this by setting POSTFIX_CREATECF to no in /etc/rc.config.d/postfix.rc.config.

Fortunately, these problems have been cleared up in SuSE Version 8. I do also use YaST2 on SuSE 7 systems, but I've examined all of the component subscripts thoroughly and made changes to configuration files to disable actions I didn't want. You should do the same.

1.4.8 FreeBSD: sysinstall

FreeBSD offers only the sysinstall utility in terms of administrative tools, the same program that manages operating system installations and upgrades (its main menu is illustrated in Figure 1-8). Accordingly, the tasks that it can handle are limited to the ones that come up in the context of operating system installations: managing disks and partitions, basic networking configuration, and so on.

Figure 1-8. The FreeBSD sysinstall facility

Both the Configure and Index menu items are of interest for general system administration tasks. The latter is especially useful in that it lists individually all the available operations the tool can perform.

1.4.9 Tru64: SysMan

The Tru64 operating system offers the SysMan facility. This tool is essentially menu driven despite the fact that it can run in various graphical environments, including via a Java 1.1-enabled browser. SysMan can run in two different modes, as shown in Figure 1-9: as a system administration utility for the local system or as a monitoring and management station for the network. These two modes of operations are selected with the sysman command's -menu and -station options, respectively; -menu is the default.

Figure 1-9. The SysMan facility

This utility does not have any command preview or logging features, but it does have a variety of "accelerators": keywords that can be used to initiate a session at a particular menu point. For example, sysman shutdown takes you directly to the system shutdown dialog. Use the command sysman -list to obtain a complete list of all defined accelerators.

One final note: the insightd daemon must be running in order to be able to access the SysMan online help.

1.4.10 Other Freely Available Administration Tools

The freely available operating systems often provide some additional administrative tools as part of the various window manager packages that they include. For example, both the Gnome and KDE desktop environments include several administrative applets and utilities. Those available under KDE on a SuSE Linux system are illustrated in Figure 1-10.

Figure 1-10. KDE administrative tools on a SuSE Linux system

We will consider some of the best of these tools from time to time in this book.

1.4.10.1 The Ximian Setup Tools

The Ximian project brings together the latest release of the Gnome desktop, the Red Carpet web-based system software update facility, and several other items into what is designed to be a commercial-quality desktop environment. As of this writing, it is available for several Linux distributions and for Solaris systems. Additional ports, including to BSD, are planned for the future.

The Ximian Setup Tools are a series of applets designed to facilitate system administration, ultimately in a multiplatform environment. Current modules allow you to administer boot setup (i.e., kernel selection), disks, swap space, users, basic networking, shared filesystems, printing, and the system time. The applet for the latter is illustrated in Figure 1-11.

Figure 1-11. The Ximian Setup Tools

This applet, even in this early incarnation, goes well beyond a simple dialog allowing you to set the current date and time; it also allows you to specify time servers for Internet-based time synchronization. The other tools are of similar quality, and the package seems very promising for those who want GUI-based system administration tools.

1.4.11 VNC

I'll close this section by briefly looking at one additional administrative tool that can be of great use for remote administration, especially in a heterogeneous environment. It is called VNC, which stands for "virtual network computing." The package is available for a wide variety of Unix systems[9] at http://www.uk.research.att.com/vnc/. It is shown in Figure 1-12.

[9] Official binary versions of the various tools are available for a few systems on the main web page. In addition, consult the contrib area for ports to additional systems. It is also usually easy to build the tools from source code.

Figure 1-12. Using VNC for remote system administration

The illustration depicts the entire desktop on a SuSE Linux system. You can see several of its icons along the left edge, as well as the tool bar at the bottom of the screen (where you can determine that it is running the KDE window manager).

The four open windows are three individual VNC sessions to different remote computers, each running a different operating system and a local YaST session. Beginning at the upper left and moving clockwise, the remote sessions are a Red Hat Linux system (Linuxconf is open), a Solaris system (we can see admintool), and an HP-UX system (running SAM).

VNC has a couple of advantages over remote application sessions displayed via the X Windows system:

  • With VNC you see the entire desktop, not just one application window. Thus, you can access applications via the remote system's own icons and menus (which may be much less convenient to initiate via commands).

  • You eliminate missing font issues and many other display and resource problems, because you are using the X server on the remote system to generate the display images rather than the one on the local system.

In order to use VNC, you must download the software and build or install the five executables that comprise it (conventionally, they are placed in /usr/local/bin). Then you must start a server process on systems that you want to administer remotely, using the vncserver command:

garden-$ vncserver
You will require a password to access your desktops.

Password:   Not echoed.
Verify:

New 'X' desktop is garden:1

Creating default startup script /home/chavez/.vnc/xstartup
Starting applications specified in /home/chavez/.vnc/xstartup
Log file is /home/chavez/.vnc/garden:1.log

This example starts a server on host garden. The first time you run the vncserver command, you will be asked for a password. This password, which is independent of your normal Unix password, will be required in order to connect to the server.

Once the server is running, you connect to it by running the vncviewer command. In this example, we connect to the vncserver on garden:

desert-$ vncviewer garden:1

The parameter given is the same as was indicated when the server was started. VNC allows multiple servers to be running simultaneously.

In order to shut down a VNC server, execute a command like this one on the remote system (i.e., the system where the server was started):

garden-$ vncserver -kill :1

Only the VNC server password is required for connection. Usernames are not checked, so an ordinary user can connect to a server started by root if she knows the proper password. Therefore, it is important to select strong passwords for the server password (see Section 6.4) and to use a different password from the normal one if such cross-user connections are needed.

Additionally, VNC passwords are sent in plain text over the network. Thus, using VNC is problematic on an insecure network. In such circumstances, VNC traffic can be encrypted by tunneling it through a secure protocol, such as SSH.


1.5 Where Does the Time Go?

We'll close this chapter with a brief look at a nice utility that can be useful for keeping track of how you spend your time, information that system administrators will find comes in handy all too often. It is called plod and was written by Hal Pomeranz (see http://bullwinkle.deer-run.com/~hal/plod/). While there are similar utilities with a GUI interface (e.g., gtt and karm, from the Gnome and KDE window manager packages, respectively), I prefer this simpler one that doesn't require a graphical environment.

plod works by maintaining a log file containing time stamped entries that you provide; the files' default location is ~/.logdir/yyyymm, where yyyy and mm indicate the current year and month, respectively. plod log files can optionally be encrypted.

The command has lots of options, but its simplest form is the following:

$ plod [text]

If some text is included on the command, it is written to the log file (tagged with the current date and time). Otherwise, you enter the command's interactive mode, in which you can type in the desired text. Input ends with a line containing a lone period.

Once you've accumulated some log entries, you can use the command's -C, -P, and -E options to display them, either as continuous output, piped through a paging command like more (although less is the default), or via an editor (vi is the default). You can specify a different paging program or editor with the PAGER and EDITOR environment variables (respectively).

You can also use the -G option to search plod log files; it differs from grep in that matching entries are displayed in their entirety. By default, searches are not case sensitive, but you can use -g to make them so.

Here is an example command that searches the current log file:

$ plod -g hp-ux
-----
05/11/2001, 22:56 --
Starting to configure the new HP-UX box.
-----
05/11/2001, 23:44 --
Finished configuring the new HP-UX box.

Given these features, plod can be used to record and categorize the various tasks that you perform. We will look at a script which can read and summarize plod data in Chapter 14.


Chapter 10. Filesystems and Disks

Managing Unix filesystems is one of the system administrator's most importanttasks. You are responsible for ensuring that users have access to the files they need and that these files remain uncorrupted and secure. Administering afilesystem includes tasks such as:

  • Making local and remote files available to users

  • Monitoring and managing the system's disk resources

  • Protecting against file corruption, hardware failures, and user errors via a well-planned backup schedule

  • Ensuring data confidentiality by limiting file and system access

  • Checking for and correcting filesystem corruption

  • Connecting and configuring new storage devices when needed

Some of these tasks—such as checking for and correcting filesystem corruption—are usually done automatically at boot time, as part of the initial system startup. Others—like monitoring disk space usage and backups—are often done manually, on a periodic or as-needed basis.

This chapter describes how Unix handles disks and filesystems. It covers such topics as mounting and dismounting local and remote filesystems, the filesystem configuration file, making local filesystems available to remote Unix and Windows users, checking local filesystem integrity with the fsck utility, and adding new disks to the system. It also looks at some optional filesystem features offered in some Unix implementations.

We looked at file ownership and protection in Section 2.1. This chapter considers filesystem protection for network shared filesystems. Other related topics considered elsewhere in this book include the discussions in Chapter 15 of managing disk space with disk quotas (Section 15.6), disk I/O performance (Section 15.5), and planning for swap space (Section 15.4), and the discussion of planning and performing backups in Chapter 11.


10.1 Filesystem Types

Before any disk partition can be used, a filesystem must be built on it. When a filesystem is made, certain data structures are written to disk that will be used to access and organize the physical disk space into files (see Section 10.3, later in this chapter).

Table 10-1 lists the most importantfilesystem types available on the various systems we are considering.

Table 10-1. Important filesystem types

Use

AIX

FreeBSD

HP-UX

Linux

Solaris

Tru64

Default local

jfs or jfs2

ufs

vxfs[1]

ext3, reiserfs

ufs

ufs or advfs

NFS

nfs

nfs

nfs

nfs

nfs

nfs

CD-ROM

cdrfs

cd9660

cdfs

iso9660

hsfs

cdfs

Swap

not needed

swap

swap, swapfs

swap

swap

not needed

DOS

not supported

msdos

not supported

msdos

pcfs

pcfs

/proc

procfs

procfs

not supported

procfs

procfs

procfs

RAM-based

not supported

mfs[2]

not supported

ramfs, tmpfs

tmpfs

mfs

Other

union

hfs

ext2

cachefs

[1] HP-UX defines the default filesystem type in /etc/default/fs's LOCAL variable.

[2] This feature is deprecated and will be replaced by the md facility in Version 5.

10.1.1 About Unix Filesystems: Moments from History

In the beginning was the System V filesystem. Well, not really, but that's where we'll start. This filesystem type once dominated System V-based operating systems.[3]

[3] The filesystem that came to be known as the System V filesystem (s5fs) actually predates System V.

The superblock of standard System V filesystems contained information about currently available free space in the filesystem in addition to information about how the space in the filesystem is allocated. It held the number of free inodes and data blocks, the first 50 free inode numbers, and the addresses of the first 100 free disk blocks. After the superblock came the inodes, followed by the data blocks.

The System V filesystem was designed for storage efficiency. It generally used a small filesystem block size: 2K bytes or less (minuscule, in fact, by modern standards). Traditionally, a block is the basic unit of disk storage;[4] all files consume space in multiples of the block size, and any excess space in the last block cannot be used by other files and is therefore wasted. If a filesystem has a lot of small files, a small block size minimizes waste. However, small block sizes are much less efficient when transferring large files.

[4] This block is not related to the blocks used in the default output from commands like df and du. Use -k with either command to avoid having to worry about units.

The System V filesystem type is obsolete at this point. It is still supported on some systems for backward compatibility purposes only.

The BSD Fast File System (FFS) was designed to remedy the performance limitations of the System V filesystem. It supports filesystem block sizes of up to 64 KB. Because merely increasing the block size to this level would have had a horrendous effect on the amount of wasted space, the designers introduced a subunit to the block: the fragment. While the block remains the I/O transfer unit, the fragment becomes the disk storage unit (although only the final chunk of a file can be a fragment). Each block may be divided into one, two, four, or eight fragments.

Whatever its absolute performance status, the BSD filesystem is an unequivocal improvement over System V. For this reason, it was included in the System V.4 standard as the UFS filesystem type. This is its name on Solaris and Tru64 systems (as well as under FreeBSD). For a while, this filesystem dominated in the Unix arena.

In addition to performance advantages, the BSD filesystem introduced reliability improvements. For example, it replicates the superblock at various points in the filesystem (which are all kept synchronized). If the primary superblock is damaged, an alternate one may be used to access the filesystem (instead of it becoming unreadable). The utilities that create new filesystems report where the spare superblocks are located. In addition, the FFS spreads the inodes throughout the filesystem rather than storing them all at the start of the partition.

The BSD filesystem format has a more complex organizational structure as well. It is organized around cylinder groups: logical subcylinders of the total partition space. Each cylinder group has a copy of the superblock, a cylinder group map recording block use in its domain, and a fraction of the inodes for that filesystem (as well as data blocks). The data structures are placed at a different offset into each cylinder group to ensure that they land on different platters. Thus, in the event of limited disk damage, a copy of the superblock will still exist somewhere on the disk, as well as a substantial portion of the inodes, enabling significant amounts of data to be potentially recoverable. In contrast, if all of the vital information is in a single location on the disk, damage at that location effectively destroys the entire disk.

The Berkeley Fast File System is an excellent filesystem, but it suffers from one significant drawback: fsck performance. Not only does the filesystem usually need to be checked at every boot, the fsck process is also very slow. In fact, on current large disks, it can take hours.

10.1.1.1 Journaled filesystems

As a result, a different filesystem strategy was developed: journaled filesystems. Many operating systems now use such filesystems by default. Indeed, the current Solaris UFS filesystem type is a journaled version of FFS. In these filesystems, filesystem structure integrity is maintained using techniques from real-time transaction processing. They use a transaction log which is stored either in a designated location within the filesystem or in a separate disk partition set aside for this purpose.

As the filesystem changes, all metadata changes are recorded to the log, and writing entries to the log always precedes writing the actual buffers to disk.[5] In the case of a system crash, the entries in the log are replayed, which ensures that the filesystem is in a consistent state. This operation is very fast, and so the filesystem is available for essentially immediate use. Note that this mechanism is exactly equivalent to traditional fsck in terms of ensuring filesystem integrity. Like fsck, it has no effect on the integrity of the data.

[5] Writes to the log itself can be synchronous (forced to disk immediately) or buffered (written to disk only when the buffer fills up).

Journaled filesystems can also be more efficient than traditional filesystems. For example, the actual disk writes for multiple changes to the same metadata can be combined into a single operation. For example, when several files are added to a directory, then each one causes an entry to be written to the log, but all four of them can be combined in a single write to disk of the block containing the directory.

10.1.1.2 BSD soft updates

In the BSD world, development of the FFS continues. The current version offers a feature called soft updates designed to make filesystems available immediately at boot time.[6]

[6] For technical details about soft updates, see the articles "Metadata Update Performance in File Systems" by GregoryGanger and Yale Patt, published in the USENIX Symposium on Operating Systems Design and Implementation (1994; available in an expanded version online at http://www.ece.cmu.edu/~ganger/papers/CSE-TR-243-95.pdf) and "Soft Updates: A Technique for Eliminating Most Synchronous Writes in the Fast Filesystem" by Marshall Kirk McKusick and Gregory R. Ganger, published in the Proceedings of 1999 USENIX Annual Technical Conference (available online at http://www.usenix.org/publications/library/proceedings/usenix1999/mckusick.html). For a comparison of FFS with soft updates to journaled filesystems, see the paper "Journaling versus Soft Updates: Asynchronous Meta-data Protection in File Systems" by Margo I. Seltzer, Gregory R. Ganger, M. Kirk McKusick, Keith A. Smith, Craig A. N. Soules, and Christopher A. Stein, published in the Proceedings of 2000 USENIX Annual Technical Conference (available online at http://www.usenix.org/publications/library/proceedings/usenix2000/general/seltzer.html).

The usual FFS writes blocks to disk in a synchronous manner: in order, and waiting for each write operation to complete before stating the next one. In contrast, the soft updates method uses a delayed, asynchronous approach by maintaining a write-back cache formetadata blocks (a technique referred to as delayed writes). This often produces significant performance improvements in that many modifications to metadata can take place in memory rather than each one having to be performed on disk. For example, consider a directory tree removal. With soft updates, the metadata changes for the entire delete operation might be made in only a single write, a great savings compared to the traditional approach.

Of course, overlapping changes to metadata can also occur. To account for these situations, the soft updates facility maintains dependency data specifying the other metadata changes that a given update assumes have already taken place.

Blocks are selected for writing to disk according to an algorithm designed for overall filesystem efficiency. When it is time to write a metadata block to disk, soft updates reviews the dependencies associated with the selected block. If there are any dependencies that assume that other pending blocks will have been written first, the changes creating the dependencies are temporarily undone (rolled back). This allows the block to be written to disk while ensuring that the filesystem remains consistent. After the write operation completes, the rolled back updates to the block are restored, ensuring that the in-memory version contains the current data state. The system also removes dependency list entries that have been fulfilled by writing out that block.[7]

[7] Occasionally, soft updates require more write operations than the traditional method. Specifically, block roll forwards immediately make the block dirty again. If the block doesn't change again before it gets flushed to disk, an extra write operation occurs that would not otherwise have been necessary. The block selection algorithm attempts to minimize the number of rollbacks in order to avoid these situations.

Soft updates have the advantage that the only filesystem inconsistencies that can be caused by a crash are inodes and data blocks marked as in use that are actually free (consult the papers listed in the earlier footnote to see why this is true). Because these errors are benign, the filesystem can be made available for immediate use after rebooting. A background process similar to fsck is used to locate and correct these errors.

10.1.2 Default Local Filesystems

Table 10-2 lists the characteristics of thedefault local filesystem types for the various Unix versions.

Table 10-2. Default local filesystem characteristics

Item

AIX

FreeBSD

HP-UX

Linux (Red Hat)

Linux (SuSE)

Solaris

Tru64

Tru64

Type

jfs

ufs

vxfs

ext3

reiserfs

ufs

ufs

advfs

Journaled

yes

soft updates

yes

yes

yes

yes

no

yes

64 bit (files>2 GB)

yes

yes

yes

yes

yes

yes

yes

yes

Dynamic resizing

yes

yes

yes

yes

yes

yes[8]

no

yes[9]

Sparse file support

yes

yes

yes

no

yes

yes

yes

yes

NFSv3 support

yes

yes

yes

yes

yes

yes

yes

yes

dump version provided

yes

yes

yes

yes

no

yes

yes

yes

[8] Solaris 9 only

[9] Requires the AdvFS utilities (additional cost option)


10.2 Managing Filesystems

This section covers such topics as mounting and dismounting local and remote filesystems, the filesystem configuration file, and checking local filesystem integrity with the fsck utility: in other words, the nitty gritty details of managing filesystems.

10.2.1 Mounting and Dismounting Filesystems

Mounting is the process that makes a filesystem's contents available to the system, merging it into the system directory tree. A filesystem can bemounted or dismounted: that is, it can be connected to or disconnected from the overall Unix filesystem. The only exception is the root filesystem, which is always mounted on the root directory while the system is up and cannot be dismounted.

Thus, in contrast to some other operating systems, mounting a Unix filesystem does more than merely make its data available. Figure 10-1 illustrates the relationship between a system's disk partitions (and their corresponding special files) and its overall filesystem. On this system, the root filesystem—the filesystem stored on the first partition of the root disk (disk 0)—contains the standard Unix subdirectories /bin, /etc, and so on. It also contains the empty directories /home, /var, and /chem, which serve as mount points for other filesystems. This filesystem is accessed via the special file /dev/dsk/c1d0s0.

Figure 10-1. Mounting disk partitions within the Unix filesystem

The figure also shows several other filesystems. One of them, accessed via the special file /dev/dsk/c1d0s8 (partition 8 of the root disk), contains the files and directories under /var. A third filesystem—partition 9 on disk 1—is accessed via the special file /dev/dsk/c1d1s9 and contains users' home directories, located under /home.

Another filesystem on this system is stored on partition 2 of disk 1 and is accessed via the special file /dev/dsk/c1d1s2. Its own root directory contains the subdirectories ./organic and ./inorganic and their contents. We'll call this the /chem filesystem, after its mount point within the system's directory tree. When /dev/dsk/c1d1s2 is mounted, these directories will become subdirectories of /chem.

One of the directories in the /chem filesystem, ./inorganic, is empty and is to be used as the mount point for yet another filesystem. The files in this fifth filesystem, on partition 2 on disk 2 and corresponding to the special file /dev/dsk/c1d2s2, become a subtree of the /chem filesystem when mounted.

The files in the root directory and its system subdirectories all come from disk 0, as do the empty directories /chem, /home, and /var before filesystems are mounted on them. Figure 10-1 illustrates the fact that the contents of the /chem directory tree come from two different physical disks.

In most cases, there is no necessary connection between a given filesystem and a particular disk partition (and its associated special file), for example, between the /chem filesystem and the special file /dev/dsk/c1d1s2. The collection of files on a disk partition can be mounted on any directory in the filesystem. After it is mounted, its top-level directory is accessed via the directory path where it is mounted, and it is often referred to by that directory's name.

At the same time, the root directory of the mounted filesystem replaces the directory where the filesystem is mounted. As a side effect, any files that were originally in the mount directory—in this example, any files that might have been in /chem prior to mounting the new filesystem—disappear when the new filesystem is mounted and thus cannot be accessed; they will reappear once the filesystem is dismounted.

To illustrate this phenomenon, let's watch a filesystem being mounted:

# ls -saC /chem                                 /chem's contents before mount.
total 20
4 .             4 ..            12 README
# mount /dev/dsk/c1d1s2 /chem                  Mount partition 2 on disk 1.
# ls -saC /chem                                /chem's contents after mount.
total 48
4 .             4 ..             4 inorganic      32 lost+found
4 organic
# du -s /chem                                  /chem is much bigger.
587432 /chem

Before the filesystem is mounted, there is just one ordinary file in /chem: README. After /dev/dsk/c1d1s2 is mounted, README disappears. It's still on the root disk, but it can't be accessed while the /chem filesystem is mounted.However, it will reappear when the filesystem is dismounted. After the filesystem is mounted, the subdirectories organic and inorganic appear, along with their contents (reflected in the larger amount of data under /chem).

On most Unix systems, a filesystem can only be mounted in one place at one time (Linux is an exception).

10.2.2 Disk Special File Naming Conventions

We looked at disk special filenames in detail in Section 2.3. The following list reviews the disk special file naming conventions for a SCSI disk under the various operating systems we are considering by listing the special file used for a partition on the third SCSI disk (SCSI ID 4) on the first SCSI controller (accessed in raw mode):[10]

[10] Under FreeBSD 4, the block and raw devices are equivalent. Character devices are vestigial in Version 4 and are slated to be removed in FreeBSD Version 5.

AIX
/dev/hdisk2 (refers to the entire disk)
FreeBSD
/dev/da0s1e (short form: /dev/da1c)
HP-UX
dev/rdsk/c0t4d0
Linux
/dev/sdc1
Solaris
/dev/rdsk/c0t4d0s7
Tru64
/dev/rdisk/dsk2c

10.2.3 The mount and umount Commands

To mount a filesystem manually, use the mount command as follows:

# mount  [-o  options ] block-special-file    mount-point

This command mounts the filesystem located on the specified disk partition. The root directory on this filesystem will be attached at mount-point within the overall Unix filesystem. This directory must already exist before the mount command is executed.

For example, the commands:

# mkdir /users2
# mount /dev/dsk/c1t4d0s7 /users2

create the directory /users2 and mount the filesystem located on the disk partition /dev/dsk/c1t4d0s7 on it. On some systems, mount's -r option may be used to mount a filesystem read-only. For example:

# mount -r /dev/dsk/c1t4d0s7 /mnt

Use mount without options to display a list of currently mounted filesystems.

The mount command can also be used to mount remote filesystems via NFS. We'll consider this use later in this chapter.

The umount command may be used to dismount filesystems:

# umount  name

This command dismounts the filesystem specified by name, where name is either the name of the filesystem's block special file or the name of the mount point where this filesystem is mounted. The -f option may be used to force an dismount operation in some cases (e.g., when there are open files), but it should be used with caution.

This section has illustrated only the simplest uses of mount and umount. We'll look at many more examples in the course of this chapter.

10.2.4 Figuring Out Who's Using a File

Filesystems must be inactive before they can be dismounted. If any user has one of a filesystem's directories as her current directory or has any file within the filesystem open, you'll get an error message something like this one if you try to unmount that filesystem:

umount: /dev/hdb1: device is busy

The fuser command may be used to determine whichfiles within a filesystem are currently in use and to identify the processes and users that are using them. If fuser is given a filename as its argument, it reports on that file alone. If it is given a disk special filename as its argument, it reports on all files within the corresponding filesystem. The -u option tells fuser to display user ID's as well as PID's in its output.

For example, the following command displays all processes and their associated users that are using files on the specified disk on an HP-UX system:

$ fuser -u /dev/dsk/c1t1d0

Under Linux, including the -m option will allow you to specify the filesystem by name; the -c option performs the same function under Solaris.

Here is an example of fuser's output:

/chem: 3119c(chavez) 3229(chavez)  3532(harvey)  3233e(wang)

Four processes are using the /chem filesystem at this moment. Users chavez and harvey have open files, indicated by the second and third process IDs, which appear without a final code letter. User chavez also has her current working directory within this filesystem (indicated by the c code after the first PID), and user wang is running a program whose executable resides within the filesystem (indicated by the e code after the final PID).

fuser's -k option may be used to kill all of the processes using the specified file or filesystem.

The lsof command performs a similar function on FreeBSD systems (and is also available for the other operating systems as well). Its output is a great deal more detailed. Here is a small part of its output (shortened to fit):

COMMAND PID   USER     FD    TYPE     DEVICE  NAME
vi      74808 aefrisch cwd   VDIR 116,131072  /usr/home/aefrisch
vi      74808 aefrisch rtd   VDIR 116,131072  /
vi      74808 aefrisch txt   VREG 116,131072  /usr/bin/vi
vi      74808 aefrisch txt   VREG 116,131072  /usr/libexec/ld-elf.so.1
vi      74808 aefrisch txt   VREG 116,131072  /usr/lib/libncurses.so.5
vi      74808 aefrisch txt   VREG 116,131072  /usr/lib/libc.so.4
vi      74808 aefrisch   0   VCHR        0,0  /dev/ttyp0
vi      74808 aefrisch   1   VCHR        0,0  /dev/ttyp0
vi      74808 aefrisch   2   VCHR        0,0  /dev/ttyp0
vi      74808 aefrisch   3-W VREG 116,131072  /usr/home/aefrisch/.login
vi      74808 aefrisch   4   VREG 116,131072  /var/tmp/vi.recover/vi.CJ6cay
vi      74808 aefrisch   5   VREG 116,131072  / (/dev/ad0s1a)

These are the entries generated by a vi process editing this user's .login file. Note that this file is opened for writing, indicated by the W following the file descriptor number (column FD).

FreeBSD also provides the fstat command, which performs a similar function.

10.2.5 The Filesystem Configuration File

Mounting filesystems by hand every time they are needed would quickly become tedious, so the required mount commands are generally executed automatically at boot time. The filesystem configuration file typically contains information about all of the system's filesystems, for use by mount and other commands.[11]

[11] This section covers only local disks. We'll look at entries for remote disks later in this chapter.

/etc/fstab is the standard Unix filesystem configuration file. It generally has the following format:

special-file  mount-dir  fs-type  options  dump-freq  fsck-pass

The fields have the following meanings:

special-file

The name of the special file on which the filesystem resides. This must be a block device name.

mount-dir

The directory on which to mount the filesystem. If the partition will be used for swapping, / is sometimes used for this field.

fs-type

The filesystem type. The value for local filesystems is highly version-dependent. Common type values are nfs for volumes mounted remotely via NFS, swap or sw for swap partitions (although Tru64 uses UFS for these as well, and HP-UX also has the swapfs type for paging to a file within the filesystem), and ignore, which tells mount to ignore the line. Available filesystem types for the various Unix versions are listed later in this chapter.

options

This field consists of one or more options, separated by commas. The fs-type field, above, determines which options are allowed for any given kind of filesystem. For ignore type entries, this field is ignored.

Multiple options are separated by commas, without intervening spaces. On many systems, the keyword defaults may be placed into this field if no options are needed. Table 10-3 lists commonly used options for local filesystems and paging/swap spaces.

dump-freq

A decimal number indicating the frequency with which this filesystem should be backed up by the dump utility. A value of 1 means backup should occur every day, 2 means every other day, and so on. A value of 0 means that the device is not to be backed up (for example, swap devices). Not all systems actually use this field.

fsck-pass

A decimal number indicating the order in which fsck should check the filesystems. A value of 1 indicates that the filesystem should be checked first, 2 indicates that the filesystem should be checked second, and so on. The root and/or boot filesystems generally have the value 1. All other filesystems generally have higher pass numbers. For optimal performance, two filesystems that are on the same disk drive should have different pass numbers; however, filesystems on different drives may have the same pass number, letting fsck check the two filesystems in parallel. fsck will usually be fastest if all filesystems checked on the same pass are roughly the same size. This field should be 0 for swap devices (0 disables checking by fsck).

Table 10-3. Commonly used filesystem options

Option

Meaning

rw

Read-write filesystem (default for read-write devices).

ro

Read-only filesystem (default for read-only media such as CDs).

nosuid

The SetUID access mode is ignored within this filesystem; suid is the default.

noauto

Don't automatically mount this filesystem at boot time; auto is the default (Linux, FreeBSD).

noexec

Prevent binary programs from executing; exec is the default (Linux, FreeBSD, Tru64).

nodev

Prevent device access via special files (AIX, Linux, FreeBSD, Tru64).

user

Allow ordinary users to mount this filesystem (Linux).

nogrpid

Use System V-style group ownership inheritance for new files (i.e., the owner's primary group); BSD-style is the default (Linux, Tru64).

resuid=n resgid=n

Set the UID/GID that has access to the reserved blocks with the filesystem (Linux ext2/ext3).

largefiles

Support files larger than 2 GB (HP-UX VxFS, Solaris).

logging

Maintain a transaction log (Solaris). The default is nologging.

delaylog

Delay writing log entries slightly to improve performance, increasing risk of loss slightly. (HP-UX VxFS)

writeback

Write out log metadata and filesystem blocks in either order, for a slight performance improvement and increased risk of loss in the event of a crash (Linux ext3).

nolog

Don't use a transaction log (HP-UX VxFS).

nologging

Don't use a transaction log (Solaris).

forcedirectio

Use direct I/O to this filesystem: i.e., no buffering (Solaris). Useful for certain applications such as databases.

notail

Disable default behavior of storing small files directly within the hash tree (Linux ReiserFS).

resize=n

Resize the filesystem to n blocks on mounting (Linux ReiserFS).

rq

Mount read-write and enable disk quotas (Tru64).

quota

Enable disk quotas (HP-UX, Solaris).

userquota groupquota

Enable user/group disk quotas (FreeBSD).

usrquota grpquota

Enable user/group disk quotas (Linux).

pri=n

Set swap space priority (0 to 32767). Under Linux, higher numbers indicated more favored areas, which are used first; HP-UX favors lower priority areas.

xx

Ignore this entry (FreeBSD).

Here are some typical /etc/fstab entries, defining one or more local filesystems, a CD-ROM drive, and aswap partition:

# FreeBSD
# device           mount         type      options         dump fsck
/dev/ad0s1a        /             ufs       rw                 1 1
/dev/cd0c          /cdrom        cd9660    ro,noauto          0 0
/dev/ad0s2b        none          swap      sw                 0 0

# Linux
# device           mount         type      options         dump fsck
/dev/sda2          /             reiserfs  defaults           1 1
/dev/sda1          /boot         ext2      defaults           1 2
/dev/cdrom         /cdrom        auto      ro,noauto,user     0 0
/dev/sda3          swap          swap      pri=42             0 0

# HP-UX
# device           mount         type      options         dump fsck
/dev/vg00/lvol3    /             vxfs      defaults           0 1
/dev/vg00/lvol1    /stand        hfs       defaults           0 1
/dev/dsk/c1t2d0    /cdrom        cdfs      defaults           0 0
/dev/vg01/swap     ...           swap      pri=0              0 0

# Tru64
# device           mount         type      options         dump fsck
root_domain#root   /             advfs     rw                 0 1
/dev/disk/cdrom0c  /cdrom        cdfs      ro                 0 2
# swap partition is defined in /etc/sysconfigtab

HP-UX and Tru64 use a logical volume manager by default for all local disks. Accordingly, the devices specified in /etc/fstab refer to logical volumes rather than actual disk partitions. Hence the rather strange device names in their examples. Logical volume managers are discussed later in this chapter.

Tru64 specifies swap partitions via the following stanza in the /etc/sysconfigtab file:

vm:
   swapdevice = /dev/disk/dsk0b
10.2.5.1 Solaris: /etc/vfstab

Solaris uses a different filesystem configuration file, /etc/vfstab , which has a somewhat different format:

block-special-file char-special-file  mount-dir fs-type fsck-pass auto-mount? options

The ordering of the normal fstab fields is changed somewhat, and there are two additional ones. The second field holds the character device corresponding to the block device in the first field (which is used by the fsck command). The sixth field specifies whether the filesystem should be mounted automatically at boot time (note that the root filesystem is set to no).

Here is an example file:

# Solaris
# mount            fsck
# device           device             mount  type  fsck  auto?  options
/dev/dsk/c0t3d0s2 /dev/rdsk/c0t3d0s0  /      ufs    1    no     rw
/dev/dsk/c0t3d0s0 /dev/rdsk/c0t3d0s0  /home  ufs    2    yes    rw,logging
/dev/dsk/c0t3d0s1 -                   -      swap   -    no     -

Note that hyphens are placed in unused fields.

10.2.5.2 AIX: /etc/filesystems and /etc/swapspaces

The filesystem configuration file under AIX is /etc/filesystems . This file is updated automatically by various AIX filesystem manipulation commands, including crfs, chfs, and rmfs. /etc/filesystems contains all the information in /etc/fstab and some additional data as well, arranged in a stanza-based format. Here are some example entries:

/:
       dev     = /dev/hd4                  Disk device.
       vol     = "root"                    Descriptive label.
       vfs     = jfs2                      Filesystem type.
       mount   = automatic                 Mount automatically with mount -a.
       check   = true                      Check with fsck if needed.
       log     = /dev/hd8                  Device to use for filesystem log.

/chem:
       dev     = /dev/us00                 Logical volume.
       vol     = "chem"                    Descriptive label.
       vfs     = jfs2                      Filesystem type.
       log     = /dev/loglv01              Device to use for filesystem log.
       mount   = true                      Mount automatically with mount -a.
       check   = 2                         Sets the fsck pass.
       options = rw,nosuid                 Mount options.
       quota   = userquota                 Enable user disk quotas.

Each mount point in the overall filesystem has its own stanza, specifying which logical volume (equivalent to a disk partition for this purpose) is to be mounted there. Like HP-UX and Tru64, AIX uses a logical volume manager by default (discussed later in this chapter).

Under AIX, paging logical volumes are listed in /etc/swapspaces , rather than in the filesystem configuration file. That file is maintained by paging space administration commands such as mkps, chps, and rmps, and its format is very simple:

hd6:
     dev = /dev/hd6

paging00:
     dev = /dev/paging00

This sample file lists two paging areas.

10.2.6 Automatic Filesystem Mounting

Regardless of its form, once the filesystem configuration file is set up, mounting may take place automatically. mount's -a option may be used to mount all filesystems that the filesystem configuration file says should be mounted on most systems. In addition, if a filesystem is included in the filesystem configuration file, the mount and umount commands will now require only the mount point or the special file name as their argument. For example, the command:

# mount /chem

looks up /chem in the filesystem configuration file to determine what special file is used to access it and then constructs and performs the proper mount operation. Similarly, the following command dismounts the filesystem on special file /dev/disk1d.:

# umount /dev/disk1d

umount also has a -a option to dismount all filesystems.

Both mount and umount have options to specify the type of filesystem being mounted or dismounted. Generally, this option is -t, but HP-UX and Solaris use -F, and AIX uses -v. This option may be combined with -a to operate on all filesystems of a given type. For example, the following command mounts all local filesystems under Tru64:

# mount -a -t advfs

FreeBSD, Tru64, and Linux also allow a type keyword to be preceded with no, causing the command to operate on all filesystem types except those listed. For example, this Linux command mounts all filesystems except DOS filesystems and remote (NFS) filesystems:

# mount -tnomsdos,nfs -a

Finally, under FreeBSD, Tru64, and Solaris, umount has a -h option that unmounts all remote filesystems from a specified host. For example, this command unmounts all filesystems from dalton:

# umount -h dalton

Under AIX, the -n option performs the same function.

10.2.7 Using fsck to Validate a Filesystem

A number of problems, ranging from operator errors to hardware failures, can corrupt a filesystem. The fsck utility ("filesystem check") checks the filesystem's consistency, reports any problems it finds, and optionally repairs them. Only under very rare circumstances will these repairs cause even minor data loss.

The equivalent utility for Tru64 AdvFS filesystems is verify (located in /sbin/advfs).

fsck can find the following filesystem problems:

  • One block belonging to several files (inodes).

  • Blocks marked as free but in use.

  • Blocks marked as used but free.

  • Incorrect link counts in inodes (indicating missing or excess directory entries).

  • Inconsistencies between inode size values and the number of data blocks referenced in address fields.

  • Illegal blocks (e.g., system tables) within files.

  • Inconsistent data in the filesystem's tables.

  • Lost files (nonempty inodes not listed in any directory). fsck places these files in the directory named lost+found in the filesystem's top-level directory.

  • Illegal or unallocated inode numbers in directories.

Basically, fsck performs a consistency check on the filesystem, comparing such items as the block free list against the disk addresses stored in the inodes (and indirect address blocks) and the inode free list against inodes in directory entries. It is important to understand that fsck's scope is limited to repairing the structure of the filesystem and its component data structures. The utility can do nothing about corrupted data within structurally intact files.

On older BSD-style systems, the fsck command is run automatically on boots and reboots. Under the System V scheme, fsck is run at boot time on filesystems only if they were not dismounted cleanly (e.g., if the system crashed). System administrators rarely need to run this utility manually: on boots when it finds serious problems (because fsck's automatic mode isn't authorized to repair all problems), after creating a new filesystem, and under a few other circumstances. Nevertheless, you need to understand how fsck works so that you'll be able to verify that the system boots correctly and to quickly recognize abnormal situations.

fsck has the following syntax:

# fsck  [options ] device

device is the special file for the filesystem. fsck runs faster on a character special file. If the device is omitted—as it is at boot time—all filesystems listed in the filesystem configuration file will be checked (all filesystems whose check attribute is not false will be checked under AIX).

On all systems except FreeBSD and Linux, the block device must be specified for the root filesystem in order to check it with fsck.

If fsck finds any problems, it asks whether or not to fix them. The example below shows a fsck report giving details about several filesystem errors and prompting for input as to what action to take:

# fsck /dev/rdisk1e
/dev/rdisk1e
** Phase 1--Check Blocks and Sizes
POSSIBLE FILE SIZE ERROR I = 478
** Phase 2--Check Pathnames
** Phase 3--Check Connectivity
** Phase 4--Check Reference Counts
UNREF FILE I = 478  OWNER = 190  MODE = 140664
SIZE = 0  MTIME = Sept 18 14:27 1990
CLEAR? y

FREE INODE COUNT WRONG IN SUPERBLOCK
FIX? y

** Phase 5--Check Cylinder Groups
1243 files   28347 blocks  2430 free
*** FILE SYSTEM WAS MODIFIED ***

fsck found an unreferenced inode—aninode marked as in use but not listed in any directory. fsck's output indicates its inode number, owner UID, and mode. From this information, we can figure out that the file is owned by user chavez and is a socket. The mode is interpreted as illustrated in Figure 10-2.

Figure 10-2. Interpreting fsck output

The first one or two digits of the mode indicate the file type: in this case, a socket that can be safely removed.

The available options for fsck allow automatic correction of the filesystem to take place (or be prevented):

-p

Preen the filesystem; automatically perform repairs that don't change any file's contents.

-n

Answer no to all prompts: list but don't repair any problems found.

-y

Answer yes to all prompts: repair all damage regardless of severity. Use this option with caution.[12]

[12] At the same time, it's not clear what alternatives you have. You can't mount a damaged filesystem, and, unless you're a real wizard regarding filesystem internals, fsck is the only tool available for fixing the filesystem.

-P

Preen the filesystem only if it is dirty (Tru64).

-f

Force a check even if the filesystem is clean (Linux).

-b n

Use an alternate superblock located at block n (BSD-style syntax). 32 is always an alternate superblock.

fsck is normally run with the -p option. In this mode, the following problems are silently fixed:

  • Lost files will be placed in the filesystem's lost+found directory, named for their inode number.

  • Link counts in inodes too large.

  • Missing blocks in the free list.

  • Blocks in the free list also in files.

  • Incorrect counts in the filesystem's tables.

  • Unreferenced zero-length files are deleted.

More serious errors will be handled with prompts as in the previous example.

For UFS filesystems under Solaris, the BSD-style options are specified as arguments to the -o option (the filesystem type-specific options flag). For example, the following command checks the UFS filesystem on /dev/dsk/c0t3d0s2 and makes necessary nondestructive corrections without prompting:

# fsck -F ufs -o p /dev/dsk/c0t3d0s2
10.2.7.1 After fsck

If fsck modifies any filesystem, it will print a message like:

*** FILE SYSTEM WAS MODIFIED ***

If the root filesystem was modified, an additional message will also appear, indicating additional action needed:

BSD-style if the automatic filesystem remount fails:
mount reload of /dev/device failed:
*** REBOOT NOW ***

System V-style:
***** REMOUNTING ROOT FILE SYSTEM *****

If this occurs as part of a normal boot process, the remount or reboot will be initiated automatically. If fsck has been run manually on the root filesystem on a BSD system, the rebooting command needs to be entered by hand. Use the reboot command with the -n option:

# reboot -n

The -n option is very important. It prevents the sync command from being run, which flushes the output buffers and might very well recorrupt the filesystem. This is the only time when rebooting should occur without syncing the disks.


10.3 From Disks to Filesystems

As we've seen, the basic Unix file storage unit is the disk partition. Filesystems are created on disk partitions, and all of the separate filesystems are combined into a single directory tree. The initial parts of this section discuss the process by which a physical disk becomes one or more filesystems on a Unix system, treating the topic at a conceptual level. Later subsections discuss the mechanics of adding a new disk to the various operating systems we are considering.

10.3.1 Defining Disk Partitions

Traditionally, the Unix operating system organizes disks into fixed-size partitions, whose sizes and locations are determined when the disk is first prepared (as we'll see). Unix treats disk partitions as logically independent devices, each of which is accessed as if it were a physically separate disk. For example, one physical disk may be divided into four partitions, each of which holds a separate filesystem. Alternatively, a physical disk may be configured to contain only one partition comprising its entire capacity.

Many Unix implementations allow several physical disks to be combined into a single logical device or partition upon which you can build a filesystem. Systems offering a logical volume manager carry this trend to its logical conclusion, allowing multiple physical disks to be combined into a single logical disk, which can then be divided into logical partitions. AIX uses only an LVM and does not use traditional partitions at all.

Physically, adisk consists of a vertical stack of equally spaced circular platters. Reading and writing is done by a stack of heads that move in and out along the radius as the platters spin around at high speed. The basic idea is not so different from an audio turntable—I hope you've seen one—although both sides of the platters can be accessed at once.[13]

[13] Also, the disk tracks are concentric, not continuous, as they are on an LP. If you don't know what an LP is, think of it as a really wide CD (about 12" diameter) with data on both sides.

Partitions consist of subcylinders[14] of the disk: specific ranges of distance from the spindle (the vertical center of the stack ofplatters): e.g., from one inch to two inches, to make up an arbitrary example. Thus, a disk partition uses the same sized and located circular section on all the platters in the disk drive. In this way, disks are divided vertically, through the platters, not horizontally.

[14] I'm using this term in a descriptive sense only. Technically, a disk cylinder consists of the same set of tracks on all the platters that make up the disk (where a track is the portion of the platter surface that can be accessed from one of the discrete radial positions that the head can take as its moves along the radius).

Partitions can be defined as part of adding a new disk. In some versions of Unix, default disk partitions are defined in advance by the operating system. These default definitions provide some amount of flexibility by defining more than one division scheme for the physical disk.

Figure 10-3 depicts a BSD-stylepartition scheme. Each drawing corresponds to a different disk layout: one way of dividing up the disk. The various cylinders graphically represent each partition's location on the disk. The solid black area at the center of each disk indicates the part of the disk that cannot be accessed, containing the bad block list and other disk data.

Figure 10-3. Sample disk partitioning scheme

Readers who prefer numeric to graphical representations can consider the numeric partitioning scheme in Table 10-4, which illustrates the same point.

Table 10-4. Sample disk partitioning scheme

Partition

Start

End

a

655360

671739

b

327680

655359

c

0

671739

d

163840

327679

e

0

163839

f

327680

671739

g

0

327679

Seven different partitions are defined for the disk, named by letters from a to g. Three drawings are needed to display all seven partitions because some of them are defined to occupy the same disk locations.

Traditionally, the c partition comprised the entire disk, including the forbidden area; this is why the c partition was never used under standard BSD. However, on most current systems using this sort of naming convention, you can use the c partition to build a filesystem that uses the entire disk. Check the documentation if you're unsure about the conventions on your system.

The other six defined partitions are a, b, and d through g. However, it is not possible to use them all at one time, because some of them include the same physical areas of the disk. Partitions d and e occupy the same space as partition g in the sample layout. Hence, a disk will use either partitions d and e, or partition g, but not both. Similarly, the a and b partitions use the same area of the disk as partition f, and partitions f and g use the same area as partition c.

Thisdisk layout, then, offers three different ways of using the disk, divided into one, two, or four partitions, each of which may hold a filesystem or be used as a swap partition. Some disk partitioning schemes offer even more alternative layouts of the disk. Flexibility is designed in to meet the needs of different systems.

NOTE

This flexibility also has the following consequence: nothing prevents you from using a disk drive inconsistently. For example, nothing prevents you from mounting /dev/disk2d and /dev/disk2g from the same disk. However, this will have catastrophic consequences, because these two partitions overlap. Best practice is to modify partitions in a standard layout that you will not be using so that they have zero length (or delete them).

These days, the following partition naming conventions generally apply:

  • The partition holding the root (or boot) filesystem is the first one on the disk and is named partition a or slice 0.

  • The primary swap partition is normally partition b/slice 1.

  • Partition c and slice 2 refer to the entire disk.

10.3.2 Adding Disks

In this section, we'll begin by examining the general process of adding a disk to a Unix system and then go on to consider the commands and procedures for the various operating systems. The following list outlines the steps needed to make a new disk accessible to users:

  • The disk must be physically attached to the computer system. Consult the manufacturer's instructions and your own system's hardware documentation for the procedure.

  • A suitable device driver for the disk's controller must be present in the operating system. If the new disk is being added to an existing controller, or you're also adding a new controller that is among those supported by the operating system, this is not a problem. Otherwise, you'll need to build a new kernel or load the appropriate kernel module (see Chapter 16).

  • The disk must be low-level formatted.[15] These days, this is always done by the manufacturer.

    [15] What I'm referring to here is not what is meant when one "formats" a diskette or disk on a PC system. In general, microcomputer operating systems like Windows use the term format differently than Unix does. Formatting a disk on these systems is equivalent to making a filesystem under Unix (and most other operating systems). Unix disk formatting is equivalent to what Windows calls a low-level format. This step is almost never needed in either environment.

  • One or more partitions must be defined on the disk.

  • The special files required to access the disk's partitions must exist or be created.

  • A Unix filesystem must be created on each of the disk partitions to be used for user files.

  • The new filesystem should be checked with fsck.

  • The new filesystem should be entered into the filesystem configuration file.

  • The filesystem can be mounted (perhaps after creating a new directory for its mount point).

  • Any site-specific activities must be performed (such as configuring backups and installing disk quotas).

The processes used to handle these activities will be discussed in the sections that follow.

As usual, planning should precede implementation. Before performing any of these operations, the system administrator must decide how the disk will be used: which partitions will have filesystems created on them and what files (types of files) will be stored in them. The layout of your filesystems can influence your system's performance significantly. You should therefore take some care in planning the structure of your filesystem.

For best performance, heavily used filesystems should each have their own disk drive, and they should not share a disk with aswap partition. Preferably, heavily used filesystems should be located on drives attached to different controllers. This setup balances the load between disk drives and disk controllers. These issues are discussed in more detail in Section 15.5. Coming up with the optimal layout may require consulting with other people: the database administrator, software developers, and so on.

We now turn to the mechanics of adding a new disk. We'll begin by considering aspects of the process that are common to all systems. The subsequent subsections discuss adding a new SCSI disk to each of the various Unix versions we are considering.

Finding a Hardware/Software Balance

Some system administrators love tinkering with hardware; the most hard-core of them consider reseating the CPU boards as the first response to any system glitch. At the other extreme are system administrators who can program their way out of any emergency but throw up their hands when they have to install a new disk drive.

A good system administrator will be able to hold her own in both the hardware and software arenas. Most of us tend to prefer one to the other, but we can all become proficient in both areas in the long run. The best way to improve your skills in whatever areas you feel least comfortable is to find a safe test system where you can learn, experiment, play, and make mistakes in private and without risk. In time, you may even find that you actually enjoy doing jobs that used to bore, disgust, or intimidate you.

10.3.2.1 Preparing and connecting the disk

There are two main types of disks in wide use today: IDEdisks and SCSI disks. IDE[16] disks are low cost devices developed for the microcomputer market, and they are generally used on PC-based Unix systems. SCSI disks are generally used on (non-Intel) Unix workstations and servers from the major hardware vendors. IDE disks generally do not perform as well as SCSI disks (claims made by ATA-2 drive vendors notwithstanding).

[16] IDE expands to Integrated Drive Electronics. These disks are also known as ATA disks (AT Attachment). Current IDE disks are virtually always EIDE: extended IDE, a follow-on to the original standard. SCSI expands to Small Computer System Interface.

IDE disks are easy to attach to the system, and the manufacturer's instructions are generally good. When you add a second disk drive to an IDE controller, you will usually need to perform some minor reconfiguration for both the existing and new disks. One disk must be designated as the master device and the other as the slave device; generally, the existing disk becomes the master and the new disk is the slave.

The master/slave setting for a disk is specified by means of a jumper on the disk drive itself, and it is almost always located on the same face of the disk as the bus and power connector sockets. Consult the documentation for the disk you are using to determine the jumper location and proper setting. Doing so on the new drive is easy because you can do it before you install the disk. Remember to check the existing drive's configuration as well, because single drives are often left unjumpered by the manufacturer. Note that the master/slave setting is not an operational definition; the two disks are treated equally by the operating system.

SCSI disks are in wide use in both PC-based systems and traditional Unix computers. When performance counts, use SCSI disks, because high-end SCSI subsystems are many times faster than the best EIDE-based ones. The SCSI subsystems are also more expensive than the best EIDE-based ones.

SCSI disks may be internal or external. These disks are designated by a number ranging from 0 to 6 known as their SCSI ID (the SCSI ID 7 is used by the controller itself). Normal SCSI adapters thus support up to seven devices, each of which must be assigned a unique SCSI ID; wide SCSI controllers support up to 15 devices (ID 7 is still used for the controller). SCSI IDs are generally set via jumpers on internal devices and via a thumbwheel or push button counter on external devices. Keep in mind that when you change the ID setting of a SCSI disk, the device must generally be power-cycled before the change will take effect.

On rare occasions, the ID display setting on an external SCSI disk will not match what is actually being set. When this happens, the counter is either attached incorrectly (backwards) or faulty (the SCSI ID does not change even though the counter does). When you are initially configuring a device, check the controller's power-on message to determine whether all devices are being recognized and to determine the actual SCSI ID assignments being used. Once again, these problems are rare, but I have seen two examples of the former and one example of the latter in my career.

SCSI disks come in many varieties; the current offerings are summarized in Table 10-5. You should be aware of the distinction between normal and differentialSCSI devices. In the latter type, there are two physical wires for each signal within the bus, and such devices use the voltage difference between the two wires as the signal value. This design reduces noise on the bus and allows for longer total cable lengths. Special cables and terminators are needed for such SCSI devices (as well as adapter support), and you cannot mix differential and normal devices. Differential signaling has used two forms over the years, high voltage differential (HVD) and low voltage differential (LVD); the two forms cannot be mixed. The most recent standards employ the latter exclusively.

Table 10-5. SCSI versions
Maximum total cable length

Version name

Single-ended

Bus width

Differential

Maximum speed

SCSI-1, SCSI-2

5 MB/s

8 bits

6 m

25 m (HVD)

Fast SCSI

10 MB/s

8 bits

3 m

25 m (HVD)

Fast Wide SCSI

20 MB/s

16 bits

3 m

25 m (HVD)

Ultra SCSI

20 MB/s

8 bits

1.5 m

25 m (HVD)

Wide Ultra SCSI

40 MB/s

16 bits

1.5 m

25 m (HVD)

Ultra2 SCSI

40 MB/s

8 bits

n/a

12 m (HVD), 25 m (LVD)

Wide Ultra-2 SCSI

80 MB/s

16 bits

n/a

12 m (HVD), 25 m (LVD)

Ultra3 SCSI (a.k.a. Ultra160 SCSI)

160 MB/s

16 bits

n/a

12 m (LVD)

Ultra320 SCSI

320 MB/s

16 bits

n/a

12 m (LVD)

Table 10-5 can also serve as a simple history of SCSI. It shows the progressively faster speeds these devices have been able to obtain. Speed-ups come from a combination of a faster bus speed and using more bits for the bus (the "wide" devices). The most recent SCSI standards are all 16 bits, and the term "wide" has been dropped from the name because there are no "narrow" devices from which they need to be distinguished.

The maximum total cable length in the table refers to a chain consisting entirely of devices of that type. If you are using different (compatible) device types in the same chain, the maximum length is the minimum allowed for the various device types. Lowest common denominator wins in this case.

There are a variety of connectors that you will encounter on SCSI devices. These are the most common:

  • DB-25connectors are 25-pin connectors that resemble those on serial cables. They have 25 rounded pins positioned in two rows about 1/8" apart. For example, these connectors are used on external SCSIZip drives.

  • 50-pin Centronics connectors were once the most common sort of SCSI connector. The pins on the connector are attached to the top and bottom of a narrow flat plastic bar about 2" long, and the connector is secured to the device by wire clips on each end.

  • 50-pin micro connectors (also known as mini-micro connectors or SCSI II connectors) are distinguished by their flat, very closely spaced pins, also placed in two rows. This connector is much narrower than the others at about 1.5" in width.

  • 68-pin connectors (also known as SCSI III connectors) are a 68-pin version of micro connectors designed for wide SCSI devices.

Figure 10-4 illustrates these connector types (shown in the external versions).

Figure 10-4. SCSI connectors

From left to right, Figure 10-4 shows a Centronics connector, two versions of the 50-pin mini-micro connector, and a DB-25 connector. 68-pin connectors look very similar to these 50-pin mini-micro connectors; they are simply wider. Figure 10-5 depicts the pin numbering schemes for these connectors.

Figure 10-5. SCSI connector pinouts

You can purchase cables that use any combination of these connectors and adapters to convert between them.

The various SCSI devices on a system are connected in a daisy chain (i.e., serially, in a single line). The first and last devices in the SCSI chain must be terminated for proper operation. For example, when the SCSI chain is entirely external, the final device will have a terminator attached and the SCSI adapter itself will usually provide termination for the beginning of the chain (check its documentation to determine whether this feature must be enabled or not). Similarly, when the chain is composed of both internal and external devices, the first device on the internal portion of the SCSI bus will have termination enabled (for example, via a jumper on an internal disk), and the final external device will again have a terminator attached.

Termination consists of regulating the voltages across the various lines comprising the SCSI bus. Terminators prevent the signal reflection that would occur on an open end. There are several different types of SCSI terminators:

  • Passive terminators are constructed from resistors. They attempt to ensure that the line voltages in the SCSI chain remain within their proper operating ranges. This type of termination is the least expensive, but it tends to work well only when there are just one or two devices in the SCSI chain and activity on the bus is minimal.

  • Active terminators use voltage regulators and resistors to force the line voltages to their proper ranges. While passive terminators simply reduce the incoming signal to the proper level (thus remaining susceptible to all power fluctuations within it), active terminators use a voltage regulator to ensure a steady standard for use in producing the target voltages. Active terminators are only slightly more expensive than passive terminators, and they are always more reliable. In fact, the SCSI II standard calls for active termination for all SCSI chains.

  • Forced perfect termination (FPT) uses a more complex and accurate voltage regulation scheme to force line voltages to their correct values. In this scheme, the voltage standard is taken from the output of two regulated voltages, and diodes are used to eliminate fluctuations within it. This results in increased stability over active termination. FPT will generally eliminate any flakiness in a SCSI chain, and you should consider it any time your chain consists of more than three devices (despite the fact that it is 2-3 times more expensive than active termination).

  • Some hybrid terminators are also available. In such devices, key lines are controlled via forced perfect termination, and the remaining lines are regulated with active termination. Such devices tend to be almost as expensive as FPT terminators and so are seldom preferable to them.

A few SCSI devices have built-in terminators that you select or deselect via a switch. External boxes containing multiple SCSI disks also often include termination. Check the device characteristics for your devices to determine if such features are present.

NOTE

Be aware that filesystems on SCSI disks are not guaranteed to survive a change of controller model (although they usually will); the standard does not specify that they must be interoperable. Thus, if you move a SCSI disk containing data from one system to another system with a different kind of SCSI controller, there's a chance you will not be able to access the existing data on the disk and will have to reformat it. Similarly, if you need to change the SCSI adapter in a computer, it is safest to replace it with another of the same model.

Having said this, I will note that I do move SCSI disks around fairly often, and I've only seen one failure of this kind. It's rare, but it does happen.

Once the disk is attached to the system, you are ready to configure it. The discussion that follows assumes that the new disk to be added is connected to the computer and is ready to accept partitions. These days, disks seldom if ever require low-level formatting, so we won't pay much attention to this process.

Before turning to the specific procedures for various operating systems, we'll look at the general issue of creating special files.

10.3.2.2 Making special files

Before filesystems can be created on a disk, thespecial files for the desired disk partitions must exist. Sometimes, they are already on the system when you go to look for them. On many systems, the boot process automatically creates the appropriate special files when it detects new hardware.

Otherwise, you'll have to create them yourself. Special files are created with the mknod command. mknod has the following syntax:

# mknod  name  |  major minor

The first argument is the filename, and the second argument is the letter c or b, depending on whether you're making the character or block special file. The other two arguments are the major and minor device numbers for the device. These numbers serve to identify the proper device driver to the kernel. The major device number indicates the general device type (disk, serial line, etc.), and the minor device number indicates the specific member within that class.

These numbers are highly implementation-specific. To determine the numbers you need, use the ls -l command on some existing special files for disk partitions; the major and minor device numbers will appear in the size field. For example:

$ cd /dev/dsk; ls -l c1d*                  Major, minor device numbers.
brw-------   1 rootroot0,144 Mar 13 19:14 c1d1s0
brw-------   1 rootroot0,145 Mar 13 19:14 c1d1s1
brw-------   1 rootroot0,146 Mar 13 19:14 c1d1s2
...
brw-------   1 rootroot0,150 Mar 13 19:14 c1d1s6
brw-------   1 rootroot0,151 Mar 13 19:14 c1d1s7
brw-------   1 rootroot0,160 Mar 13 19:14 c1d2s0
brw-------   1 rootroot0,161 Mar 13 19:14 c1d2s1
...
$ cd /dev/rdsk; ls -l c1d1*
crw-------   1 rootroot3,144 Mar 13 19:14 c1d1s0
crw-------   1 rootroot3,145 Mar 13 19:14 c1d1s1
.. .

In this example, the numbering pattern is pretty clear: block special files for disks on controller 1 have major device number 0; the corresponding character special files have major device number 3. The minor device number of the same partition of successive disks differs by 16. So if you want to make the special files for partition 2 on disk 3, its minor device number would be 162+16 = 178, and you'd use the following mknod commands:

# mknod /dev/dsk/c1d3s2  b 0 178
# mknod /dev/rdsk/c1d3s2 c 3 178

Except on Linux and FreeBSD systems, be sure to make both the block and character special files.

On many systems, the /dev directory includes a shell script named MAKEDEV which automates running mknod. It takes the base name of the new device as an argument and creates the character and block special files defined for it. For example, the following command creates the special files for a SCSI disk under Linux:

# cd /dev
# ./MAKEDEV sdb

The command creates the special files /dev/sdb0 through /dev/sdb16.

10.3.2.3 FreeBSD

The first step is to attach the disk to the system and then reboot.[17]FreeBSD should detect the new disk. You can check the boot messages or the output of the dmesg command to ensure that it has:

[17] If the system has hot swappable SCSI disks, you can use the cancontrol rescan bus command to detect them without rebooting.

da1 at adv0 bus 0 target 2 lun 0
da1: <SEAGATE ST15150N 0017> Fixed Direct Access SCSI-2 device
da1: 10.000MB/s transfers (10.000MHz, offset 15), Tagged Queueing Enabled
da1: 4095MB (8388315 512 byte sectors: 255H 63S/T 522C)

On Intel-based systems, disk ordering happens at boot time, so adding a new SCSI disk with a lower SCSI ID than an existing disk will cause special files to be reassigned[18] and probably break your /etc/fstab setup. Try to assign SCSI IDs in order if you anticipate adding additional devices later.

[18] This can happen at other times as well. For example, changes to fiber channel configurations such as switch reconfigurations might lead to unexpected device reassignments, because the operating system gets information on hardware addressing from the programmable switch.

FreeBSD disk partitioning is a bit more complex than for the other operating systems we are considering. It is a two-part process. First, the disk is divided into physical partitions, which BSD calls slices. One or more of these is assigned to FreeBSD. The FreeBSD slice is then itself subdivided into partitions. The latter are where filesystems actually get built.

The fdisk utility is used to divide a disk into slices. Here we create a single slice comprising the entire disk:

# fdisk -i /dev/da1
******* Working on device /dev/da1 *******
.. .
Information from DOS bootblock is:
The data for partition 1 is:
<UNUSED>
Do you want to change it? [n] y
Supply a decimal value for "sysid (165=FreeBSD)" [0] 165
Supply a decimal value for "start" [0]
Supply a decimal value for "size" [0] 19152
Explicitly specify beg/end address ? [n] n
sysid 165,(FreeBSD/NetBSD/386BSD)
    start 0, size 19152 (9 Meg), flag 0
        beg: cyl 0/ head 0/ sector 1;
        end: cyl 18/ head 15/ sector 63
Are we happy with this entry? [n] y
The data for partition 2 is:
<UNUSED>
Do you want to change it? [n] n
.. .
Do you want to change the active partition? [n] n
Should we write new partition table? [n] y

Unless you want to create multiple slices, this step is required only on the boot disk on an Intel-based system. However, if you're using a slice other than the first one, you'll need to create the special files to access it:

# cd /dev; ./MAKEDEV /dev/da1s2a

The disklabel command creates FreeBSD partitions within the FreeBSD slice:

# disklabel -r -w da1 auto

The auto parameter says to create a default layout for the slice. You can preview what disklabel will do by adding the -n option.

Once you have created a default label (division), you can edit it by running disklabel -e. This command starts a editor session from which you can modify the partitioning (using the editor specified in the EDITOR environment variable).

NOTE

disklabel is a very cranky utility, and often fails with the message:

disklabel: No space left on device

The message is completely spurious. This happens more often with larger disks than with smaller ones. If you encounter this problem, try running sysinstall, and select the Configure [image] Label menu path. This form of the utility can usually be coaxed to work, but even it will not accept all valid partition sizes. Caveat emptor.

Once you have made partitions, you create filesystems using the newfs command, as in this example:

# newfs /dev/da1a
/dev/da1a: 19152 sectors in 5 cylinders of 1 tracks, 4096 sectors
  9.4MB in 1 cyl groups (106 c/g, 212.00MB/g, 1280 i/g)
super-block backups (for fsck -b #) at:
 32

The following options can be used to customize the newfs operation:

-U

Enable soft updates (recommended).

-b size

Filesystem block size in bytes (the default is 16384; value must be a power of 2).

-f size

Filesystem fragment size: the smallest allocatable unit of disk space. The default is 2048 bytes. This parameter determines the minimum file size, among other things. It must be a power of 2 less than or equal to the filesystem block size and no smaller than one eighth of the filesystem block size. Experts recommend always making this value one eighth of the filesystem block size.

-i bytes

Number of bytes per inode (the default is 4 times the fragment size: 8192 with the default fragment size). This setting controls how many inodes are created for the new filesystem (number of inodes equals filesystem size divided by byte per inode). The default value generally works well.

-m free

Percentage of free space reserved. The default is 8%; you can usually safely decrease it to about 5% or even less for a very large disk.

-o speed | space

Set the optimization preference. speed means that the filesystem will attempt to minimize the time spent allocating disk blocks, while space means that it will try to minimize disk fragmentation. The default is space if the minimum free space percentage is less than 8%, and speed otherwise. Hence, speed is the default with the default free space percentage.

The tunefs command can be used to modify the values of -m and -o for an existing filesystem (using the same option letters). Similarly, -n can be used to enable/disable soft updates for an existing filesystem (it takes enable or disable as its argument).

Finally, we run fsck on the new filesystem:

# fsck /dev/da1a
** /dev/da1a
** Last Mounted on
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
1 files, 1 used, 4682 free (18 frags, 583 blocks, 0.4% fragmentation)

In this instance, fsck finishes very quickly.

If you use the menu-driven version of disklabel in the sysinstall utility, the newfs and mount commands can be run for you automatically (and the utility does so by default).

The growfs command can be used to increase the size of an existingfilesystem, as in this example:

# growfs /dev/da1a

By default, the filesystem is increased to the size of the underlying partition. You can specify a specific new size with the -s option if you want to.

10.3.2.4 Linux

After attaching the disk to the system, it should be detected when the system is booted. You can use the dmesg command to display boot messages. Here are some sample messages from a very old, but still working, Intel-based Linux system:

scsi0 : at 0x0388 irq 10 options CAN_QUEUE=32 CMD_PER_LUN=2 ...
scsi0 : Pro Audio Spectrum-16 SCSI
scsi : 1 host.
Detected scsi disk sda at scsi0, id 2, lun 0
scsi : detected 1 SCSI disk total.

The messages indicate that this disk is designated as sda.

On Intel-based systems, disk ordering happens at boot time, so adding a new SCSI disk with a lower SCSI ID than an existing disk will cause special files to be reassigned[19] and probably break your /etc/fstab setup. Try to assign SCSI IDs in order if you anticipate adding additional devices later.

[19] This can happen at other times as well. For example, changes to fiber channel configurations such as switch reconfigurations might lead to unexpected device reassignments because the operating system gets information on hardware addressing from the programmable switch.

If necessary, create the device special files for the disk (needed only when you have many, many disks). For example, these commands create the special files used to access the sixteenth SCSI disk:

# cd /dev; ./MAKEDEV sdp

Assuming we have our special files all in order, we will use fdisk or cfdisk (a screen-oriented version) to divide the disk into partitions (we'll be creating two partitions). The following commands will start these utilities:

# fdisk /dev/sda
# cfdisk /dev/sda

The available subcommands for these utilities are listed in Table 10-6.

Table 10-6. Linux partitioning utility subcommands

Action

fdisk

cfdisk

Create new partition.

N

N

Change partition type.

T

T

Make partition active (bootable).

A

B

Write partition table to disk.

W

W

Change display/entry size units.

U

U

Display partition table.

P

Always visible

List available subcommands.

m

At dialog bottom

cfdisk is often more convenient to use because the partition table is displayed continuously, and we'll use it here. cfdisk subcommands always operate on the current (highlighted) partition. Thus, in order to create a new partition, move the highlight to the line corresponding to Free Space and press n.

You first need to select either a primary or a logical (extended) partition. PC disk partitions are of two types: primary and extended. A disk may contain up to four partitions. Both partition types are a physical subset of the total disk. Extended partitions may be further subdivided into units known as logical partitions (or drives) and thereby provide a means for dividing a physical disk into more than four pieces.

Next, cfdisk prompts for the partition information:

Primary or logical [pl]: p
Size (in MB): 110

If you'd rather enter the size in a different set of units, use the u subcommand (units cycle among MB, sectors, and cylinders). Once these prompts are answered, you will be asked if you want the partition placed at the beginning or the end of the free space (if there is a choice).

Use the same procedure to create a second partition, and then activate the first partition with the b subcommand. Then, use the t subcommand to change the partition types of the two partitions. The most commonly needed type codes are 6 for Windows FAT16, 82 for a Linux swap partition, and 83 for a regular Linux partition.

Here is the final partition table (output has been simplified):

                         cfdisk 2.11i

                     Disk Drive: /dev/hde
                    Size: 3228696576 bytes
     Heads: 128   Sectors per Track: 63   Cylinders: 782

Name         Flags        Part Type     FS Type      Size (MB)
--------------------------------------------------------------
/dev/sda1    Boot        Primary        Linux        110.0
/dev/sda2                Primary        Linux         52.5
                         Pri/Log        Free Space     0.5

(Yes, those sizes are small; I told you it was an old system.)

At this point, I reboot the system. In general, when I've changed the partition layout of the disk—in other words, done anything other than change the types assigned to the various partitions—I always reboot PC-based systems. Friends and colleagues accuse me of being mired in an obsolete Windows superstition by doing so and argue that this is not really necessary. However, many Linux utility writers (see fdisk) and filesystem designers (see mkreiserfs) agree with me.

Next, use the mkfs command to create a filesystem on the Linux partition. mkfs has been streamlined in the Linux version and requires little input:

# mkfs -t ext3 -j /dev/sda1

This command[20] creates a journaled ext3 filesystem, the current default filesystem type for many Linux distributions. The ext3 filesystem is a journaled version of the ext2 filesystem, which was used on Linux systems for several years and is still in wide use. In fact, ext3 filesystems are backward-compatible and can be mounted in ext2 mode.

[20] Actually, the fsck, mkfs, mount, and other commands are front ends to filesystem-specific versions. In this case, mkfs runs mke2fs.

If you want to customize mkfs's operation, the following options can be used:

-b bytes

Set filesystem block size in bytes (the default is 1024).

-c

Check the disk partition for bad blocks before making the filesystem.

-i n

Specify bytes/inode value: create one inode for each n bytes. The default value of 4096 usually creates more than you'll ever need, but probably isn't worth changing.

-m percent

Specify the percentage of filesystem space to reserve (accessible only by root and group 0). The default is 5% (half of what is typical on other Unix systems). In these days of multigigabyte disks, even this percentage may be worth rethinking.

-J device

Specify a separate device for the filesystem log .

Once the filesystem is built, run fsck:

# fsck -f -y /dev/sda1

The -f option is necessary to force fsck to run even though the filesystem is clean. The new filesystem may now be mounted and entered into /etc/fstab.

The tune2fs command may be used to list and alter fields within the superblock of an ext2 filesystem. Here is an example of its display output (shortened):

# tune2fs -l /dev/sdb1
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      filetype sparse_super
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              253952
Block count:              507016
Reserved block count:     25350
Free blocks:              30043
Free inodes:              89915
First block:              0
Block size:               4096
Last mount time:          Thu Apr  4 11:28:19 2002
Last write time:          Wed May 22 10:00:36 2002
Mount count:              1
Maximum mount count:      20
Last checked:             Thu Apr  4 11:28:01 2002
Check interval:           15552000 (6 months)
Next check after:         Tue Oct  1 12:28:01 2002
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)

The check-related items in the list indicate when fsck will check the filesystem even if it is clean (they appear fifth to third from last). The Linux version of fsck for ext3 filesystems checks the filesystem if either the maximum number of mounts without a check has been exceeded or the maximum time interval between checks has expired (20 times and 6 months in the preceding output; the check interval is given in seconds).

tune2fs's -i option may be used to specify the maximum time interval between checks in days, and the -c option may be used to specify the maximum number of mounts between checks. For example, the following command disables the time-between-checks function and sets the maximum number of mounts to 25:

# tune2fs -i 0 -c 25 /dev/sdb1
Setting maximal mount count to 25
Setting interval between check 0 seconds

Another useful option to tune2fs is -m, which allows you to change the percentage of filesystem space held in reserve. The -u and -g options allow you to specify the user and group ID (respectively) allowed to access the reserved space.

You can convert an ext2 filesystem to ext3 with a command like this one:

# tune2fs -j /dev/sdb2

Existing ext2 and ext3 filesystems can be resized using the resize2fs command, which takes the filesystem and new size (in 512-byte blocks) as parameters. For example, the following commands will change the size of the specified filesystem to 200,000 blocks:

# umount /dev/sdc1
# e2fsck -f /dev/sdc1
e2fsck 1.23, 15-Aug-2001 for EXT2 FS 0.5b, 95/08/09
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/1: 11/247296 files (0.0% non-contiguous), 15979/493998 blocks
# resize2fs -p /dev/sdc1 200000
resize2fs 1.23 (15-Aug-2001)
Begin pass 1 (max = 1)
Extending the inode table     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 10)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/sdc1 is now 200000 blocks long.

The -p option says to display a progress bar as the operation runs. Naturally, the size of the underlying disk partition or logical volume (discussed later in this chapter) will need to be increased beforehand.

Increasing the size of a filesystem is always safe. If you want the new size to be the same as the size of the underlying disk partition—as is virtually always the case—you can omit the size parameters from the resize2fs command. To decrease the size of a filesystem, perform the resize2fs operation first, and then use fdisk or cfdisk to decrease the size of the underlying partition. Note that data loss is always possible, even likely, when decreasing the size of a filesystem, because no effort is made to migrate data within the filesystem prior to shortening it.

10.3.2.4.1 The Reiser filesystem

Some Linux distributions also offer the Reiser filesystem, designed by Hans Reiser (see http://www.reiserfs.org).[21] The commands to create a Reiser filesystem are very similar:

[21] The name is pronounced like the word riser (as in stairs) and rhymes with sizer and miser.

# mkreiserfs /dev/sdb3
<-------------mkreiserfs, 2001------------->
reiserfsprogs 3.x.0k-pre9
mkreiserfs: Guessing about desired format..
mkreiserfs: Kernel 2.4.10-4GB is running.
13107k will be used
Block 16 (0x2142) contains super block of format 3.5 with standard journal
Block count: 76860
Bitmap number: 3
Blocksize: 4096
Free blocks: 68646
Root block: 8211
Tree height: 2
Hash function used to sort names: "r5"
Objectid map size 2, max 1004
Journal parameters:
        Device [0x0]
        Magic [0x18bbe6ba]
        Size 8193 (including journal header) (first block 18)
        Max transaction length 1024
        Max batch size 900
        Max commit age 30
Space reserved by journal: 0
Correctness checked after mount 1
Fsck field 0x0
ATTENTION: YOU SHOULD REBOOT AFTER FDISK!
        ALL DATA WILL BE LOST ON '/dev/hdf2'!
Continue (y/n):y
Initializing journal - 0%....20%....40%....60%....80%....100%
Syncing..ok
ReiserFS core development sponsored by SuSE Labs (suse.com)
Journaling sponsored by MP3.com.
To learn about the programmers and ReiserFS, please go to
http://namesys.com
Have fun.
# reiserfsck -x /dev/sdb3
<-------------reiserfsck, 2001------------->
reiserfsprogs 3.x.0k-pre9
Will read-only check consistency of the filesystem on /dev/hdf2
        Will fix what can be fixed w/o --rebuild-tree
Will put log info to 'stdout'
Do you want to run this program?[N/Yes] (note need to type Yes):Yes
13107k will be used
###########
reiserfsck --check started at Wed May 22 11:36:07 2002
###########
Replaying journal..
No transactions found
Checking S+tree..ok
Comparing bitmaps..ok
Checking Semantic tree...ok
No corruptions found
There are on the filesystem:
        Leaves 1
        Internal nodes 0
        Directories 1
        Other files 0
        Data block pointers 0 (zero of them 0)
###########
reiserfsck finished at Wed May 22 11:36:19 2002
###########

Reiser filesystems may be resized with the resize_reiserfs -s command. They can also be resized when they are mounted. The latter operation uses a command like the following:

# mount -o remount,resize=200000 /dev/sdc1

This command changes the size of the specified filesystem to 200,000 blocks. Once again, increasing the size of a filesystem is always safe, while decreasing it requires great care to avoid data loss.

10.3.2.5 Solaris

In this section, we add a SCSI disk (SCSI ID 2) to aSolaris system.

After attaching the device, boot the system with boot -r, which tells the operating system to look for new devices and create the associated special files and links into the /devices tree.[22] The new disk should be detected when the system is booted (output simplified):

[22] You should verify that these steps are done correctly after the boot. If not, you can create the /devices entries and links in /dev by running the drvconfig and disks commands. Neither requires any arguments.

sd2 at esp0: target 2 lun 0
  corrupt label - wrong magic number
  Vendor 'QUANTUM', product 'CTS160S', 333936 512 byte blocks

The warning message about a corrupt label comes because no valid Sun label (a vendor-specific disk header block that Sun uses) has been written to the disk yet. If you miss the messages during the boot, use the dmesg command.

We now label the disk and then create partitions on it (which Solaris sometimes calls slices). Solaris uses the format utility for these tasks.[23] Previously, it was often necessary to tell format about the characteristics of your disk. These days, however, the utility knows about most kinds of disks, which makes adding a new disk much simpler.

[23] Solaris also contains a version of the fdisk utility designed for operating system installations. This is not what you should use to prepare a new disk.

Here is the command used to start format and write a generic label to the disk (if it is unlabeled):

# format /dev/rdsk/c0t2d0s2               Partition 2 = the entire disk.
selecting /dev/rdsk/c0t2d0s2
[disk formatted, no defect list found]

FORMAT MENU:
...Menu is printed here.
format> label                             Write generic disk label.
Ready to label disk, continue? y

Once the disk label is written, we can set up partitions. We'll be dividing this disk into two equal partitions. We use the partition subcommand to define them:

format> partition
PARTITION MENU:
        0      - change `0' partition
        1      - change `1' partition
        .. .
        7      - change `7' partition
        select - select a predefined table
        modify - modify a predefined partition table
        name   - name the current table
        print  - display the current table
        label  - write partition map and label to the disk
        quit
partition>                                Redefine partition 0
Enter partition id tag[unassigned]: root   Specifies partition use.
Enter partition permission flags[wm]: wm   Read-write, mountable.
Enter new starting cyl[0]:
Enter partition size[0b, 0c, 0e, 0.00mb, 0.00gb]: 5.00gb
.. .
partition> 1
Enter partition id tag[unassigned]:
Enter partition permission flags[wm]: wm
Enter new starting cyl[0]: 10403
Enter partition size[0b, 0c, 0e, 0.00mb, 0.00gb]: 7257c
.. .
partition> print                           Print partition table.
Current partition table (unnamed):
Total disk cylinders available: 17660 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders         Size            Blocks
  0       root    wm       0 - 10402        5.00GB    (10403/0/0) 10486224
  1 unassigned    wm   10403 - 17659        3.49GB    (7257/0/0)   7315056
  2 unassigned    wm       0                0         (0/0/0)            0
  .. .
  7 unassigned    wm       0                0         (0/0/0)            0

We define two partitions here, 0 and 1. In the first case, we specify a starting cylinder number of 0 and the partition size in GB. In the second case, we specify a starting cylinder and the length in cylinders. We took a look at the partition table between issuing these two commands to find these numbers.

The partition ID tag is a label specifying the intended use of the partition. Partition 0 will be used for the root filesystem and is labeled accordingly.

The permission flags are usually one of wm (read-write and mountable) and wu (read-write and not mountable). The latter is used for swap partitions.

Once the partitions are defined, we write a label to the disk using the label subcommand:

partition> label
Ready to label disk, continue? y
partition> quit
format> quit

The partition submenu also has a name subcommand, which allows a custom partition table to be named and saved; it can be applied to a new disk with the select subcommand on the same menu.

Now, we create filesystems on the new disk partitions with the newfs command:

# newfs /dev/rdsk/c0t2d0s0
newfs: construct a new file system /dev/rdsk/c0t2d0s3: (y/n)? y
/dev/rdsk/c0t0d0s3: 10486224 sectors in 10403 cylinders
                    of 16 tracks, 63 sectors
5120.2MB in 119 cyl groups (88 c/g, 43.31MB/g, 5504 i/g)
super-block backups (for fsck -F ufs -o b=#) at:
 32, 88800, 177568, 266336, 355104, 443872, 532640, 621408, 710176, .. .

The prudent course of action is to print out this list and store it somewhere for safe keeping, in case both the primary superblock and the one at address 32 get corrupted.[24]

[24] A tip from one of the book's technical reviewers: "If you lose your list of backup superblocks, make a filesystem on a device of the same size and read the locations of the superblocks when you newfs that new partition."

Finally, we run fsck on the new filesystem:

# fsck -y /dev/rdsk/c0t2d0s0
** /dev/rdsk/c0t0d0s3
** Last Mounted on
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
2 files, 9 used, 5159309 free (13 frags, 644912 blocks,  0.0% fragmentation)

This process is repeated for the other disk partition.

You can customize the parameters for the new filesystem using these options to newfs:

-b size

Filesystem block size in bytes (the default is 8192; value must be a power of 2 from 4096 to 8192).

-f size

Filesystem fragment size: the smallest allocateable unit of disk space. The default is 1024 bytes (must be a power of 2 in the range of 1024 to 8192). This parameter determines the minimum file size, among other things. It must be less than or equal to the filesystem block size and no smaller than one eighth the filesystem block size.

-i bytes

Number of bytes per inode (the default is 2048). This setting controls how many inodes are created for the new filesystem (number of inodes equals filesystem size divided by bytes per inode). The default value of 2048 usually creates more than you'll ever need except for filesystems with many, many tiny files. You can usually increase this to 4098 without risk.

-m free

Percentage of free space reserved. The default is 10%; you can usually safely decrease it to about 5% or even less for a very large disk.

The -N option to newfs may be used to have the command display all of the parameters it would pass to mkfs—the utility that does the actual work—without building the filesystem.

Logging is enabled for Solaris UFS filesystems at mount time, via the logging mount option.

10.3.2.6 AIX, HP-UX, and Tru64

These operating systems use a logical volume manager (LVM) by default. Adding disks to these systems is considered during the LVM discussion later in this chapter.

10.3.2.7 Remaking an existing filesystem

Occasionally, it may be necessary to reconfigure a disk. For example, you might want to select another layout, using a different set of partitions. You might want to change the value of a filesystem parameter, such as its block size. Or you might want to add an additional swap partition or get rid of an unneeded one. Sometimes, these operations require that you recreate the existing filesystems.

Recreating a filesystem will destroy all the existing data in the filesystem, so it is essential to perform a full backup first (and to verify that the tapes are readable; see Chapter 11). For example, the following commands may be used to reconfigure a filesystem with a 4K block size under Linux:

# umount /chem                          Dismount filesystem.
# dump 0 /dev/sda1                      Backup.
# restore -t                            Check tape is OK!
# mke2fs -b 4096 -j /dev/sda1           Remake filesystem.
# mount /chem                           Mount new filesystem.
# cd /chem; restore -r                  Restore files.

A very cautious administrator would make two copies of the backup tape.

10.3.3 Logical Volume Managers

This section looks at logical volume managers (LVMs). The LVM is the only disk management facility under AIX, and the corresponding facilities are also used by default under HP-UX and Tru64. Linux and Solaris 9 also offer LVM facilities. As usual, we'll begin this section with a conceptual overview of logical volume managers and then move on to the specifics for the various operating systems.

When dealing with an LVM, you will do well to forget everything you know about disk partitions under Unix. Not only is a completely different vocabulary employed, but some Unix terms—like partition—also are used with completely different meanings. However, once you get past the initial obstacles, the LVM point of view is very clear and sensible, and it is superior to the standard Unix approach to handling disks. A willing suspension of disbelief will come in very handy at first.

In general, an LVM brings the following benefits:

  • Filesystems and individual files can be larger than a single physical disk.

  • Filesystems may be dynamically extended in size without having to be rebuilt.

  • Software disk mirroring and RAID are often supported (for data protection and continued system availability even in the face of disk failures).

  • Software disk striping is often provided as part of an LVM for improved I/O performance.

10.3.3.1 Disks, volume groups, and logical volumes

To begin at the beginning, there are disks: real, material, solid objects that hurt your toe if they fall on it. However, such disks must be initialized and made into physical volumes before they may be used by the LVM. When they are made part of a volume group (defined in a moment), these disks are divided into allocable units of space known as physical partitions (AIX) or physical extents (HP-UX and Tru64). The default size for these units is generally 4 MB. Note that these partitions/extents are units of disk storage only; they have nothing to do with traditional Unix disk partitions.

A volume group is a named collection of disks. Volume groups can also include collections of disks accessed as a single hardware unit (e.g., a RAID array). Volume groups allow filesystems to span physical disks (although it is not required that they do so). Paradoxically, the volume group is the LVM equivalent of the Unix physical disk: that entity which can be split into subunits called logical volumes, each of which holds a single filesystem. Unlike Unix disk partitions, volume groups are infinitely flexible in how they may be divided into filesystems.

HP-UX allows volume groups to be subdivided into sets of disks called physical volume groups (PVGs). These groups of disks are accessed through separate controllers and/or buses, and the facility is designed to support high-availability systems by reducing the number of potential single points of hardware failure.

Logical volumes are the entities on which filesystems reside; they may also be used as swap devices, as dump devices, for storing boot programs, and by application programs in raw mode (analogously to a raw-mode disk partition). They consist of some number of fixed physical partitions (disk chunks) generally located arbitrarily within a volume group (although some implementations optionally allow specific physical volumes to be requested when a logical volume is created or extended). Hence, logical volumes may be any size that is a multiple of the physical partition size for their volume group. They may be easily increased in size after creation while the operating system is running. Logical volumes may also be shrunk (although not without consequences to any filesystem they may contain).

Logical volumes are composed of logical partitions (AIX) or logical extents (HP-UX). Many times, physical and logical partitions are identical (or at least map one-to-one). However, logical volumes have the capability of storing redundant copies of all data, if desired; from one to two additional copies of each data block may be stored. When only a single copy of the data is stored, one logical partition corresponds to one physical partition. If two copies are stored, one logical partition corresponds to two physical partitions: one original and one mirror. Similarly, in a doubly mirrored logical volume, each logical partition corresponds to three physical partitions.

The main LVM data storage entities are illustrated in Figure 10-6 (representing an AIX system). The figure shows how three physical disks are combined into a single volume group (named chemvg). The separate disks composing it are suggested via shading.

Figure 10-6. Logical volume managers illustrated

Three user logical volumes are then defined from chemvg.[25] Two of them—chome and cdata—store a single copy of their data using physical partitions from three separate disks. cdata is a striped logical volume, writing data to all three disks in parallel. It uses identically sized sections from each physical disk. chome illustrates the way that a filesystem can be spread across multiple physical disks, even noncontiguously in the case of hdisk3.

[25] In addition to the logging volume group required by AIX for the jfs journaled filesystem type.

The other logical volume, qsar, is a mirrored logical volume. It contains an equal number of physical partitions from all three disks; it stores three copies of its data (each on a separate disk), and one physical partition per disk is used for each of its logical partitions.

Once a logical volume exists, you can build a filesystem on it and mount it normally. At any point in its lifetime, a filesystem's size may be increased as long as there are free physical partitions within its volume group. There need not initially be any free logical partitions within its logical volume. Generally, both the logical volume and filesystem are resized using a single command.

Some operating systems can also reduce the size of an existing logical volume. If this operation is performed on a mounted filesystem, and the new size of the logical volume is still at least a little larger than the existing filesystem, it can be accomplished without losing any data. Under any other conditions, data loss is very, very likely indeed. This technique is not for the fainthearted.

Currently, there is no easy way to decrease the size of a filesystem under AIX or FreeBSD, even if there is unused space within the filesystem. If you want to make a filesystem smaller, you need to back up the current files (and verify that the tape is readable!), delete the filesystem and its logical volume, create a new, smaller logical volume and filesystem, and then restore the files. The freed logical partitions can then be allocated as desired within their volume group; they can be added to an existing logical volume, used to make a new logical volume and filesystem, used in a new or existing paging space, or held in reserve.

Table 10-7 lists theLVM-related terminology used by the various Unix operating systems.

Table 10-7. LVM terminology

Item

AIX

FreeBSD[26]

HP-UX

Linux

Solaris

Tru64 AdvFS[27]

Tru64 LSM

Facility

Logical Volume Manager

Vinum Volume Manager

Logical Volume Manager

Logical Volume Manager

Volume Manager

Advanced File System

Logical Storage Manager

Virtual disk

volume group

None

volume group

volume group

volume

domain

disk group

Logical volume

logical volume

Volume

logical volume

logical volume

volume, soft partition

fileset

volume

Allocation unit

partition

Subdisk

extent

Extent

extent

extent

extent

[26] As we'll see, the FreeBSD entity mappings here are not precise because the concepts are somewhat different.

[27] Not a true LVM, AdvFS nevertheless shares many features with them.

10.3.3.2 Disk striping

Disk striping is an option that is increasingly available as an extension to Unix, especially on high-performance systems. Striping combines one or more physical disks (or disk partitions) into a single logical disk, viewed like any other filesystem device by the rest of Unix. Disk striping is used to increase I/O performance at least as often as it is used to create very large filesystems spanning more than one physical disk. Striped disks split I/O operations across the physical disks in the stripe, performing them in parallel, and are thus able to achieve significant performance improvements over a single disk (although not always the nearly linear speedups that are sometimes claimed). Striping is especially effective for single-process transfer rates to a very large file and for processes performing a large number of I/O operations. Disk striping performance is discussed in detail in Section 15.5.

Special-purpose striped-disk devices are available from many vendors. In addition, many Unix systems offer software disk-striping. They provide utilities for configuring physical disks into a striped device, and the striping itself is done by the operating system, at the cost of some additional overhead.

The following general considerations apply to softwarestriped-disk configurations:

  • For maximum performance, the individual disks in the striped filesystem should be on separate disk controllers. However, it is permissible to place different disks on a given controller into separate stripe sets.

  • Some operating systems require that the individual disks be identical devices: the same size, the same partition layout, and often the same brand. If the layouts are different, the size of the smallest disk is often what is used for the filesystem and any additional space on the other disks will be unusable and wasted.

  • In general, disks used for striping should not be used for any purpose other than the I/O whose performance you want to optimize. Placing ordinary user files on striped disks seldom makes sense. Similarly, striping swap space makes sense only if paging performance is the most significant disk I/O performance factor on the system.

  • In no case should the device containing the root filesystem be used for disk striping. This is really a corollary of the previous item.

  • The stripe size selected for a striped filesystem is important. The optimal value depends on the typical data transfer characteristics and requirements for the application programs for which the filesystem is intended. Some experimentation with different stripe sizes will probably be necessary. Provided that processes using the striped filesystem perform large enough I/O operations, a larger stripe size will generally result in better I/O performance. However, the tradeoff is that larger stripe sizes mean a larger filesystem block size and, accordingly, less efficient allocation of available disk space.

  • Software disk striping is really designed for two to four disks. In most cases, any additional performance gains are generally quite modest.

  • SCSI disks make the most sense when you're using software striping for performance.

Software disk-striping is generally accomplished via the LVM or similar facility.

10.3.3.3 Disk mirroring and RAID

Another approach to combining multiple disks into a single logical device is RAID (or Redundant Array of Inexpensive[28] Disks). In general, RAID devices are designed for increased data integrity and availability (via redundant copies), not for improved performance (RAID 0 is an exception).

[28] Some acronym expansions put "Independent" here.

There are at least 6 definedRAID levels that differ in how the multiple disks within the unit are organized. Most available hardware RAID devices support some combination of the following levels (level 2 is not used in practice). Table 10-8 summarizes the available RAID levels.

Table 10-8. Commonly used RAID levels

Level

Description

Advantages/Disadvantages

0

Disk striping only.

+ Best I/O performance for large transfers.

+ Largest storage capacity.

- No data redundancy.

1

Disk mirroring: every disk drive is duplicated for 100% data redundancy.

+ Most complete data redundancy.

+ Good performance on small transfers.

- Largest disk requirements for fault tolerance.

3

Disk striping with a parity disk; data is split across component disks on a byte-to-byte basis; the parity disk enables reconstruction of all data if a drive fails.

+ Data redundancy with minimal overhead.

+ Decent I/O performance for reads.

- Parity disk is a bottleneck for writes.

- Significant operating system overhead.

4

Disk striping with a parity disk; data is split across component disks on a per-block basis; the parity disk enables reconstruction of all data if a drive fails.

+ Data redundancy with minimal overhead.

+ Better than level 3 for large sequential writes.

- Parity disk is a bottleneck for small writes.

- Significant operating system overhead.

5

Same as level 3 except that the parity information is split across multiple component disks, in an attempt to prevent the parity disk from becoming an I/O bottleneck.

+ Data redundancy with minimal overhead.

+ Best performance for writes.

- Not as fast as level 3 or 4 for reads.

- Significant operating system overhead.

Figure 10-7 illustratesRAID 5 in action, using 5 disks.

Figure 10-7. The RAID 5 data distribution scheme

There are also some hybrid RAID levels:

  • RAID 0+1: Mirroring of striped disks. Two striped sets are mirrors of one another. Data is striped across each stripe set, and the same data is sent to both stripes. Thus, this RAID variation provides both I/O performance advantages and fault tolerance.

  • RAID 1+0 (sometimes called RAID 10): Striping across mirror sets. Similar in intent to RAID 0+1, it provides equivalent performance advantages and slightly better fault tolerance in that it is easier to rebuild the RAID device after a single disk failure (since the data on only one mirror set is affected).

Both these levels use a minimum of four disks.

Most hardware RAID devices connect to standard SCSI or SCSI-2 controllers.[29] Many systems also offer software RAID facilities within their LVM (as we shall see).

[29] A small minority use fiber channel.

The following considerations apply to all softwareRAID implementations:

  • Be careful not to overload disk controllers when using software RAID, because this will significantly degrade performance for all RAID levels. Putting disks on separate controllers is almost always beneficial.

  • As with plain disk striping, the stripe size chosen for RAID 5 can effect performance. The optimum value to choose is very highly dependent on the typical I/O operation type.

  • The sad fact is that if you want both high performance and fault tolerance, software RAID, and especially RAID 5, is likely to be a poor choice. RAID 1 works reasonably (with two-way mirroring), although it does add some overhead to the system. The additional overhead that RAID 5 places on the operating system is considerable, about 23% more than required for normal I/O operations. The bottom line for RAID 5 is to spend the money to get a hardware solution, and use software RAID 5 only if you can't afford anything better. Having said that, software RAID 5 often works well on a dedicated file server with a lot of CPU horsepower, some fast SCSI disks, and very few write operations.

10.3.3.4 AIX

AIX defines the root volume group, rootvg, automatically when the operating system is installed. Here is a typical setup:

# lsvg rootvg               Display volume group attributes.
VOLUME GROUP:   rootvg                   VG IDENTIFIER:  0000018900004c0.. .
VG STATE:       active                   PP SIZE:        32 megabyte(s)
VG PERMISSION:  read/write               TOTAL PPs:      542 (17344 MB)
MAX LVs:        256                      FREE PPs:       69 (2208 MB)
LVs:            11                       USED PPs:       473 (15136 MB)
OPEN LVs:       10                       QUORUM:         2
TOTAL PVs:      1                        VG DESCRIPTORS: 2
STALE PVs:      0                        STALE PPs:      0
ACTIVE PVs:     1                        AUTO ON:        yes
MAX PPs per PV: 1016                     MAX PVs:        32
LTG size:       128 kilobyte(s)          AUTO SYNC:      no
HOT SPARE:      no
# lsvg -l rootvg                      List logical volumes in a volume group.
rootvg:
LV NAME             TYPE       LPs   PPs   PVs  LV STATE      MOUNT POINT
hd5                 boot       1     1     1    closed/syncd  N/A
hd6                 paging     16    16    1    open/syncd    N/A
hd8                 jfs2log    1     1     1    open/syncd    N/A
hd4                 jfs2       1     1     1    open/syncd    /
hd2                 jfs2       49    49    1    open/syncd    /usr
hd9var              jfs2       3     3     1    open/syncd    /var
hd3                 jfs2       1     1     1    open/syncd    /tmp
hd1                 jfs2       1     1     1    open/syncd    /home
hd10opt             jfs2       1     1     1    open/syncd    /opt
lg_dumplv           sysdump    32    32    1    open/syncd    N/A

Adding a new disk under AIX follows the same basic steps as for other Unix systems, although the commands used to perform them are quite different. Once you've attached the device to the system, reboot it. Usually, AIX will discover new devices at boot time and automatically create special files for them. Defined disks have special filenames like /dev/hdisk1. The cfgmgr command may be used to search for new devices between boots; it has no arguments.

The lsdev command will list the disks present on the system:

$ lsdev -C -c disk
hdisk0 Available 00-00-0S-0,0 1.0 GB SCSI Disk Drive
hdisk1 Available 00-00-0S-2,0 Other SCSI Disk Drive
.. .

The new disk must then be made part of a volume group. To create a new volume group, use the mkvg command:

# mkvg -y "chemvg" hdisk5 hdisk6

This command creates a volume group named chemvg consisting of the disks hdisk5 and hdisk6. mkvg's -s option can be used to specify the physical partition size in MB: from 1 to 1024 (4 is the default). The value must be a power of 2.[30]

[30] You will need to increase this parameter for disks larger than 4 GB (1016 * 4 MB), because the maximum number of physical partitions is 1016. You can increase the latter limit using the -t option to mkvg and chvg. The new maximum will be this option's value times 1016. This can be necessary when adding a large (18 GB or more) disk to an existing volume group containing significantly smaller disks. It may also eventually be necessary for future very, very large disks.

After a volume group is created, it must be activated with the varyonvg command:

# varyonvg chemvg

Thereafter, the volume group will be activated automatically at each boot time. Volume groups are deactivated with varyoffvg; all of their filesystems must be dismounted first.

A new disk may be added to an existing volume group with the extendvg command. For example, the following command adds the disk hdisk4 to the volume group named chemvg:

# extendvg chemvg hdisk4

The following other commands operate on volume groups:

chvg

Change volume group characteristics.

reducevg

Remove a disk from a volume group (removing all disks deletes the volume group).

importvg

Add an existing volume group to the system (used to move disks between systems and to activate existing volume groups after replacing the root disk).

exportvg

Remove a volume group from the system device database but don't alter it (used to move disks to another system).

Logical volumes are created with the mklv command, which has the following basic syntax:

mklv -y "lvname" volgrp n [disks]

lvname is the name of the logical volume, volgrp is the volume group name, and n is the number of logical partitions. For example, the command:

# mklv -y "chome" chemvg 64

makes a logical volume in the chemvg volume group consisting of 64 logical partitions (256 MB) named chome. The special files /dev/chome and /dev/rchome will automatically be created by mklv.

The mklv command has many other options, which allow the administrator as much control over how the logical volume maps to physical disks as desired, down to the specific physical partition level. However, the default settings work very well for most applications.

The following commands operate on logical volumes:

extendlv

Increase the size of a logical volume.

chlv

Change the characteristics of a logical volume.

mklvcopy

Increase the number of data copies in a logical volume.

rmlv

Delete a logical volume.

A small logical volume in each volume group is used for logging and other disk management purposes. Such logical volumes are created automatically by AIX and have names like lvlog00.

Once the logical volumes have been created, you can build filesystems on them. AIX has a version of mkfs, but crfs is a much more useful command for creating filesystems. There are two ways to create a filesystem:

  • Create a logical volume and then create a filesystem on it. The filesystem will occupy the entire logical volume.

  • Create a filesystem and let AIX create a logical volume for you automatically.

The second way is faster, but the logical volume name AIX chooses is quite generic (lv00 for the first one so created, and so on), and the size must be specified in 512-byte blocks rather than in logical partitions (which default to 4 MB units).

The crfs command is used to create a filesystem. The following basic form may be used to create a filesystem:

crfs -v jfs2 -g vgname -a size=n -m mt-pt -A yesno -p prm

The options have the following meanings:

-v jfs2

The filesystem type is jfs2 ("enhanced journaled filesystem," using the logging logical volume in its volume group), the recommended local filesystem type.

-g vgname

Volume group name.

-a size= n

Size of the filesystem, in 512-byte blocks.

-m mt-pt

Mount point for the filesystem (created if necessary).

-A yesno

Whether the filesystem is mounted by mount -a commands.

-a frag= n

Use a fragment size of n bytes for the filesystem. This value can range from 512 to 4096, in powers of 2, and it defaults to 4096. Smaller sizes will allocate disk space more efficiently for usage patterns consisting of many small files.

-a nbpi= n

Specify n as the number of bytes per inode. This setting controls how many inodes are created for the new filesystem (number of inodes equals filesystem size divided by bytes per inode). The default value of 4096 usually creates more than you'll ever need except for filesystems with many, many tiny files. The maximum value is 16384.

-a compress=LZ

Use transparent LZ compression on the files in the filesystem (this option is disabled by default).

For example, the following command creates a new filesystem in the chemvg volume group:

# crfs -v jfs2 -g chemvg -a size=50000 -a frag=1024 -m /organic2 -A yes
# mount /organic2

The new filesystem will be mounted at /organic2 (automatically at boot time), is 25 MB in size, and uses a fragment size of 1024 bytes. A new logical volume will be created automatically, and the filesystem will be entered into /etc/filesystems. The initial mount must be done by hand.

The -d option is used to create a filesystem on an existing logical volume:

# crfs -v jfs2 -d chome -m /inorganic2 -A yes

This command creates a filesystem on the logical volume we created earlier. The size and volume group options are not needed in this case.

The chfs command may be used to increase the size of a filesystem. For example, the following command increases the size of the /inorganic2 filesystem (and of its logical volume chm00) created above:

# chfs -a size=+50000 /inorganic

An absolute or relative size may be specified for the size parameter (in 512-byte blocks). The size of a logical volume may be increased with the extendlv command, but it has no effect on filesystem size.

The following commands operate on AIX jfs and jfs2 filesystems:

chfs

Change filesystem characteristics.

rmfs

Remove a filesystem, its associated logical volume, and its entry in /etc/filesystems.

10.3.3.4.1 Replacing a failed disk

When you need to remove a disk from the system, most likely due to a hardware failure, there are two considerations to keep in mind:

  • If possible, perform the steps to remove a damaged non-rootdisk from the LVM configuration before letting field service replace it (otherwise, it will take some persistence to get the system to forget about the old disk).

  • Items must be removed in the reverse order from the way they were created: filesystems, then logical volumes, then volume groups.

The following commands remove hdisk4 from the LVM configuration (the volume group chemvg2 and the logical volume chlv2 holding the /chem2 filesystem are used as an example):

# umount /chem2                         Unmount filesystem.
# rmfs /chem2                           Repeat for all affected filesystems.
# rmlvcopy chlv2 2 hdisk4               Remove mirrors on hdisk4.
# chps -a n paging02                    Don't activate paging space at next boot.
# shutdown -r now                       Reboot the system.
# chpv -v r hdisk4                      Make physical disk unavailable.
# reducevg chemvg2 hdisk4               Remove disk from volume group.
# rmdev -l hdisk4 -d                    Remove definition of disk.

When the replacement disk is added to the system, it will be detected, and devices will be created for it automatically.

10.3.3.4.2 Getting information from the LVM

AIX provides many commands and options for listing information about LVM entities. Table 10-9 attempts to make it easier to figure out which one to use for a given task.

Table 10-9. AIX LVM informational commands

If you want to see:

Use this command:

All disks on the system

lspv

All volume groups

lsvg

All logical volumes

lsvg -l 'lsvg'

All filesystems

All filesystems of a given type

lsfs

lsfs -v type

What logical volumes are in a volume group

lsvg -l vgname

What filesystems are in a volume group

lsvgfs vgname

What disks are in a volume group

lsvg -p vgname

Which volume group a disk is in

lsvg -n hdiskn

Disk characteristics and settings

lspv hdiskn

Volume group settings

lsvg vgname

Logical volume characteristics

lslv lvname

Size of an unmounted local filesystem (in blocks)

lsfs file-system

Whether there is any unused space on a logical volume already containing a filesystem (compare lv size and fs size)

lsfs -q file-system

Disk usage summary map by region

lspv -p hdiskn

Locations of the free physical partitions on a disk broken down by region

lspv hdiskn

Locations of all free physical partitions in a volume group, by disk and disk region

lsvg -p vgname

Which logical volumes use a given disk, broken down by disk region

lspv -l hdisk n

What disks a logical volume is stored on, including disk region distribution

lslv -l lvname

Table showing the physical-to-logical partition mapping for a logical volume

lslv -m lvname

Table showing physical partition usage for a disk by logical volume

lspv -M hdiskn

10.3.3.4.3 Disk striping and disk mirroring

A striped logical volume is created by specifying mklv's -S option, indicating the stripe size, which must be a power of 2 from 4K to 128K. For example, this command creates a 500 MB logical volume striped across two disks consisting of a total of 125 logical partitions, each 4 MB in size:

# mklv -y cdata -S 64K chemvg 125 hdisk5 hdisk6

Note that the disk names are required on the mklv command when creating a striped logical volume.

Multiple data copies—mirroring—may be specified with the -c option, which takes the number of copies as its argument (the default is 1). For example, the following command creates a two-way mirror logical volume:

# mklv -c 2 -s s -w y biovg 500 hdisk2 hdisk3

The command specifies two copies, a super strict allocation policy (forces each mirror to a separate physical disk, which are listed), and specifies that write synchronization take place during each I/O operation (which reduces I/O performance but guarantees data synchronization).

An entire volume group can also be mirrored. This is configured using the mirrorvg command.

Finally, the -a option is used to request placement of the new logical volume within a general region of the disk. For example, this command requests that the logical volume be placed in the center portion of the disk to as great an extent as possible:

# mklv -y chome -ac chemvg 64

Disks are divided into five regions named as follows (beginning at the outer edge): edge, middle, center, inner-middle, and inner-edge. The middle region is the default, and the other available arguments to -a are accordingly e, im, and ie.

AIX does not provide general software RAID, although one can use mirrors and stripes to achieve the same functionality as RAID 0, 1, and 1+0.

10.3.3.5 HP-UX

HP-UX provides another version of a LVM that is used by default. The vg00volume group holds the system files, which are divided into several logical volumes:

# vgdisplay vg00                         Display volume group attributes.
--- Volume groups ---                    Output shortened.
VG Name                     /dev/vg00
VG Write Access             read/write
VG Status                   available
Max LV                      255
Cur LV                      8
Open LV                     8
Max PV                      16
Cur PV                      1
Act PV                      1
Max PE per PV               2500
PE Size (Mbytes)            4
Total PE                    2169
Alloc PE                    1613
Free PE                     556
Total Spare PVs             0
Total Spare PVs in use      0
# bdf                                    Output shows mounted logical volumes.
Filesystem          kbytes    used   avail %used Mounted on
/dev/vg00/lvol3     143360   22288  113567   16% /
/dev/vg00/lvol1      83733   32027   43332   42% /stand
/dev/vg00/lvol7    2097152  419675 1572833   21% /var
/dev/vg00/lvol6    1048576  515524  499746   51% /usr
/dev/vg00/lvol5      65536    1128   60386    2% /tmp
/dev/vg00/lvol4    2097152  632916 1372729   32% /opt
/dev/vg00/lvol8      20480    1388   17900    7% /home

The process of creating a volume group begins by designating the component disks (or disk partitions) as physical volumes, using the pvcreate command:

# pvcreate /dev/rdsk/c2t0d0

Next, a directory and character special file must be created in /dev for the volume group:

# mkdir /dev/vg01
# mknod /dev/vg01/group c 64 0x010000

The major number is always 64, and the minor number is of the form 0x0n0000, where n varies from 0 to 9 and must be unique across all volume groups (I assign them in order).

The volume group may now be created with the vgcreate command, which takes the volume group directory in /dev and the component disks as its arguments:

# vgcreate /dev/vg01 /dev/dsk/c2t0d0

vgcreate's -s option may be used to specify an alternate physical extent size (in megabytes). The default of 4 may be too small for large disks. You can add an additional volume to an existing volume group with the vgextend command.

The vgcreate and vgextend commands also have a -g option, which allows you to define named subsets of the disks in the volume group, known as physical volume groups, as in this example that creates two physical volume groups in the vg01 volume group:

# vgcreate /dev/vg01 -g groupa /dev/dsk/c2t2d0 /dev/dsk/c2t4d0
# vgextend /dev/vg01 -g groupb /dev/dsk/c1t0d0 /dev/dsk/c1t1d0

The file /etc/lvmpvg holds the physical volume group data, and it may be edited directly rather than running vgcreate:

VG     /dev/vg01
PVG    groupa
/dev/dsk/c2t0d0
/dev/dsk/c2t4d0
PVG    groupb
/dev/dsk/c1t0d0
/dev/dsk/c1t1d0

Once the volume group is created, the lvcreate command may be used to create a logical volume. For example, the following command creates a 200 MB logical volume named chemvg:

# lvcreate -n chemvg -L 200 /dev/vg01

If the specified size is not an even multiple of the extent size (4 MB), the size is rounded up to the nearest multiple.

If the new logical volume is to be used for the root or boot filesystem or as a swap space, you must run the lvlnboot command with its -r, -b, or -s option (respectively). The command takes the logical volume device as its argument:

# lvlnboot -r -s /dev/vg01/swaplv

The -r option will create a combined boot/root volume if the specified logical volume is the first one on the physical volume.

Once a logical volume is built, a filesystem may be built upon it. For example:

# newfs /dev/vg01/rchemvg

The logical volume name is concatenated to the volume group directory in /dev to form the special filenames referring to the logical volume; note that newfs uses the raw device. The new filesystem may then be mounted and entered into the filesystem configuration file.

You can customize the parameters for a new VxFS filesystem using these options to newfs :

-b size

Filesystem block size in bytes. The default is 1024 for filesystems smaller than 8 GB, 2048 for ones up to 16 GB, 4096 for ones less than 32 GB, and 8192 for larger ones. The value must be a power of 2 from 4096 to 8192 (or to 65536 on 700 series systems using disk striping, which is discussed later in this chapter).

-l

Enable files larger than 2 GB.

Other commands that operate on LVM entities are listed below:

vgextend

Add disk to volume group.

vgreduce

Remove disk from volume group.

vgremove

Remove a volume group.

lvextend

Add physical extents or mirrored copies to a logical volume.

lvreduce

Remove physical extents or mirrored copies from a logical volume.

Lvremove

Remove a logical volume from a volume group.

10.3.3.5.1 Displaying LVM information

The following commands display information about LVM entities:

pvdisplay disk

Summary information about the disk drive.

pvdisplay -v disk

Mapping of physical extents to logical extents.

vgdisplay vg

Summary information about the volume group.

vgdisplay -v vg

Brief information about all logical volumes within the volume group.

lvdisplay lv

Summary information about the logical volume.

lvdisplay -v lv

Mapping of logical to physical extents for the logical volume.

10.3.3.5.2 Disk striping and mirroring

The LVM is also used to perform disk striping and disk mirroring onHP-UX systems. For example, the following command creates a 200 MB logical volume named cdata with one mirrored copy:

# lvcreate -n cdata -L 200 -m 1 -s g /dev/vg01

The -s g option specifies that the mirrors must be placed into different physical volume groups.

Under HP-UX, disk striping occurs at the logical volume level. The following command creates an 800 MB four-way striped logical volume, using a striped width of 64 KB:

# lvcreate -n tyger -L 400 -i 4 -I 64 /dev/vg01

The -i option specifies the number of stripes (disks) and can be no larger than the total number of disks in the volume group; -I specifies the stripe size in KB, and its valid range is powers of 2 from 4 to 64.

Most HP-UX version do not provide software RAID.[31]

[31] Software RAID is provided under HP-UX with VxVM (the Veritas Volume Manager, which supports software RAID 5, 0+1, and 1+0). HP began shipping VxVM with HP-UX 11i.

10.3.3.6 Tru64

Tru64 provides two facilities which have many of the characteristics of a logical volume manager:

  • The Advanced File System (AdvFS), whose name is something of a misnomer, as it is actually both a filesystem type and a simple logical volume manager. The filesystem is included with the operating system, but there is also an add-on product containing additional AdvFS utilities.

  • The Logical Storage Manager (LSM) facility is an advanced LVM facility. It adds an additional layer to the structure usually found in logical volume managers. This is an add-on product.

We'll consider each of them in separate subsections.

10.3.3.6.1 AdvFS

The AdvFS defines the following entities:

  • A volume is a logical entity that can correspond to a disk partition, an entire disk, an LSM volume (see below), or even an external storage device such as a hardware RAID array.

  • A domain is a set of one or more volumes.

  • A fileset is a directory tree that can be mounted within the filesystem. Domains can contains multiple filesets.

Unlike other LVMs, under the AdvFS, domains and filesets—physical storage and directory trees—are independent, and either one can be modified without affecting the other (as we'll see).

The AdvFS facility is used by default on Tru64 systems. It defines two domains and several filesets:

# showfdmn root_domain                    Describe this domain.
               Id              Date Created  LogPgs  Version  Domain Name
3a535b22.000c47c0  Wed Jan  3 12:02:26 2001     512        4  root_domain

  Vol   512-Blks        Free  % Used  Cmode  Rblks  Wblks  Vol Name
   1L     524288       95680     82%     on    256    256  /dev/disk/dsk0a
# mountlist -v                            List mounted filesets.
        root_domain#root                  Root filesystem.
        usr_domain#usr                    Mounted at /usr.
        usr_domain#var                    Mounted at /var.
# showfsets usr_domain                    List filesets in a domain.
usr
        Id           : 3a535b27.0005a120.1.8001
        Files        :    43049,  SLim=        0,  HLim=        0
        Blocks (512) :  1983812,  SLim=        0,  HLim=        0
        Quota Status : user=off group=off Output shortened.
var
        Id           : 3a535b27.0005a120.2.8001
        Files        :     1800,  SLim=        0,  HLim=        0
        Blocks (512) :    34954,  SLim=        0,  HLim=        0
        Quota Status : user=off group=off

You can create a new domain with the mkfdmn command:

# mkfdmn /dev/disk/dsk1c chem_domain

This command creates the chem_domain domain consisting of the specified volume (here, a disk partition). If you have the AdvFS Utilities installed, you can add volumes to a domain with the addvol command, as in this example, which adds a second disk partition to the chem_domain domain:

# addvol /dev/disk/dsk2c chem_domain
# balance chem_domain

You can similarly remove a volume from a domain with the rmvol command. The balance command is typically run after either one; it has the effect of balancing disk space usage among the various volumes in the domain to improve performance.

Once a domain has been created, you can create filesets within it. This process creates an entity which is effectively a relocateable filesystem; a fileset is ready to accept files as soon as it is created (no mkfs step is required), and its contents can be moved to a different physical disk location in its domain if required.

The following commands create two filesets with our domain, and mount them into two existing directories immediately afterward:

# mkfset chem_domain bronze
# mkfset chem_domain silver
# mount chem_domain#bronze /bronze
# mount chem_domain#silver /silver

The fileset is referred to by appending its name to the domain name, separated by a number sign (#). Note that we don't have to specify any actual disk locations (and indeed we cannot do so). These matters are handled by the AdvFS itself.

The rmfset command may be used to remove a fileset from a domain. The renamefset command may be used to change the name of a fileset, as in this example:

# renamefset chem_domain lead gold

The AdvFS offers some limiteddisk striping facilities as part of its optional utilities package. A file can be striped by creating it with the stripe command:

# stripe -n 2 sulfur

This command creates the file sulfur as a two-way striped file. The file must created before any data is placed into it. More complex striping of entire volumes can be done with the Logical Storage Manager described in the next subsection.

10.3.3.6.2 LSM

The Tru64 Logical Storage Manager is designed to support advanced disk features such as disk striping and fault tolerance. It is a layered product which must be added to the basic Tru64 operating system.

Under the LSM, a whole new set of terminology comes into play:

Disk group

A named collection of disks using a common LSM database. This roughly corresponds to a volume group.

Plex

The primary data storage entity. A plex can be concatenated, meaning that the discrete subdisks are simply combined sequentially, or striped, where data is striped across subdisks for higher performance. Software RAID 5 plexes can also be created.

Subdisk

A group of contiguous physical disk blocks. Subdisks are defined to force plexes to specific physical disk locations.

Volume

A collection of one or more plexes, conceptually performing the same function as a logical volume. Filefilesystemssystems are built upon volumes. The innovation introduced by the LSM is that the component plexes in a mirrored volume need not be identical. For example, one plex might be made up of three subdisks, and another one could be composed of four subdisks of the same total size.

For the most common cases, you need only worry about disk groups and volumes; plexes are taken care of automatically by the LSM. In the remainder of this section, we'll look briefly at some simple examples of LSM configuration. Consult the documentation for full details.

The voldiskadd command is used to create new disk group.[32] This command takes the disks to be added to the group as its arguments:

[32] This discussion assumes that the LSM has been initialized by creating the root disk group. This is done with the volsetup command, which takes two or more disks as its arguments. The vold and voliod daemons should also be running (which happens automatically during a successful LSM installation).

# voldiskadd dsk3 dsk4  .. .

It is an interactive tool which will prompt you for the additional information it needs, including the disk group name (we'll use dg1 in our examples) and the use for each disk (data or spare).

If you later want to place additional disks into a disk group, you use the voldg command, as in this example, which adds several more disks to dg1:

# voldg -g dg1 adddisk dsk9 dsk10 dsk11

Volumes are generally created with the volassist command. For example, the following command creates a volume consisting of a concatenated plex named chemvol, essentially a logical volume comprised of space from multiple disks on which a filesystem can be built:

# volassist -g dg1 make chemvol 2g dsk3 dsk4

The volume is created using the dg1 disk group, using the specified disks (the disk list is optional). Its size is 2 GB.

We'll go on to make this a mirrored plex, using these commands:

# volassist -g dg1 mirror chemvol init=active layout=nolog dsk5 dsk6
# volassist addlog chemvol dsk7

The first command adds a mirror to the chemvol volume (we've again chosen to specify which disks to use). The second command adds the required logging area to the volume.

The same technique could be used to mirror a single disk by using only one disk in each volassist command.

We can create a striped plex in a similar way:

# volassist -g dg1 make stripevol 2g layout=stripe nstripe=2 dsk3 dsk4

This command creates a two-way striped volume named stripevol.[33]

[33] For more complex striped and RAID 5 plexes, you may need to define subdisks to force the various stripes to specific disks (e.g., to spread them across multiple controllers) as the default assignments made by the LSM often do not do so.

The following command will create a 3 GB RAID 5 volume:

# volassist -g dg1 make raidvol 3g layout=raid5 nstripe=5  disks

For both striped andRAID 5 volumes, you can also use the stripeunit attribute (following nstripe) to specify the stripe size.

Disk groups containing mirrored or RAID 5 volumes should include designated hot spare disks. The following commands designate dsk9 as a hot spare for our disk group:

# voledit -g dg1 set spare=on dsk9
# volwatch -s lsmadmin@ahania.com

The volwatch command enables automatic hot spare replacement (-s), and its argument is the email address to which to send notifications when these events occur.

Once an LSM volume is created, it can be placed within an AdvFS domain and used for creating filesets.

The following commands are useful in obtaining information about LSM entities:

voldg -g dg free

Display free space in a disk group.

voldisk list

List all component disks used by the LSM.

volprint -v

List all volumes.

volprint -ht volume

Display information about a specific volume.

volprint -pt

List all plexes.

volprint -lp plex

Display information about a specific plex.

volprint -st

List all subdisks.

volprint -l subdisk

Display information about a specific subdisk.

Finally, the volsave command is used to save the LSM metadata to a disk file, which can then be backed up. The default location for these files is /usr/var/lsm/db, but you can specify an alternate location using the command's -d option. The files themselves are given names of the form LSM.n.host, where n is a 14 digit encoding of the date and time. The volrestore command will restore the saved data should it ever be necessary.

10.3.3.7 Solaris

Solaris 9 introduces a logical volume manager as part of the standard operating system. This facility was available as an add-on product with earlier versions of Solaris (although there have been some changes with respect to previous versions—see the documentation for details).

The Solaris Volume Manager supports striping, mirroring, RAID 5, soft partitions (the ability to divide any disk into more than four partitions), and some other features. The Volume Manager must be initialized before its first use, using commands like these:

# metadb -a -f c0t0d0s7                   Create initial state database replicas.
# metadb -a -c 2 c1t3d0s2                 Add replicas on this slice.

We are now ready to create volumes. We will look briefly at some simple examples in the remainder of this section.

The Solaris Volume Manager uses fixed names for volumes of the form dn, where n is an integer from 0 to 127. Thus, the maximum number of volumes is 128. The metainit command does most of the work of creating and configuring volumes.

The following command will create a concatenated volume consisting of three disks:

# metainit d1 3 1 c1t1d0s2 1 c1t2d0s2 1 c1t3d0s2

The parameters are the volume name, the number of components (always greater than one for a concatenated volume), and then three pairs consisting of the number of component disks (always 1 here) followed by desired disk(s). When the command completes, the volume d1 can be treated as if it were a single disk partition.

You can expand an existingfilesystem using a similar command, as in this example, which expands the /docs filesystem (originally on c0t0d0s6):

# umount /docs
# metainit d10 2 1 c0t0d0s6 1 c2t3d0s2 Add additional disk space.
# vi /etc/vfstab                       Change the filesystem's devices to /dev/md/[r]dsk/md10.
# mount /docs
# growfs -M /dev/md/rdsk/d10           Increase the filesystem size to the volume size.

The following command will create a striped volume:

# metainit d2 1 2 c1t1d0s2 c2t2d0s2 -i 64k

The parameters following the volume name indicate that we are creating a singlestriped volume with two component disks, using a stripe size (interlace value) of 64 KB (-i).

You can mirror volumes using metainit's -m option, followed by the metattach command, as in this example:

# metainit d20 -f 1 1 c0t3d0s2         Create the volume to be mirrored.
# umount /dev/dsk/c0t3d0s2
# metainit d21 1 1 c2t1d0s2            Create a volume to be used as the mirror.
# metainit d22 -n d20                  Specify the volume to be mirrored.
# vi /etc/vfstab                       Modify entry to point to the mirror volume (d22).
# mount /dev/md/dsk/d22                Remount filesystem.
# metattach d22 d21                    Add a mirror.

In this case, we add a mirror to an existing filesystem. We use the -f option on the first metainit command to force a volume to be created from an existing filesystem.

If we were mirroring the root filesystem, we would run the metaroot command (specifying the mirror volume as its argument) and then reboot the system, rather than ummounting and remounting the filesystem.

Other volume types can also be mirrored—concatenated, striped, etc.—using just the final two commands.

You can specify the read and write policies for mirrored volumes using the metaparam command, as in this example:

# metaparam -r geometric -w parallel d22

The -r option specifies the read policy, one of roundrobin (successive read operations go to each disk in turn, which is the default), first (all reads go to the first disk), and geometric (read operations are divided between the component disks by assigning specific disk regions to each one). The geometric read policy can minimize seek times by confining disk head movement to a subset of the disk, which can produce measurable performance improvements for I/O that is seek time-limited (e.g., randomly accessed data, such as a database).

The -w parameter specifies the write policy, one of parallel (write to all disks at the same time, which is the default) and serial. The latter might be used to improve performance when both mirrors are on the same busy disk controller.

The following command will create aRAID 5 volume:

# metainit d30 -r  disks  -i 96k

This creates a RAID 5 volume using a stripe size of 96 KB. The default stripe size is 16 KB, and it must range from 8 KB to 100 KB.

Don't try to access a RAID 5 volume until it has finished initializing. This can take a while. You can check its status with the metastat command.

You can replace a failed RAID 5 component volume using the metareplace command, as in this example:

# metareplace -e d30 c2t5d0s2

Alternatively, you can define a hot spare pool from which disks can be taken as needed for all RAID 5 devices. For example, these commands create a pool named hsp001[34] and designate it for use with RAID 5 device d30:

[34] Hot spare pool names must be of the form hspnnn, where nnn ranges from 000 to 999. Why you would need 1000 hot space pools for 128 volumes is a good question.

# metainit hsp001 c3t1d0s2 c3t2d0s2
# metaparam -h hsp001 d30

You can modify the disks in a hot space pool using the metahs command and its -a (add), -r (replace), and -d (delete) options.

The last Volume Manager feature we'll consider is soft partitions. Soft partitions are simply logical partitions (subsets) of a disk. For example, the following command creates a volume consisting of 2 GB from the specified disk:

# metainit d7 -p c2t6d0s2 2g

When used with a new disk, you can add the -e option to the command. This causes the disk to be repartitioned so that all but 4 MB is in slice 0 (the 4 MB is in slice 7 and is used to hold a state database replica). For example, this command performs that repartitioning and then assigns 3 GB of slice 0 to volume d8:

# metainit d8 -p -e c2t5d0s2 3g

Once volumes are created, you can create a UFS filesystem on them using newfs as usual. You can also remove any volume with the metaclear command, which takes the desired volume as its argument. Naturally, any data on the volume will be lost.

The following commands are useful for obtaining information about the Volume Manager and individual volumes:

metadb

List all state database replicas.

metadb -I

Show status of state database replicas.

metastat d n

Show volume status.

metaparam d n

Show volume settings.

10.3.3.8 Linux

Linux systems can use both a logical volume manager and software disk striping and RAID, although the two facilities are separate. They are compatible, however; for example, RAID volumes can be used as components in the logical volume manager.

The Linux Logical Volume Manager (LVM) project has been in existence for several years (its homepage is http://www.sistina.com/products_lvm.htm), and support for the LVM is merged into the Linux 2.4 kernel. Conceptually, the LVM allows you to combine and divide physical disk partitions in a completely flexible manner. The resulting filesystems are dynamically resizable. The current version of the LVM supports up to 99 volume groups and 256 logical volumes. The maximum logical volume size is currently 256 GB.

The logical volume manager is included in some recent Linux distributions (for example, SuSE Linux 6.4 and later). If it is not included in yours, installing it is quite straightforward:

  • Download the LVM package and the appropriate kernel patch for your system.

  • Unpack and build the LVM package.

  • If necessary, patch the kernel source code and build a new kernel, enabling LVM support during the kernel configuration process. One way to do this is to use the make xconfig command. Use the Block Devices button from the main menu.

  • If you have selected modular support for the LVM, add entries to /etc/modules.conf to enable the modprobe command to load the LVM module at boot time. Here are the needed entries:

        alias  block-major-58  lvm-mod
    alias  char-major-109  lvm-mod

  • Install the new kernel into the boot directory, and enable its use with LILO or GRUB.

  • Modify the system startup and shutdown scripts to activate and deactivate the LVM configuration. Add these commands to the startup scripts:

        vgscan                     # Search for volume groups
    vgchange -a y              # Activate all volume groups

  • Add this command to the shutdown script:

        vgchange -a n              # Deactivate all volume groups

  • Reboot the system using the new kernel.

The LVM package includes a large number of administrative utilities, each of which is designed to create or manipulate a specific type of LVM entity. For example, the commands vgcreate, vgdisplay, vgchange, and vgremove create, display information about, modify the characteristics of, and delete a volume group (respectively). You can also backup and restore the volume group configurations with vgcfgbackup and vgcfgrestore, change the size of a volume group with vgextend (increase its size by adding disk space to it) and vgreduce (decrease its size), divide and combine volume groups (vgsplit and vgmerge), move a volume group between computer systems (vgexport and vgimport), search all local disks for volume groups (vgscan), and rename a volume group (vgrename). (Many of these commands are similar to the HP-UX equivalents.)

There are similar commands for other LVM entities:

Physical volumes

pvcreate, pvdisplay, pvchange, pvmove, and pvscan.

Logical volumes

lvcreate, lvdisplay, lvchange, lvremove, lvreduce, lvextend, lvscan, and lvrename.

Let's look at some of these commands in action as we create a volume group and some logical volumes and then build filesystems on them.

The first step is to set the partition type of the desired disk partitions to 0x8E. We use fdisk for this task; here is the process for the first disk partition:

# fdisk /dev/sdb1
Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): 8e
Command (m for help): w

The first time we use the LVM, we need to run vgscan to initialize the facility (among other things, it creates the /etc/lvmtab file). Next, we designate the disk partitions as physical volumes by specifying the desired disk partitions as command arguments to the pvcreate command (/dev/sdc2 is the second partition we will be using in our volume group):

# pvcreate /dev/sdb1 /dev/sdc2
pvcreate -- reinitializing physical volume
pvcreate -- physical volume "/dev/sdb1" successfully created
...

We are now ready to create a volume group, which we will name vg1:

# vgcreate vg1 /dev/sdb1 /dev/sdc2
vgcreate -- INFO: using default physical extent size 4 MB
vgcreate -- INFO: maximum logical volume size is 255.99 Gigabyte
vgcreate -- doing automatic backup of volume group "vg1"
vgcreate -- volume group "vg1" successfully created and activated

This command creates the vg1 volume group using the two specified disk partitions. In doing so, it creates/updates the ASCII configuration file /etc/lvmtab (which holds the names of the system's volume groups) and places a binary configuration file into two subdirectories of /etc: lvmtab.d/vg1 and lvmconf/vg1.conf (the latter directory will also store old binary configuration files for this volume group, reflecting changes to its characteristics and components).

The vgcreate command also creates the special file /dev/vg1/group, which can be used to refer to the volume group as a device.

Now we can create two 800 MB logical volumes:

# lvcreate -L 800M -n chem_lv vg1
lvcreate -- doing automatic backup of "vg1"
lvcreate -- logical volume "/dev/vg1/chem_lv" successfully created
# lvcreate -L 800M -n bio_lv -r 8 -C y vg1
lvcreate -- doing automatic backup of "vg1"
lvcreate -- logical volume "/dev/vg1/bio_lv" successfully created

We set the sizes of both logical volumes via the lvcreate command's -L option. In the case of the second logical volume, bio_lv, we also specify that the read-ahead mode chunk size is 8 sectors via -r (the amount of data returned at a time during sequential access) and specify that a contiguous logical volume be created (via the -C y option).

Once again, two new special files are created, each named after the corresponding logical volume and located under the volume group directory in /dev (here, /dev/vg1).

We can now create filesystems using the ordinary mke2fs command, specifying the logical volume as the device on which to build the new filesystem. For example, the following command creates an ext3 filesystem on the bio_lv logical volume:

# mke2fs -j /dev/vg1/bio_lv

Once built, this filesystem may be mounted as usual. You can also build a Reiser filesystem on a logical volume.

In addition to the previously mentioned commands, the LVM provides the e2fsadmin command, which can be used to increase the size of a logical volume and the ext2 or ext3 filesystem it contains a single, nondestructive operation. This utility requires the resize2fs utility (originally developed by PowerQuest as part of its PartitionMagic product and now available under the GPL at http://e2fsprogs.sourceforge.net).

Here is an example of its use; the following command adds 100 MB to the bio_lv logical volume and the filesystem that it contains:

# umount /dev/vg1/bio_lv
# e2fsadm /dev/vg1/bio_lv -L+100M
e2fsck 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vg1/bio_lv: 11/51200 files (0.0% non-contiguous), 6476/819200 blocks
lvextend -- extending logical volume "/dev/vg1/bio_lv" to 900 MB
lvextend -- doing automatic backup of volume group "vg1"
lvextend -- logical volume "/dev/vg1/bio_lv" successfully extended

resize2fs 1.19 (13-Jul-2000)
Begin pass 1 (max = 5)
Extending the inode table     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 25)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/vg1/bio_lv is now 921600 blocks long.

e2fsadm -- ext2fs in logical volume "/dev/vg1/bio_lv"
successfully extended to 900 MB

Note that the filesystem must be unmounted in order to increase its size.

To use the Linux software RAID facility, you must install the component disks, enable RAID support in the kernel and then set up the RAID configuration. You can perform the second task using a utility like make xconfig and selecting the Block Devices category from the main menu. The Multiple devices driver support item is the one that must be enabled to access all of the other RAID-related items. I recommend enabling all of them.

RAID devices use special files of the form /dev/mdn (where n is an integer), and they are defined in the /etc/raidtab configuration file. Once defined, you can create them using the mkraid command and start and stop them with the raidstart and raidstop commands. Alternatively, you can define them with the persistent superblock options, which enables automatic detection and mounting/dismounting of RAID devices by the kernel. In my view, the latter is always the best choice.

The best way to understand the /etc/raidtab file is to examine some sample entries. Here is an entry corresponding to a striped disk using two component disks, which I have annotated:

raiddev /dev/md0                      Defines RAID device 0.
raid-level 0                          RAID level.
nr-raid-disks 2                       Number of component disks.
chunk-size 64                         Stripe size (in KB).
persistent-superblock 1               Enable the persistent superblock feature.
device /dev/sdc1                      Specify the first component disk ...
raid-disk 0                               and number it.
device /dev/sdd1                      Same for all remaining component disks.
raid-disk 1

If we had wanted to define a two-way mirror set instead of a stripe set, using the same disks, we would omit the chunk-size parameter and change the raid-level parameter from 0 to 1 in the first section, and the rest of the entry would remain the same.

We can set up a RAID 0+1 disk, a mirrored striped disk, in this way:

raiddev /dev/md0
...Set up the first striped disk.
raiddev /dev/md1
...Set up the second striped disk.

raiddev /dev/md2
raid-level 1
nr-raid-disks 2
persistent-superblock 1
device /dev/md0                        The component disks are also md devices.
raid-disk 0
device /dev/md1
raid-disk 1

The following entry defines a RAID 5 disk containing 5 component disks, as well as a spare disk to be automatically used should any of the active disks fail:

raiddev /dev/md0
raid-level 5                           Use RAID level 5.
nr-raid-disks 5                        Number of active disks in the device.
persistent-superblock 1
device /dev/sdc1                       Specify the 5 component disks.
raid-disk 0
device /dev/sdd1
raid-disk 1
device /dev/sde1
raid-disk 2
device /dev/sdf1
raid-disk 3
device /dev/sdg1
raid-disk 4
device /dev/sdh1                       Specify a spare disk.
spare-disk 0

You can use multiple spare disks if you want to.

RAID devices can be used with the logical volume manager if desired.

10.3.3.9 FreeBSD

FreeBSD provides theVinum Volume Manager. It uses somewhat different concepts than other LVMs. Under Vinum, a drive is a physical disk partition. Disk space is allocated from drives in user-specified chunks known as subdisks. Subdisks in turn are used to define plexes, and one or more plexes makes up a Vinum volume. Multiple plexes within a volume constitute mirrors.

NOTE

Be prepared to be very patient when learning Vinum. It is quite inflexible in how it wants operations to be performed. Plan to learn the procedures on a safe test system.

In addition, be aware that the facility is still under development. As of this writing, only the most basic functionality is present.

To use a disk partition with Vinum, it must be prepared as follows:

  • Create one or more slices on it using fdisk.

  • Create an initial disk label using disklabel or sysinstall. I prefer the latter. If you choose to use sysinstall, create a single swap partition in each slice that you want to use with Vinum. Ignore the messages about it being unable to start the swap partition (you don't want it to anyway).

  • Modify the disk label using disklabel -e. Only the partition list at the bottom will need to be changed. It must look like this when you are done:

        #        size   offset    fstype   [fsize bsize bps/cpg]
      c: 11741184        0    unused              # (Cyl.    0 - 11647)
      e: 117411184       0    vinum

    If you used sysinstall to create the initial disk label, all you have to do is add the final line.

Partition e is somewhat arbitrary, but it works. Note that partition c cannot be used with Vinum.

Once the drives are prepared, the best way to proceed is to create a description file that defines the Vinum entities that you want to create. Here is a file that defines a volume named big:

drive d1 device /dev/da1s1e            Define drives.
drive d2 device /dev/da2s1e
volume big                             Define volume big.
  plex org concat                      Create a concatenated plex.
    sd length 500m drive d1            First 500 MB subdisk from drive d1.
    sd length 200m drive d2            Second 200 MB subdisk from drive d2.

The file first defines the drives to be used, naming them d1 and d2. Note that this operation needs to be performed only once for a given partition. Future example configurations will omit drive definitions.

The second section of the file defines the volume big as one concatenated plex (org concat). It consists of two subdisks: 500 MB of space from /dev/da1s1e and 200 MB of space from /dev/da2s1e. This disk space will be treated as a single unit.

You can create these entities using the following command:

# vinum create /etc/vinum.big.conf

The final argument specifies the location of the description file.

Once the volume is created, you can create a filesystem on it:

# newfs -v /dev/vinum/big

The device is specified via the file in /dev/vinum named for the volume. The -v option tells newfs not to look for partitions on the specified device. Once newfs completes, the filesystem may be mounted. For it to be detected properly at boot time, however, the following line must be present in /etc/rc.conf:

start_vinum="YES"

This causes the Vinum kernel module to be loaded on boots.

Here is a description file that defines a striped (RAID 1) volume:

volume fast
  plex org striped 1024k
    sd length 0 drive d1
    sd length 0 drive d2

This stripe set consists of two components. The plex line has an additional entry, the stripe size. This value must be a multiple of 512 bytes. The subdisk definitions specify a length of 0; this corresponds to all available space in the device. The actual volume can be created using the vinum create command as before.

If both of these volumes were created, then different areas of the various disk partitions would be used by each one. Vinum drives can be subdivided among different volumes. You can specify the location with the drive when the subdisk is created (see the vinum(8) manual page for details).

The following configuration file creates amirrored volume by defining two plexes:

volume mirror
  plex org concat                      First mirror.
    sd length 1000m drive d1
  plex org concat                      Second mirror.
    sd length 1000m drive d2

Creating and activating the mirrored volume requires several vinum commands (the output is not shown):

# vinum create  file                     Create the volume.
# vinum  init mirror.p1                  Initialize the subdisk.
Wait for command to finish.
# vinum start mirror.p1                 Activate the mirror.

When you first create a mirrored volume, the state of the second plex appears in status listings as faulty, and its component subdisk has a status of empty. The vinum init command initializes all of the component subdisks of plex mirror.p1, and the vinum start command regenerates the mirror (actually, creates it for the first time). Both of these commands start background processes to do the actual work, and you must wait for the initialization to finish before running the regeneration. You can check on their status using this command:

# vinum list

Once both of these commands have completed, you can build a filesystem and mount it.

The following description file created aRAID 5 volume named safe:

volume safe
  plex org raid5 1024k
    sd length 0 drive d1
    sd length 0 drive d2
    sd length 0 drive d3
    sd length 0 drive d4
    sd length 0 drive d5

This volume consists of a single plex containing five subdisks. The following commands can be used to create and activate the volume:

# vinum create  file                     Create the volume.
# vinum init safe.p0                    Initialize the subdisks.

Once again, the initialization process runs in the background, and you must wait for it to finish before creating a filesystem.

As a final example, consider this description file:

volume zebra
  plex org striped 1024k
    sd length 200m drive d1
    sd length 200m drive d2
  plex org striped 1024k
    sd length 200m drive d3
    sd length 200m drive d4

This file defines a volume named zebra, which is a striped mirrored volume (RAID 0+1). The volume consists of two striped plexes which become mirrors. The following commands are required to create and activate this volume:

# vinum create  file                     Create the volume.
# vinum init zebra.p0 zebra.p1          Initialize subdisks.
# vinum start zebra.p1                  Regenerate the mirror.

The following commands are useful for displaying Vinum information:

vinum list

Display information about all Vinum entities.

vinum ld

List drives, including current free space.

vinum lv

List volumes.

vinum ls

List subdisks.

vinum ls -v

Display subdisk details, including the plex they are part of and their component drives.

vinum lp

List plexes.

vinum lp -v

Display plex details, including the volume they belong to.

You can follow any of these commands with the name of a specific item to limit the display to its characteristics.

Here is an example of the vinum list command:

4 drives:
D d1                State: up       Device /dev/ad1s1e      Avail: 2799/2999 MB (93%)
D d2                State: up       Device /dev/ad1s2e      Avail: 2799/2999 MB (93%)
D d3                State: up       Device /dev/ad1s3e      Avail: 2799/2999 MB (93%)
D d4                State: up       Device /dev/ad1s4e      Avail: 532/732 MB (72%)

1 volumes:
V zebra             State: up       Plexes:       2 Size:        400 MB

2 plexes:
P zebra.p0        S State: up       Subdisks:     2 Size:        400 MB
P zebra.p1        S State: faulty   Subdisks:     2 Size:        400 MB

4 subdisks:
S zebra.p0.s0       State: up       PO:        0  B Size:        200 MB
S zebra.p0.s1       State: up       PO:     1024 kB Size:        200 MB
S zebra.p1.s0       State: R 16%    PO:        0  B Size:        200 MB
S zebra.p1.s1       State: R 16%    PO:     1024 kB Size:        200 MB

This display shows the zebra volume we defined earlier. The subdisk initialization has completed. At this moment, the regeneration operation is 16% complete.

10.3.4 Floppy Disks

On systems with floppy disk drives, Unix filesystems may also be created on floppy disks. (Before they can be used, floppy disks must, of course, be formatted.) But why bother? These days, it is usually much more convenient to use floppy disks in one of the following ways:

  • Mounted as a DOS-type filesystem whose files can then be accessed with standard utilities like cp and ls.

  • Using special utilities designed to read and write files to and from DOS disks (we'll look at specific examples in a minute).

10.3.4.1 Floppy disk special files

Floppy disks are accessed using the followingspecial files (the default refers to a 1.44 MB 3.5-inch diskette):

AIX
/dev/fd0
FreeBSD
/dev/fd0
HP-UX
/dev/dsk/c0t1d0 (Normal disk naming convention)
Linux
/dev/fd0
Solaris
/dev/diskette
Tru64
/dev/fd0

Floppy disk special files are only occasionally needed on Solaris systems, because these devices are managed by the media handling daemon (discussed later in this chapter).

10.3.4.2 Using DOS disks on Unix systems

Methods for accessing DOS disks vary widely from system to system. In this section, we'll look at formatting diskettes in DOS format and copying files to and from them on each system.

Under HP-UX, the following commands format a DOS floppy disk:

$ mediainit -v -i2 -f16 /dev/rdsk/c0t1d0
$ newfs -n /dev/rdsk/c0t1d0 ibm1440

The -n option on the newfs command prevents boot information from being written to the diskette.

HP-UX provides a number of utilities to access files on DOS diskettes: doscp, dosdf, doschmod, dosls, dosll, dosmkdir, dosrm, and dosrmdir. Here is an example using doscp:

$ doscp /dev/rdsk/c0d1s0:paper.txt paper.new

This command copies the file paper.txt from the diskette to the current HP-UX directory.

On Linux and FreeBSD systems, a similar process is used. These commands format a DOS floppy and write files to it:

Linux

FreeBSD

# fdformat /dev/fd0
# mkfs -t msdos /dev/fd0
# mount /dev/fd0 /mnt
# cp prop2.txt /mnt
# umount /mnt

# fdformat /dev/fd0
# newfs_msdos /dev/fd0
# mount /dev/fd0 /mnt
# cp prop2.txt /mnt
# umount /mnt

The Mtools utilities are also available on Linux and FreeBSD systems (described in the next section).

AIX also provides several utilities for accessing DOS disks: dosformat, dosread, doswrite, dosdir, and dosdel. However, they provide only minimal functionality—for example, there is no wildcard support—so you'll be much happier and work more efficiently if you use the Mtools utilities.

On Solaris systems, diskettes are controlled by the volume management system and its vold daemon. This facility merges the diskette as transparently as possible within the normal Solaris filesystem.

These commands could be used to format a diskette and create a DOS filesystem on it:

$ volcheck
$ fdformat -d -b g04

The volcheck command tells the volume management system to look for new media in the devices that it controls. The fdformat command formats the diskette, giving it a label of g04.

The following commands illustrate the method for copying files to and from diskette:

$ volcheck
$ cp ~/proposals/prop2.txt /floppy/g96
$ cp /floppy/g96/drug888.dat ./data
$ eject

The diskette is mounted in a subdirectory of /floppy named for its label (or in /floppy/unnamed_floppy if it does not have a label). Configuration of vold is discussed later in this chapter.

Tru64 provides no support for DOS diskettes, so you'll need to use the Mtools utilities, to which we will now turn.

10.3.4.3 The Mtools utilities

The Mtools package is available for all the Unix versions we are considering. It is currently maintained by David Niemi and Alain Knaff (see http://mtools.linux.lu).

The package contains a series of utilities for accessing DOS diskettes and their files, modeled after their similarly named DOS counterparts:

mformat

Format a diskette in DOS format.

mlabel

Label a DOS diskette.

mcd

Change the current directory location on the diskette.

mdir

List the contents of a directory on a DOS diskette.

mtype

Display the contents of a DOS file.

mcopy

Copy files between a DOS diskette and Unix.

mdel

Delete file(s) on a DOS diskette.

mren

Rename a file on a DOS diskette.

mmd

Create a subdirectory on a DOS diskette.

mrd

Remove a subdirectory from a DOS diskette.

mattrib

Change DOS file attributes.

Here are some examples of using the Mtools utilities:

$ mdir
Volume in drive A is GIAO24
Directory for A:/
SILVERDAT79    1-29-95   9:36p
PROP43_1 TXT2304    1-29-95   9:33p
REFCARD  DOC73216    1-13-95   5:28p
3 File(s)     1381376 bytes free
$ mren prop43_1.txt prop43_1.old
$ mcopy a:refcard.doc .
Copying REFCARD.DOC
$ mcopy proposal.txt a:
Copying PROPOSAL.TXT
$ mmd data2
$ mcopy gold* a:data2
Copying GOLD.DAT
Copying GOLD1.DAT
$ mcopy "a:\data\*.dat" ./data
Copying NA.DAT
Copying HG.DAT
$ mdel silver.dat

As these examples illustrate, the Mtools utilities are designed to make accessing diskettes as painless as possible. For example, it generally assumes that files being referred to are on the floppy disk. The only time that you have to refer explicitly to the diskette—via the a: construct—is with the mcopy command, which makes sense because there is no other way to know which direction the copy is taking place. Note also that filenames on diskette are not case-sensitive.

10.3.4.4 Stupid DOS partition tricks

On PC-based Unix systems, hard-disk DOSpartitions can also be mounted within the Unix filesystem. This allows not only for copying files between Unix and the other operating systems, but also for handling the entire partition using Unix utilities. For example, suppose you decide to change the partitioning scheme on your boot disk, decreasing the size of the DOS partition (without affecting the Unix partitions). The following commands will let you do so without reinstalling DOS, Windows, or any installed software:

# mount -t msdos /dev/hdal /mnt        Linux is used as an example.
# cd /mnt
# tar -c -f /tmp/dos.tar *
# unmount /mnt
Mess with partitions and/or filesystems.
# mount -t msdos /dev/hda1 /mnt
# cd /mnt
# tar -x -f /tmp/dos.tar
# cd /; umount /mnt

You could restore only some of the files from the tar archive if that is what made sense. Many other operations along these lines are also possible: for example, moving the DOS partition from the first hard drive to the second one, copying a DOS partition between systems or across a network, and so on. There are, of course, other ways of accomplishing these same tasks, but this procedure is often much faster.

When the partition in question is the Windows boot partition, this procedure works very well with older and simpler Windows versions such as Windows 98 and Windows ME. For Windows NT and later, you may have to alter the Boot.Ini file to get the system to boot.

10.3.5 CD-ROM Devices

CD-ROM drives are also generally treated in a manner similar to disks. The following special files are used to access SCSI CD-ROM devices:

AIX
/dev/cd0
FreeBSD
/dev/cd0c or /dev/acd0c (SCSI or ATAPI)
Linux
/dev/cdrom
Solaris
/dev/dsk/c0tnd0s02 (Normal disk naming conventions)
HP-UX
/dev/dsk/cmtnd0 (Normal disk naming conventions)
Tru64
/dev/disk/cdrom0c

The following example commands all mount a CD on the various systems:

mount -o ro -v cdrfs /dev/cd0 /mnt         AIX
mount -r -t cd9660 /dev/cd0c /mnt          FreeBSD
mount -o ro -F cdfs /dev/dsk/c1t2d0 /mnt   HP-UX
mount -r -t iso9660 /dev/sonycd_31a /mnt   Linux
mount -o ro -t hsfs /dev/c0t2d0s0 /mnt     Solaris
mount -r -t cdfs /dev/disk/cdrom0c /mnt    Tru64

Entries can also be added to the filesystem configuration file for CD-ROM filesystems.

10.3.5.1 CD-ROM drives under AIX

On AIX systems, if you add a CD-ROM drive to an existing system, you'll need to create a device for it in this manner:

# mkdev -c cdrom -r cdrom1 -s scsi -p scsi0 -w 5,0
cd0 available

This command adds a CD-ROM device using SCSI ID 5.

Individual CDs are usually mounted via predefined mount points. For example, the following commands create a generic CD-ROM filesystem to be mounted on /cdrom:

# mkdir /cdrom
# crfs -v cdrfs -p ro -d cd0 -m /cdrom -A no

This filesystem will be mounted read-only and will not automatically be mounted when the system boots. A CD may now be mounted with the mount /cdrom command.

The lsfs command may be used to list all defined CD-ROM filesystems:

$ lsfs -v cdrfs
Name     Nodename  Mount Pt                   VFS   Size  Options  Auto  Acct
/dev/cd0 --       /cdrom                      cdrfs --    ro       no    no
10.3.5.2 The Solaris media-handling daemon

Solaris has a similar media handling facility implemented by the vold daemon. It generally mounts CDs and diskettes in directory trees rooted at /cdrom and /floppy, respectively, creating a subdirectory named for the label on the current media (or unnamed_cdrom and unnamed_floppy for unlabeled ones).

There are two configuration files associated with the volume management facility. /etc/vold.conf specifies the devices that it controls and the filesystem types it supports:

# Volume Daemon Configuration file
#

# Database to use (must be first)
db db_mem.so

# Labels supported
label dos label_dos.so floppy
label cdrom label_cdrom.so cdrom
label sun label_sun.so floppy

# Devices to use
use cdrom drive /dev/dsk/c0t6 dev_cdrom.so cdrom0
use floppy drive /dev/diskette dev_floppy.so floppy0

# Actions
insert /vol*/dev/diskette[0-9]/* user=root /usr/sbin/rmmount
insert /vol*/dev/dsk/* user=root /usr/sbin/rmmount
eject /vol*/dev/diskette[0-9]/* user=root /usr/sbin/rmmount
eject /vol*/dev/dsk/* user=root /usr/sbin/rmmount
notify /vol*/rdsk/* group=tty /usr/lib/vold/volmissing -c

# List of file system types unsafe to eject
unsafe ufs hsfs pcfs

The section labeled Actions indicates commands to be run when various events occur—media is inserted or removed, for example. The final section lists filesystem types that must be unmounted before being removed and hence will require the user to issue an eject command.

If you want to share mounted CDs via the network, you'll need to add an entry to /etc/rmmount.conf :

# Removable Media Mounter configuration file.
#

# File system identification
ident hsfs ident_hsfs.so cdrom
ident ufs ident_ufs.so cdrom floppy
ident pcfs ident_pcfs.so floppy

# Actions
action -premount floppy action_wabi.so.1
action cdrom action_filemgr.so
action floppy action_filemgr.so

# File System Sharing
share cdrom*
share solaris_2.x* -o ro:phys

File-sharing entries are in the final section of this file. An entry is provided for sharing standard CD-ROM filesystems (mounted at /cdrom/cdrom*). The -o in the second entry in this section passes options to the share command, in this case limiting access. You can modify the provided entry for CD-ROMs if appropriate. Shared CD-ROM filesystems can be mounted by other systems using the mount command and entered into their /etc/vfstab files.

Tru64 also has a vold daemon. However, it is part of its Logical Storage Manager facility and thus performs a completely different function.


10.4 Sharing Filesystems

In the final section of this chapter, we consider sharing localfilesystems with other systems, including Windows systems. It covers the most common Unix filesystem sharing facility, NFS, and the Samba facility, which makes Unix filesystems available to Windows systems.

More information about NFS is available in NFS and NIS by Hal Stern, Mike Eisler and Ricardo Labiaga (O'Reilly & Associates). More information about Samba is available in the books Teach Yourself Samba in 24 Hours by Gerald Carter with Richard Sharpe (SAMS) and Using Samba by Robert Eckstein, David Collier-Brown, and Peter Kelly (O'Reilly & Associates).

10.4.1 NFS

The Network File System (NFS) enables filesystems physically residing on one computer system to be used by other computers in the network, appearing to users on the remote host as just another local disk.[35] NFS is universally available on Unix systems.

[35] However, NFS assumes that users will have accounts with the same UID on both systems.

The following configuration files are used by NFS:

/etc/fstab (/etc/vfstab under Solaris)

Remote filesystems are entered into the filesystem configuration file, using only a slightly varied syntax from regular entries.

/etc/exports

This file controls which filesystems on the local system can be mounted by remote hosts and under what conditions and restrictions. On Solaris systems, this file is not used, but the file /etc/dfs/dfstab performs an analogous function.

Table 10-10 lists the daemons used by NFS and the files that start them in the various Unix versions.

Table 10-10. NFS daemonsa

Item

AIX

FreeBSD

HP-UX

Linux

Solaris

Tru64

Main NFS daemon

nfsd

nfsd

nfsd

rpc.nfsd

nfsd

nfsd

Handles mount requests

mountd

mountd

mountd

rpc.mountd

mountd

mountd

Block/asynch. I/O

biod

nfsiod

biod

nfsiod

File locking

rpc.lockd

rpc.lockd

rpc.lockd

rpc.lockd

lockd

Rpc.lockd

Network status monitor

rpc.statd

rpc.statd

rpc.statd

rpc.statd

statd

Rpc.statd

RPC port mapper

portmap

portmap

portmap

portmap

rpcbind

portmap

Boot script(s)[36]

/etc/rc.nfs

/etc/rc.network

/sbin/init.d/nfs.*

/etc/init.d/nfs*

/etc/init.d/nfs.*

/etc/init.d/nfs*

[36] The portmap daemon is started by a different file, as part of general TCP/IP initialization.

A few remarks about some of these daemons are in order:

  • The nfsd daemon handles filesystem exporting and file access requests from remote systems. An NFS server—any system that makes its filesystems available to other computers—runs multiple instances of this daemon.

  • The biod daemon performs NFS (block) I/O operations for client processes. Multiple instances of this daemon typically run on NFS clients.

  • The mountd daemon handles mount requests from remote systems.

  • The rpc.lockd daemon manages file locking on both server and client systems.

  • The rpc.statd daemon handles lock, crash, and recovery services (client and server).

  • The portmap daemon facilitates initial connection between local and remote servers (not strictly an NFS daemon but required for the NFS server facility to function).

As Table 10-10 indicates, the names of these daemons vary on some systems.

10.4.1.1 Mounting remote directories

As we've noted, remote filesystems may be entered into the filesystem configuration file in order to allow them to be automatically mounted at boot time. The format for an NFS entry is:

host:pathname mount-pt nfs options 0 0

where the first field is a concatenation of the remote hostname and the pathname to the mount point of the desired filesystem on the remote host, joined with a colon. For example, to designate the filesystem mounted at /organic on host duncan, use duncan:/organic. The filesystem type field is set to nfs, and the remaining fields have their usual meanings. Note that the dump frequency and fsck pass fields should be zero.

Here is an example:

# device         mount             type  options  dump fsck
duncan:/organic  /duncan/organic   nfs   bg,intr     0 0

On Solaris systems, the /etc/vfstab entries look like this:

# mount          fsck
# device         dev   mount             type  pass  auto?  options
duncan:/organic  -     /remote/organic   nfs    -    yes    bg,intr

In addition to options for local filesystems, there are many other options available for remote filesystems. The most important are summarized in Table 10-11.

Table 10-11. Important NFS-specific mounting options

Option

Meaning

bg

If the NFS mount of this filesystem fails on the first try, continue retrying in the background. This speeds up booting when remote filesystems are unavailable.

retry=n

Number of mount retries before giving up (100,000 is the default).

timeo=n

Set the timeout—the length of time to wait for the first try of each individual NFS request before giving up—to the specified number of tenths of seconds. Each subsequent retry doubles the previous timeout value.

retrans=n

Retransmit a request n times before giving up (the default is 3).

soft, hard

Quit or continue trying to connect even after the retrans value is met.

intr

Allow an interrupt to kill a hung process.

rsize=n

wsize=n

The size of the read or write buffer in bytes. Tuning these sizes can have a significant impact of NFS performance on some systems.

The soft and hard options are worth special mention. They define the action taken when a remote filesystem becomes unavailable. If a remote filesystem is mounted as hard, NFS will try to complete any pending I/O requests forever, even after the maximum number of retransmissions is reached; if it is mounted soft, an error will occur and NFS will cancel the request.

If a remote filesystem is mounted hard and intr is not specified, the process will block (be hung) until the remote filesystem reappears. For an interactive process especially, this can be quite annoying. If intr is specified, sending an interrupt signal to the process will kill it. This can be done interactively by typing Ctrl-C (although it won't die instantly; you'll still have to wait for the timeout period). For a background process, sending an INT (2) or QUIT (3) signal will usually work (again not necessarily instantaneously):

#  kill -QUIT 34216

Sending a KILL signal (-9) will not kill a hung NFS process.

It would seem that mounting filesystems soft would get around the process-hanging problem. This is fine for filesystems mounted read-only. However, for a read-write filesystem, a pending request could be a write request, and so simply giving up could result in corrupted files on the remote filesystem. Therefore, read-write remote filesystems should always be mounted hard, and the intr option should be specified to allow users to make their own decisions about hung processes.

Here are some additional example /etc/fstab entries for remote filesystems:

duncan:/benzene    /rings    nfs rw,bg,hard,intr,retrans=5  0  0
portia:/propel     /peptides nfs ro,soft,bg,nosuid          0  0

The first command mounts the filesystem mounted at /benzene on the host duncan under /rings on the local system. It is mounted read-write, hard, with interrupts enabled. The second command mounts the /propel filesystem on the host portia under /peptides; this filesystem is mounted read-only, and the SetUID status of any of its files is ignored on the local host.

Under AIX, remote filesystems have stanzas in /etc/filesystems like local ones, with some additional keywords:

/rings: Local mount point.
    dev        =  /benzene             Remote filesystem.
    vfs        =  nfs                  Type is NFS.
    nodename   =  duncan               Remote host.
    mount      =  true                 Mount on boot.
    options    =  bg,hard,intr         Mount options.

Once defined in the filesystem configuration file, the short form of the mount command may be used to mount the filesystem. For example, the following command mounts the proper remote filesystem at /rings:

# mount /rings

The mount command may also be used to mount remote filesystems on an ad hoc basis, for example:

# mount -t nfs -o rw,hard,bg,intr duncan:/ether /mnt

This command mounts the /ether filesystem from duncan under /mnt on the local system. Note that the option that specifies the filesystem type varies on some systems. In fact, the filesystem type is usually superfluous.

10.4.1.2 Exporting local filesystems

The /etc/exports file controls the accessibility of local filesystems to network access (except on Solaris systems; see below). Its traditional form consists of a series of lines containing a local filesystem moun t point and followed by one or more hostnames:

/organic    spain canada
/inorganic

This export configuration file allows the hosts spain and canada to mount the /organic filesystem and any remote host to remotely mount the /inorganic filesystem.

The preceding examples present only the simplest examples of filesystem export options. In fact, any filesystem, directory, or file can be exported, not just the entire filesystem. And there is greater control over the type of access allowed. Entries in /etc/exports consist of lines of the form:

pathname -option,option...

pathname is the name of the file or directory to which network access will be allowed. If pathname is a directory, all of the files and directories below it within the same local filesystem are also exported, but not any filesystems mounted within it. The second field in the entry consists of options specifying the type of access to be given and to whom.

A filesystem should be exported only once to a given host. Exporting two different directories within the same filesystem to the same host doesn't work in general.

Here are some sample entries from /etc/exports (note that only the first option in the list is preceded by a hyphen):

/organic    -rw=spain,access=brazil:canada,anon=-1
/metal/3    -access=duncan:iago,root=duncan
/inorganic  -ro

This file allows the host spain to mount /organic for reading and writing and the hosts brazil and canada to mount it read-only, and it maps anonymous users—usernames from other hosts that do not exist on the local system and the root user from any remote system—to the UID -1. This corresponds to the nobody account, and it tells NFS not to allow such a user access to anything. On some systems, the UID -2 may be used to allow anonymous users access only to world-readable files. The -rw option exports the directory read-write to the hosts specified as its argument and read-only to all other allowed hosts; this access is referred to as read-mostly.

Note that hosts within a list are separated by colons.

The second entry grants read-write access to /metal/3 to the hosts duncan and iago, and allows root users on duncan to retain that status and its access rights when using this filesystem. The third entry exports /inorganic read-only to any host that wants to use it.

Table 10-12 lists the most useful exports file options.

Table 10-12. Useful exports file options

Option

Meaning

rw=list ro=list

Read-write and read-only access lists. rw is the default.

root=list

List of hosts where root status may be retained for this filesystem.

anon=n

Map remote root access to this UID.

maproot=n

Map remote root access to this UID (FreeBSD).

mapall=n

Map all remote users to this UID (FreeBSD).

root_squash

Map UID 0 and GID 0 values to the anonymous values (under Linux, to those specified in the anonuid and anongid options). This is the default.

anonuid=n anongid=n

UID/GID to which to map incoming root/group 0 access (Linux).

noaccess

Prohibits access to the specified directory and its subdirectories (Linux). This option is used to prevent access to part of a tree that has already been exported.

secure

Require access to be via the normal privileged NFS port (Linux). This is the default. I do not recommend ever using the insecure option.

If you modify /etc/exports, the exportfs command must be run to put the new access restrictions into effect. The following command puts all of the access information in /etc/exports into effect:

# exportfs -a

FreeBSD does not provide the exportfs command. You can use this command instead:

# kill -HUP `cat /var/run/mountd.pid`

Tru64 also does not have exportfs. The NFS mountd daemon detects changes to the file automatically.

The showmount command may be used to list exported filesystems (using its -e option) or other hosts that have remotely mounted local filesystems (-a). For example, the following command shows that the hosts spain and brazil have mounted the /organic filesystem:

# showmount -a
brazil:/organic
spain:/organic

This data is stored in the file /etc/rmtab. This file is saved across boots, so the information in it can get quite old. You may want to reset it from time to time by copying /dev/null onto it (the system boot scripts take care of this automatically when NFS is started).

NOTE

If you're having trouble allowing other systems to mount the local filesystems from some particular system, the first thing to check is that the NFS server daemons are running. These daemons are often not started by default. If they are not running, you can start them manually, using the boot script listed in Table 10-10.

10.4.1.2.1 Exporting directories under Linux

The exports file has a slightly different format on Linux systems; options are included in parentheses at the end of the entry:

/organic     spain(rw) brazil(ro) canada(ro)
/metal/3     *.ahania.com(rw,root_squash)
/inorganic   (ro)

Based on this file, /organic is exported read-write to spain and read-only to brazil and canada. /metal/3 is exported read-write to any host in the domain ahania.com, with UID 0 access mapped to the nobody account. /inorganic is exported read-only to the world.

10.4.1.2.2 Exporting filesystems under Solaris

On Solaris systems, filesystem exporting is done via the /etc/dfs/dfstab configuration file, which stores the share commands needed to export filesystems. The following dfstab file is equivalent to the exports file we looked at previously:

share -F nfs -o rw=spain,access=brazil:canada,anon=-1 /organic
share -F nfs -o access=duncan:iago,root=duncan /metal/3
share -F nfs -o ro /inorganic

For example, the first line exports the /organic filesystem: it allows spain to mount it for reading and writing and brazil and canada to mount it read-only. Requests from usernames without accounts on the local system are denied.

These same commands need to be executed manually to put these access restrictions into effect prior to the next reboot (be sure that mountd is running).

10.4.2 The NFS Automounter

Once a network has even a moderate number of systems in it, trying to cross-mount even one or two filesystems from each system can quickly become a nightmare. The NFS automounter facility is designed to handle such situations by providing a means by which remote directories are mounted only when they are needed: when a user or process uses or refers to a file or subdirectory located within the remote directory. Directories that have not been used in a while are also unmounted automatically.

Using the automounter has the potential for simplifying remote directory management. The filesystem configuration file is made more straightforward because it lists only local filesystems and perhaps one or two statically mounted remote filesystems or directories. Booting is faster because NFS mounts are done later. Systems can also be shut down unexpectedly with fewer ill effects and hung processes.

The automounter works by detecting attempted access to any part of the remote directories under its control. When such an event occurs, the automounter generally mounts the remote filesystem into a directory known as its staging area—usually /tmp_mnt—and creates a (pseudo) symbolic link to the mount location expected by the user. For example, if a user attempts to copy the file /data/organic/strained/propell.com, and /organic is a directory on host spain, the automounter will mount that remote directory on /tmp_mnt and create a link to the local mount point, /data/organic. To the user, the file will look like it really is located in /data/organic/strained; however, if he changes to the directory /data/organic and issues a pwd command, the real mount point will be visible (confusion is also likely if he uses a command like cd .. after moving to an automounted directory until he gets used to how the automounter works).

The automounter uses configuration files known as maps, which are of two types:

  • Direct maps hold entries for remote directories to be mounted on demand by the automounter. These entries are really just abbreviated versions of traditional NFS /etc/fstab entries.

  • Indirect maps are used for local directories whose subdirectories are each NFS-mounted, most likely from different remote hosts. For example, user home directories are usually managed with an indirect map. They are all automounted at a standard location within the filesystem on every system within a network, even though every one of them may be physically located on a separate system.

Indirect maps are used far more frequently than direct ones.

Direct maps are conventionally stored in /etc/map.direct. Here is a sample entry from a direct map:

/metal/3    -intr    dalton:/metal/3

This entry places the directory /metal/3 on host dalton under automounter control. The directory will be mounted when needed at /metal/3 on the local system; directories controlled by direct maps do not use the automounter staging area. The second field in the entry holds options for the mount command.

Indirect maps are generally named for the local directory whose (potential) contents they specify. Here is a short version of the indirect map /etc/auto.homes, which is used to configure the local directory /homes; its entries specify the remote locations of the various subdirectories of /homes:

chavez-rw,intr  dalton:/home/chavez
harvey-rw,intr  iago:/home/harvey
wang-rw,intr  portia:/u/wang
stein-rw,intr  hamlet:/home/stein4

The format is very similar to that for direct maps. In this case, the first field is the name of the subdirectory of /homes from which the remote directory will be accessed locally. Note that we have set up automounting at /homes, not in the usual location of /home, because it is illegal to mix local and automounted subdirectories within the same local directory.

Once the automounter is configured in this way on every system, user home directories will be invariant to the system the user happens to be using. No matter where he is, his home directory will always have the same files within it.

The automounting facility uses the automount daemon, which may be started with a command like this one:

# automount -tl 600 /homes /etc/auto.homes /- /etc/auto.direct

The -tl option specifies how long a directory must be idle before it is automatically unmounted (in seconds; five minutes is the default). The next two arguments illustrate the method for specifying a local directory for automounter control and its corresponding indirect map. The final two arguments illustrate how a direct map is specified; the local directory is always specified as /- for a direct map. A command like the previous needs to be added to (or uncommented out within) the system initialization scripts for the automounter to be started at boot time.

If you want to stop the automounter process for some reason, use the kill command without any signal option; this will send the process a TERM signal and allow it to terminate gracefully and clean up after itself. For example:

# kill `ps -ea | grep automoun | awk '{print $1}'`

If you kill it with -9, hung processes and undeletable phantom files are the almost certain result.

10.4.3 Samba

The freeSamba facility allows Unix filesystems to be shared with Windows systems. Samba does so by supporting the Server Message Block (SMB) protocol,[37] the native resource sharing protocol for Microsoft networks. It is available for all of the Unix versions we are considering.

[37] Also known as theCommon Internet File System, CIFS (this week...).

With Samba, you can make Unix filesystems look like shared Windows filesystems, allowing them to be accessed using the normal Windows facilities and commands such as net use . Linux systems can also mount Windows filesystems within the Unix filesystem using a related facility.

Installing Samba is quite simple. The books I mentioned earlier have excellent discussions of the procedure. Once you have built Samba, the next step is to create the Samba configuration file, smb.conf, usually stored in the lib subdirectory of the main Samba directory or in /etc/samba.

Here is a simple version of this file:

[global]                               Global settings applying to all exports.
hosts allow = vala, pele
hosts deny = lilith
valid users = dagmar, @chem, @phys, @bio, @geo
invalid users = root, admin, administrator
max log size = 2000                    Log size in KB.
[chemdir]                              Define a directory (share) for export.
path = /chem/data/new                  Local (Unix) path to be shared.
comment = New Data                     Description of the filesystem.
read only = no                         Filesystem is not read-only.
case sensitive = yes                   Filenames are case sensitive.
force group = chemists                 Map all user access to this Unix group.
read list = dagmar, @chem, @phys       Users/groups allowed read access.
write list = @chem                     Users/groups allowed write access.

The first section of the configuration file, introduced by the [global] line, specifies global Samba settings that apply to all filesystems exported via the facility. Its first two lines specify remote systems that are allowed to access Samba filesystems and those that are forbidden from doing so, respectively. The next two lines similarly specify Unix users and groups that are allowed and denied access (note that group names are prefixed by an at sign: @chem). The final line of this first section specifies the maximum size of the Samba log file in KB.

The second section of the sample Samba configuration file defines a filesystem for exporting (i.e., a share). In this case, it consists of the local path /chem/data/new, and it will be accessed by remote systems using the share name chemdir (defined in the section's header line). This exported filesystem is exported read-write and uses case-sensitive filenames. All incoming access to the filesystem will take place as if the user were a member of the local Unix chemists group. Windows user dagmar and groups chem and phys are allowed read access to the filesystem, and members of Windows group chem are also given write access. Whether an individual file may be read or written will still be determined by its Unix file permissions.

User home directories are exported in a slightly different way via configuration file entries like these:

[homes]                                Create the special homes share.
comment = Home directories
writeable = yes
valid users = %S                       %S expands to the share name (here = username).

These entries create a share for each local Unix user home directory (as defined in the password file). These shares are actually created on the fly as they are accessed. For example, if user chavez attempts to access the share \\india\home (where india is the Unix system), the share \\india\chavez will be created and presented to her. Only she will be able to access this share due to the valid users line in the homes share definition; all other users will be denied access. User chavez can access the share as either \\india\homes or as \\india\chavez.

You can use the testparm command to verify the syntax of a Samba configuration file before you install it. See the Samba documentation for full details on configuration file entries.

Another useful Samba feature is the username mapping file, specified via a configuration file entry like the following:

username map = /etc/samba/smbusers

Entries within the file look like this:

# Unix = Windows
chavez = rachel
root = Administrator admin             Multiple names are allowed.
quigley = "Filbert Quigley"            Quote names with spaces.

Map files can have some unexpected effects. For one thing, when a password is required by the Unix system before access is granted, it is that password for the Unix account that will be needed. This can be confusing if the mapping sends a user to an account that is different from the one he usually uses. Secondly, home share names will again reflect the mapped Unix username.

The smbstatus command may be used to display current remote users of local filesystems on the Unix system:

$ smbstatus
Samba version 1.9.16
Service  uid     gid      pid   machine
----------------------------------------------
chemdir  nobody  chemists 14810 vala (192.168.13.34) Jul 14 11:51:07
No locked files
10.4.3.1 Samba authentication

In general, Samba prompts the user for a password when required. By default, these passwords are sent across the network in unencrypted form (i.e., as clear text). This is an insecure practice that most sites will find unacceptable. Samba can be modified to use only encoded passwords as follows:

  • Add the following entries to the global section of the Samba configuration file:

    encrypt passwords = yes
security = user

  • Use the mksmbpasswd.sh script included with the Samba package source code to create the initial Samba password file. For example:

    # cat /etc/passwd | mksmbpasswd.sh > /etc/samba/private/smbpasswd

  • The smbpasswd file should be owned by root and have the permissions mode 600. The subdirectory in which it resides should be protected 500.

Once encrypted passwords are enabled, users must use the smbpasswd command in order to set their Samba passwords.

You can use a single Unix server to authenticate all Samba passwords by using these configuration file entries:

security = server
password server = host
encrypt passwords = yes

You can authenticate Samba using a Windows domain controller with these configuration file entries:

security = domain
workgroup = domain
password server = domain-controllers
encrypt passwords = yes

See the Samba documentation and the previously cited books for more details about this topic (including how to use a Samba server as a Windows domain controller).

10.4.3.1.1 Mounting Windows filesystems under Linux and FreeBSD

The Samba package includes the smbclient utility in order to access remote SMB-based shares from the Unix system. It uses an interface similar to the FTP facility.

A much better approach is provided onLinux systems via the built-in smbfs filesystem type. For example, the following command mounts the depot share on vala as the local directory /win_stuff:

# mount -t smbfs -o username= user ,password= xxx  //vala/depot /win_stuff

This command makes the connection as the specified user account on the Windows system using the specified password. If the password option is omitted, you will be prompted for the proper password. If you do include a password in the /etc/fstab file, be sure to protect the file from ordinary users. In general, you should not use the Administrator password. Create an unprivileged user account to use for the mount process instead.

A similar facility is available under FreeBSD Version 4.5 and later. For example:

# mount_smbfs -I vala //chavez@vala/depot /mnt
Password:                              Not echoed.

Passwords can be stored in a file named $HOME/.nsmbrc. In this case, add the -N option to the command to suppress the password prompt. Here is a sample file:

[VALA:CHAVEZ:DEPOT]                    server:user:share
password=xxxxxxxx

Yes, the first line really does have to be in uppercase (ugh!).

You can also enter such filesystems into /etc/fstab on either system, using entries like these:

# remote share       mount point  type  options
//chavez@vala/depot  /depot/vala  smbfs noauto 0 0                            FreeBSD
//vala/depot         /depot/vala  smbfs noauto,username=chavez,password=x 0 0 Linux

Under FreeBSD, you'll need to specify the password in the .nsmbrc file if you want to remote share to mounted automatically.


11.1 Planning for Disasters and Everyday Needs

Developing an effective backup strategy is an ongoing process. You usually inherit something when you take over an existing system and start out doing the same thing you've always done when you get a new system. This may work for a while, but I've seen companies try to retain their centralized, hordes-of-operators-based backup policies after they switched from a computer room full of mainframes to a building full of workstations. Such an attempt is ultimately as comical as it is heroic, but it all too often ends up only in despair, with no viable policy ever replacing the outdated one. The time to develop a good backup strategy is right now, starting from however you are approaching things at the moment.

Basically,backups are insurance. They represent time expended in an effort to prevent future losses. The time required for any backup strategy must be weighed against the decrease in productivity, schedule slippage, and so on if the files are needed but are not available. The overall requirement of any backup plan is that it be able to restore the entire system—or group of systems—within an acceptable amount of time in the event of a large-scale failure. At the same time, a backup plan should not sacrifice too much in the way of convenience, either in what it takes to get the backup done or how easy it is to restore one or two files when a user deletes them accidentally. The approaches one might take when considering only disaster recovery or only day-to-day convenience in isolation are often very different, and the final backup plan will need to take both of them into account (and will accordingly reflect the tension between them).

There are many factors to consider in developing a backup plan. The following questions are among the most important:

  • What files need to be backed up?

    The simplest answer is, of course, everything, and while everything but scratch files and directories needs to be saved somewhere, it doesn't all have to be saved as part of the system backups. For example, when the operating system has been delivered on CD-ROM, there is really no need to back up the system files, although you may choose do so anyway for reasons of convenience.

  • Where are these files?

    This question involves both where the important files are within the filesystem and which systems hold the most important data.

  • Who will back up the files?

    The answer may depend on where the files are. For example, many sites assign the backup responsibility for server systems to the system administrator(s) but make users responsible for files that they keep on their workstation's local disks. This may or may not be a good idea, depending on whether or not all of the important files really get backed up.

  • Where, when, and under what conditions should backups be performed?

    Where refers to the computer system on which the backup will be performed; this need not necessarily be the same as the system where the files are physically located. Similarly, in an ideal world, all backups would be performed after hours on unmounted filesystems. That's not always practical in the real world, however.

  • How often do these files change?

    This information will help you decide both when and how often to perform backups and the type of schedule to implement. For example, if your system supports a large, ongoing development project, the files on it are likely to change very frequently and will need to be backed up at least daily and probably after hours. On the other hand, if the only volatile file on your system is a large database, its filesystem might need to backed up several times every day while the other filesystems on the same system would be backed up only once a week.[1]

    [1] In actual fact, a database is often backed up using a facility provided by the software vendor, but you get the idea here.

  • How quickly does an important missing or damaged file need to be restored?

    Since backups protect against both widespread and isolated file loss, the timeframe in which key files need to be back online needs to be taken into account. The number of key files, how widely spread they are throughout a filesystem (or network), and how large they are will also influence matters. Your system may only have one irreplaceable file, but you'll need to plan very differently depending on whether it is 1 KB or 1 GB in size. Note that losing even a single 1 KB file can wreak havoc if it's the license file without which the central application program won't run.

  • How long do we need to retain this data?

    Backups protect current data from accidents. As such, they are normally needed—or useful—only for a relatively short period (months or a year or two) In contrast, most sites also need to create permanent archives of important "point-in-time" data, for example, the software and data used to prepare a tax return. These need to be saved for an indefinite period: many years or even decades. While the requirements are similar, the goals are different enough that you are unlikely to be able to rely on your regular backups for archival purposes. Thinking about this kind of data and how to create and store it must be part of every effective backup plan.

  • Where should the backup media be stored?

    Recent backups are generally kept close to the computer for quick restoration. Long-term backups and archives should be stored in a secure offsite location.

  • Where will the data be restored?

    Will the backup files be used only on the system from which they were made, or is there an expectation that they could be restored to a different system in an emergency? If multisystem compatibility is ever important, it needs to be taken into account in designing the backup and recovery plan. For example, you might need to ensure that any compression scheme in use on one system can be decoded by the other target systems (or avoid using any vendor-specific formats). Other examples of this sort of issue include access control list data that might be backed up along with files and backups of a filesystem from a system that is larger than the maximum filesystem size on the target system.

NOTE

Virtually all Unix documentation recommends that filesystems be unmounted before a backup is performed (except for the root filesystem). This recommendation is rarely followed, and in practice, backups can be performed on mounted filesystems. However, you need to make users aware that open files are not always backed up correctly. It is also true that there are circumstances in which events in an active filesystem can cause some files or even the entire backup archive itself to be corrupt. We will consider those that are relevant to the various availablebackup programs as we discuss them.

11.1.1 Backup Capacity Planning

Once you have gathered all the data about what needs to be backed up and the resources available for doing so, a procedure like the following can be used to develop the detailed backup plan itself:

  1. Begin by specifying an idealbackup schedule without considering any of the constraints imposed by your actual situation. List what data you would like to be backed up, how often it needs to be backed up, and what subdivisions of the total amount make sense.

  2. Now compare that ideal schedule to what is actually possible in your environment, taking the following points into consideration:

    • When the data is available to be backed up: backing up open files is always problematic—the best you can hope for is to get an uncorrupted snapshot of the state of the file at the instant that the backup is made—so, ideally, backups should be performed on idle systems. This usually translates to after normal working hours.

    • How many tape drives (or other backup devices) are available to perform backups at those times and their maximum capacities and transfer rates: in order to determine the latter, you can start with the manufacturer's specifications for the device, but you will also want to run some timing tests of your own under actual conditions to determine realistic transfer rates that take into account the system loads, network I/O rates, and other factors in your environment. You will also need to take into account whether all the data is accessible to every backup device or not.

    At this point (as with any aspect of capacity planning), there is no substitute for doing the math. Let's consider a simple example: a site has 180 GB of data that all needs to be backed up once a week, and there are 3 tape drives available for backups (assume that all of the data is accessible to every drive). Ideally, backups should be performed only on week nights between midnight and 6 A.M. In order to get everything done, each tape drive will have to back up 60 GB of data in the 30 hours that the data is available. That means that each tape drive must write 2 GB of data per hour (333 KB/sec) to tape.

    This is within the capabilities of current tape drives when writing local data.[2] However, much of the data in our example is distributed across a network, so there is a chance that data might not be available at a fast enough rate to sustain the tape drive's top speed. Some backup programs also pause when they encounter an open file, giving it a chance to close (30 seconds is a typical wait period); when there are a lot of open files in a backup set, this can substantially increase how long the backup takes to complete.

    [2] In practice, of course, you would also need an auto loading tape device (or someone to change tapes in the middle of the night).

    In addition, we have not made any allowances for performing incremental backups (discussed below) between full backups. Thus, this example situation seems to strain the available resources.

  3. Make modifications to the plan to take into account the constraints of your environment. Our example site is cutting things a bit too close for comfort, but they have several options for addressing this:

    • Adding additional backup hardware, in this case, a fourth tape drive.

    • Decreasing the amount of data to be backed up or the backup frequency: for example, they could perform full backups only every two weeks for some or all of the data.

    • Increasing the amount of time available/used for backups (for example, performing some backups on weekends or doing incremental backups during the early evening hours).

    • Staging backups to disk. This scheme writes the backup archives to a dedicated storage area. The files can then be written to tape at any subsequent time. Disks are also faster than tape drives, so this method also takes less time than directly writing to tape. It does, of course, require that sufficient disk space be available to store the archives.

  4. Test and refine the backup plan. Actually trying it out will frequently reveal factors that your on-paper planning has failed to consider.

  5. Review the backupplan on a periodic basis to determine if it is still the best solution to your site's backup needs.

11.1.2 Backup Strategies

The simplest and most thorough backup scheme is to copy all the files on a system to tape or other backup media. A full backup does just that, including every file within a designated set of files, often defined as those on a single computer system or a single disk partition.[3]

[3] For the purposes of this discussion, I'll focus on per-disk partition backups, but keep in mind that this is not the only reasonable way of organizing things. I'll also refer to "backup tapes" most of the time in this chapter. In most cases, however, what I'll be saying will apply equally well to other backup media.

Fullbackups are time-consuming and can be unwieldy; restoring a single file from a large backup spanning multiple tapes is often inconvenient, and when files are not changing very often, the time taken to complete a full backup may not be justified by the number of new files that are actually being saved. On the other hand, if files are changing very rapidly, and 50 users will be unable to work if some of them are lost, or when the amount of time a backup takes to complete is not an issue, then a full backup might be reasonable even every day.

Incremental backups are usually done more frequently. In an incremental backup, the system copies only those files that have been changed since some previous backup. Incrementals are used when full backups are large and only a small amount of the data changes within the course of, say, one day. In such cases, backing up only the changed files saves a noticeable amount of time over performing a full backup.

Some Unix backup programs use the concept of a backup level to distinguish different kinds of backups. Each backup type has a level number assigned to it; by definition, a full backup is level 0. Backing up the system at any level means saving all the files that have changed since the last backup at the previous level. Thus, a level 1 backup saves all the files that have changed since the last full (level 0) backup; a level 2 backup saves all the files that have been changed since the last level 1 backup, and so on.[4]

[4] Not all backup commands explicitly use level numbers, but the concept is valid for and can be implemented with any of the available tools, provided you are willing to do some of the record keeping yourself (by hand or by script).

A typical backup strategy using multiple levels is to perform a full backup at the beginning of each week, and then perform a level 1 backup (all files that have changed since the full backup) each day. The following weekly backup schedule summarizes one implementation of this plan:

Monday: Level 0 (full)
Tuesday-Friday: Level 1 (incremental)

A seven-day version of this approach is easy to construct.

The primary advantage of this plan is that only two sets of backup media are needed to restore the complete filesystem (the full backup and the incremental). Its main disadvantage is that the daily backups will gradually grow and, if the system is very active, may approach the size of the full backup set by the end of the week.

A popular monthly plan for sites with very active systems might look something like this:

First Monday: Level 0 (full)
All other Mondays: Level 1 (weekly incremental to previous Level 0)
Tuesday-Friday: Level 2 (daily incremental to previous Level 1)

This plan will require three sets of backup media to do a complete restore (the most recent backup of each type).

In deciding on a backup plan, take into account how the system is used. The most heavily used portions of the filesystem may need to be backed up more often than the other parts (such as the root filesystem, which contains standard Unix programs and files and which therefore rarely changes). A few parts of the system (like /tmp) need never be backed up. You may want to create some additional filesystems that will never be backed up; anyone using them would be responsible for backing up his own files.

You should also consider performing a full backup—whether the schedule calls for it or not—before you make significant changes to the system, such as building a new kernel, adding a new application package, or installing a new version of the operating system. This may be one of the few times that the root filesystem gets backed up, but if you ever have a problem with your system disk, you will find it well worth the effort when you can avoid a significant amount of reconfiguration.

11.1.2.1 Unattended backups

The worst part of doing backups is sitting around waiting for them to finish. Unattended backups solve this problem for some sites. If the backup will fit on a single tape, one approach is to leave a tape in the drive when you leave for the day, have the backup command run automatically by cron during the night, and pick up the tape the next morning.

Sometimes, however, unattended backups can be a security risk; don't use them if untrusted users have physical access to the tape drive or other backup device and thus could steal the media itself. Backups needed to be protected as strongly as the most secure file on the system.

Similarly, don't do unattended backups when you can't trust users not to accidentally or deliberately write over the tape or other rewriteable media (ejecting the tape after the backup is completed sometimes prevents this, but not always). You also won't be able to use them if the backup device is in heavy use and can't be tied up by the backup for the entire night.

11.1.2.2 Data verification

In many cases,backups can simply be written to media, and the media can go directly to its designated storage location. This practice is fine as long as you are 100% confident in the reliability of your backup devices and media. In other cases, data verification is a good idea.

Data verification consists of a second pass through the backed-up data, in which each file is compared to the version on disk, ensuring that the file was backed up correctly. It also verifies that the media itself is readable.

Some sites will choose to verify the data on all backups. All sites should perform verification operations on at least a periodic basis for all of their backup devices. In addition, as they age and wear out, many devices begin to produce media that can only be successfully read in the drive that produced it. If you need backups that will be readable by devices or systems other than the one that originally wrote on the physical media, you should also periodically verify the backups' readability by examining them on the target devices and systems.

11.1.2.3 Storing backup media

Properly storing thebackup tapes, diskettes, or other media once you've written them is an important part of any backup plan. Here are some things to keep in mind when deciding where to store your backup media:

  • Know where things are

    Having designated storage locations for backups makes finding the right one quickly much more likely. It is also important that anyone who might need to do a restore knows where the media are kept (you will want to take a vacation occasionally). Installation CDs, bootable recovery tapes, boot diskettes, and the like also ought to be kept in a specific location known to those people who may need them. I can assure you from personal experience that a system failure is much more unpleasant when you have to dig through boxes of tapes or piles of CDs looking for the right one before you can even attempt to fix whatever's wrong with the system.

    Another aspect of knowing where things are concerns figuring out what tape holds the file that you need to restore. Planning for this involves making records of backup contents, which is discussed later in this chapter.

  • Make routine restorations easy

    Backups should be stored close enough to the computer so that you can quickly restore a lost file, and tapes should be labeled sufficiently well so that you can find the ones you need.

    Ideally, you should have a full set of tapes for each distinct operation in your backup schedule. For example, if you do a backup every day, it's best to have five sets of tapes that you reuse each week; if you can afford it, you might even have 20 sets that you rotate through every four weeks. Using a single set of tapes over and over again is inviting disaster.

    Labeling tapes clearly is also a great help in finding the right one quickly later. Color-coded labels are favored by many sites as an easy yet effective way to distinguish the different sets of tapes. At the other extreme, I visited a site where the backup system they developed prints a detailed label for the tape at the conclusion of each backup.

  • Write-protect backup media

    This prevents backup media from being accidentally overwritten. The mechanism for write-protection varies with different media types, but most mechanisms involve physically moving a plastic dial or tab to some designated position. The position that is the unwriteable one varies: floppy disks, optical disks and DAT (4mm) tapes are writeable when the tabbed opening is closed, while 8mm tapes and removable disks are writeable when it is open.

  • Consider the environment

    Most backup media like it cool, dry, and dark. High humidity is probably the most damaging environment, especially for cartridge-enclosed media, which are easily ruined by the moisture condensation that accompanies temperature drops in humid conditions. Direct sunlight should also be avoided, especially for floppy disks, since most plastic materials will deform when subjected to the temperature within the trunk of a car or the enclosed passenger compartment on a hot summer day. Dust can also be a problem for most backup media. I've had lint make floppy disks unreadable after taking them home in my coat pocket (now I put them in a zip-top plastic bag first).

    The fact that backup media prefer the same environment used for many computer rooms does not necessarily mean that any or all backup media should be stored in the same room as the computer. Doing so runs the risk that a major problem will destroy both the computer and the backups. Backup tapes are actually more sensitive to some types of problems than some computer components. For example, if a pipe bursts above the computer room, the computer may suffer only minor damage, but your backup tapes will usually all be ruined if they get wet.

    If the tape storage area differs in temperature from the computer area by more than a few degrees, allow the tapes to acclimate to the computer temperature before writing to them.

    Magnetic interference is also something to think about. One of this book's technical reviewers relayed a story about "an entire backup library that kept getting wiped out on a nearly daily basis. Turns out that the tapes were in a secure location but placed against a wall that was shared with a freight elevator. The magnetic fields and such caused by the moving lift caused all that nice magnetic tape storage to become erased. Funny but cautionary."

  • Handle media properly

    Some media have special requirements that you'll need to take into account. For example, floppy disks and zip disks ideally should be stored upright, resting on a thin edge rather than stacked on top of one another. Similarly, cartridge tapes like to be stored with the spools vertical (perpendicular to the ground, like a car's tires) with the edge that contacts the drive heads down (so gravity pulls tape away from the spools). When you're counting on media to preserve important data, humor them and orient them the way they prefer.

  • Take security into account

    In every location where you store backup tapes, the usual physical security considerations apply: the tapes should be protected from theft, vandalism, and environmental disasters as much as is possible.

11.1.2.4 Off-site and long-term storage

Off-site backups are the last barrier between your system and total annihilation. They are full backup sets that are kept in a locked, fireproof, environmentally-controlled location completely off site. Such backups should be performed on unmounted filesystems if at all possible.

Preparing backups for off-site storage is also one of the few times when simply making a backup is not enough.[5] In these cases, you also need to verify that the backup tape or diskette is readable. This is done by using an appropriate restore command to list the contents of the tape or diskette. While this will not guarantee that every file is completely readable, it will improve the odds of it considerably. Some backup utilities provide a full verification facility in which the entire content of each file in a backup set is compared with the corresponding file on disk; this is the preferred method of checking critical backups. In any case, backups should be verified in the best way available whenever the integrity of the backup is essential.

[5] Another such time is when you are rebuilding a filesystem.

NOTE

For data meant for permanent archiving, you should create and verify two sets of backup media with the idea that the redundant copy can be used should the first one fail. The media should also be checked periodically (annually or possibly biannually). When a particular media item fails—and they all will eventually—a new copy should be made from the other one to replace it.

You should also make sure that you have at least one working drive of the type that you are using for permanent storage media. For example, if you have an archive of 8 mm tapes, you will need to always have working 8 mm tape drives to read them. This will continue to be true if your primary backup medium changes. Similarly, you must maintain whatever software programs and other running environment is required to use the data for it to be of any use.

Finally, tapes should be rewound or retensioned regularly (perhaps twice a year) to maintain readability. Given this requirement, tapes are being superceded by CDs as permanent storage media.

When Being Compulsive is Good

It's very easy to put off doing backups, especially when you are responsible only for your own files. However, performing backups regularly is vital. Basically, it's a good idea to assume that the next time you sit down at the computer, all your disks will have had head crashes. Keeping such a catastrophe in mind will make it obvious what needs to be backed up and how often. Backups are convenient for restoring accidentally deleted files, but they are also essential in the event of serious hardware failures or other disasters. Catastrophes will happen. All hardware has a finite lifetime, and eventually something will fail.

Given this reality, it is obvious why an almost drone-like adherence to routine is an important attribute for an effective system administrator. Planning for worst-case scenarios is part of the job. Let them call you compulsive if they want to; one day, your compulsiveness—also known to many as carefulness—will save them, or at least their files.


11.2 Backup Media

When I first started working as a system administrator, 9-track tape was the only medium you'd consider using for abackup.[6] That's certainly no longer true. Today, there are many different media suitable for storing backed-up data. This section provides a quick summary of the available choices. This list includes most of the drives and media types which are in common use. The backup strategy for any particular system will often involve more than one media type.

[6] The only other possibilities were punch cards and paper tape.

Up-to-the-minute information about available backup devices and media may be obtained from http://www.storagemountain.com. There is also an excellent discussion in Unix Backup and Recovery.

11.2.1 Magnetic tape

Magnetic tape of one sort or another has been the traditional backup medium for decades. Over the years, it has taken on a variety of sizes and forms, beginning with 7-track and then 9-track tape: 1/2-inch wide tape wound around a circular reel. The introduction of plastic cartridges containing the tape and both reels was a major step forward in terms of reducing the space requirements of backup media. The first tape of this type was 1/4-inch cartridge tape (also known as QIC tape), which for a while was the medium of choice for most workstations; these tapes are still occasionally used.

Around 20 years ago, higher-capacity tapes in formats originally developed for other markets became available. 8 mm tape drives became popular in the late 1980s and are still in wide use. Originally designed for video uses, the tapes are about the size of an audio cassette. 4 mm digital audio tapes (commonly called DAT tapes although the data storage scheme is technically known as DDS) are also in wide use. DAT cartridges are about 25% smaller than 8 mm tapes.

8 mm and 4 mm tapes come in two grades, one designed for video and audio recording (respectively), and a better, more expensive grade designed for data. Be sure to purchase only data-quality tapes. Although lower-quality tapes will sometimes appear to work fine, in my experience they are much, much less reliable about retaining data (despite urban legends to the contrary).

Both of these tape types are in use today, although DAT is far more prevalent than 8 mm. Both types of tape come in a variety of lengths and corresponding data capacities. Currently, the largest ordinary 8 mm tapes are 160 meters long and hold up to 7 GB of data,[7] although there are also tapes that hold 1.2 GB (54 m) and 2.4 GB (112 m). DAT tapes correspond to various DDS levels:

[7] That is, 7 GB of bits. The amount of "data" written may be much more if the original files are compressed before or as they are written to tape. Tape drive and media manufacturers love to inflate their products' capacities by quoting maximum compressed data numbers.

DDS-1

2 and 3 GB tapes (60 and 90 m

DDS-2

4 GB tapes (120 m)

DDS-3

12 GB tapes (125 m)

DDS-4

20 GB tapes (150 m)

DDS-3 and DDS-4 use a different technology than the earlier versions.

Be aware that only the newest tape drives can support the largest tapes, but most drives provide read-only backward compatibility.

There are also several newer magnetic tape technologies. Exabyte's Mammoth-2[8] and Sony's Advanced Intelligent Tape (AIT) technologies take 8 mm tapes to much higher capacities: 20, 40, or 60 GB and 35 or 50 GB, respectively. They both use the Advanced Metal Evaporative (AME) cartridge developed by Sony (a new 8 mm format). Some Mammoth-2 drives can also read earlier 8 mm tapes, but they require an extensive clearing procedure to be performed after each instance. These are also among the fastest tape drives, with transfer rates of up to 12 MB/s for Mammoth-2 drives and 6 MB/s for AIT drives.

[8] This was preceded by the Mammoth technology, which was notoriously unreliable. Mammoth-2 initially seems to be better.

The Digital Linear Tape (DLT) technology was initially developed by Digital Equipment Corporation, but they later sold it to Quantum Corporation. This format uses cartridges similar to DEC's old TK family, which have proven themselves to be extremely reliable and long-lived. It is also a fast format, with transfer rates of up to 10 MB/s.

The high capacity of magnetic tapes make them ideal for unattended backups: you can put a tape in at night, start a shell script that puts several filesystems on one tape, and go home.

Tapes also have some disadvantages:

  • They are extremely sensitive to heat and electromagnetic fields and fail quite easily when they are mishandled. Electromagnetic fields are produced by a variety of common devices found near computers, including UPS power supplies, external peripheral devices containing their own power supplies, monitors, and speakers. Moreover, simply reading a magnetic tape also contributes to data degradation.

  • They are sequential storage devices. In order to reach a given file on a tape, you have to wind the tape to the proper point. This is more of a problem for older tapes drives; current high-end drives can reach an arbitrary point on a tape in seconds.

11.2.2 Magneto-optical disks

Magneto-optical disks have the same width and length as floppy disks but are about twice as thick and hold a lot more data. Magneto-optical disks also come in 3.5-inch and 5.25-inch versions,[9] and their current capacity ranges up to 9.1 GB. Optical disks are purported to be much more stable than any of the purely magnetic media; the stability comes from the fact that they are written magnetically but are read optically, so reading the disk has no degrading effect on the stored data. In addition, the media can also be erased and rewritten as needed. Finally, magneto-optical disks also have the advantage of being random access devices. Transfer rates for these devices peak at about 5 MB/s.

[9] You might wonder what is so magical about 3.5 and 5.25 inches. Devices of this size fit easily into the standard device bays found in PCs as well as into available storage boxes.

Current drives are still quite expensive—over $2000—as are the disks themselves, but they are nevertheless very popular. As I noted in the previous edition of this book (circa 1995), "a rewriteable medium that can permanently store over a gigabyte of data in the space of a couple floppy disks probably has a future." Now it's gigabytes of data and a definite future.

There are also other optical formats used or in development by a few manufacturers.

11.2.3 CDs and DVDs

Writeable CDs and DVDs have become viable backup media due to the substantial price reductions for both drives and media. There are two types of writeable CDs, referred to as CD-R (write-once CDs) and CD-RW (rewriteable CDs). Both come in 640 MB capacity, and recently 700 MB CD-R media have become available.

Writeable DVD technology is just emerging into the general marketplace at this writing. In fact, there are several DVD recording formats:

DVD-RAM

The first available format, it is now falling out of use since it cannot be read in ordinary DVD drives.

DVD-R

Write-once DVDs (also an aging technology).

DVD-RW

Rewriteable DVDs that can be read by ordinary DVD drives.

DVD+RW

An emerging technology devised by a coalition of drive manufacturers. These drives can produce ordinary (sequential) DVDs as well as random access disks. The former are readable by ordinary DVD players (but not by recorders of the other types), although some older models may require firmware updates. DVD+RW media can hold up to 4.7 GB per side.

As of this writing, Hewlett-Packard has recently released a low-cost DVD+RW writer suitable for use on PC-based systems, so this may become a popular backup device in that market in time.

11.2.4 Removable disks: Zip and Jaz

Removable disks are fully enclosed disk units that are inserted into a drive as needed. They tend to be significantly more reliable than either tapes or floppy disks. On Unix systems, they generally behave like a hard disk, but it is also possible to treat them as a giant floppy disk. They are suitable as backup media in some environments and circumstances.

There have been a variety of removable disk technologies over the years. The Zip and Jaz drives by Iomega have come to dominate this market. Zip drives—which come in 100 MB and 250 MB sizes—can be used with most Unix systems. Jaz drives, which have capacities of 1 GB or 2 GB, can also be used. I had a great deal of trouble with early Jaz drives, which were designed for infrequent, intermittent backup use and consistently failed when used on even a semi-continuous basis. More recent drives are said to be better. Both drive types are available with various I/O interfaces: SCSI, USB, IDE.

11.2.5 Floppy disks

Floppy disk drives are still found on most PC-based computer systems,[10] and they do have some limited backup uses. For example, PC-based Unix versions (as well as a few running on larger systems) often use floppy disks for emergency boot devices. In addition, floppy disks can be useful for inherently limited backup tasks, such as saving customized system configuration files from the root filesystem. Standard floppy disks hold 1.44 MB, and some Unix workstations include drives that double that capacity to 2.8 MB. Occasionally, you will come across a floppy drive that also supports Super disks: media that look like floppy disks but hold 120 MB.

[10] Although this will probably no longer be true in a couple of years.

11.2.6 Hard disks

Given the low prices of harddisks these days, they may also be a viable backup target device in some circumstances. For example, some sites provide a large backup disk on the local network where users can make periodic copies of key files that they are working on. Large disks can also be used for scratch purposes, for temporary data repositories and data holding areas, and similar purposes. They can also be used as a staging area where backups are stored temporarily on the way to being written to tape or other media.

11.2.7 Stackers, jukeboxes, and similar devices

There are a variety of devices designed to make media handling more automated, as well as to store and make available large numbers of media units. For example, there are auto-loading tape drives—also known as stackers—which can feed tapes automatically from a stack of 10 or so. Early stackers could access the component tapes only in order, but many current devices can retrieve any desired tape.

Another type of device puts multiple drive units into a box that looks to users like a single tape drive with the combined capacity of all of its components. Alternatively, such a device can be used to make multiple identical tapes simultaneously.

Still other units combine both multiple drives and tape auto-loading capabilities. These devices are known as jukeboxes or libraries .[11] The most sophisticated of them can retrieve a specific tape and place it into the desired drive. Some of these devices include integrated bar-code readers so that tapes can be identified by their physical label rather than storage location or electronic label. Similar devices also exist for optical disks and writeable CD-ROMs.

[11] Very large libraries (greater than 500 volumes) are known as silos. The two types of devices used to be distinguished by whether or not multiple hosts could be connected, but some libraries now have this capability. Separate silos are also able to pass tapes between them.

11.2.8 Media Lifetime

From time to time, you also need to think about the reasonable expected lifetime of your backup media. Stored under the right conditions, tapes can last for years, but unfortunately you cannot count on this. Some manufacturers recommend replacing tapes every year. This is certainly a good idea if you can afford to do so. The way that tapes and diskettes are stored also affects their lifetime: sunlight, heat, and humidity can all significantly shorten it. I always replace tapes that have had read errors or other failures more than once, regardless of their age; for some people and situations, a single failure is enough. I always throw away diskettes and Zip disks at the first hint of trouble.

Even so-called permanent media like CDs actually have a finite lifetime. For example, CDs begin to fail after about 5 years (and sometimes even sooner). Accordingly, creating two copies of important data and checking them periodically is the only prudent course.

Given these considerations, your site may want to consider alternative media for off-site and archival backups. For example, manufacturers of optical disks claim a lifetime of 15 years for this media (this is based on accelerated aging tests; as of this writing, we won't know for about 8-9 years whether this is really true).

11.2.9 Comparing Backup Media

Table 11-1 lists the most important characteristics of a variety of backup media. The largest media capacity for each item shown is the biggest that was available as of this writing. These size values refer to raw data capacity: the actual amount of data that can be written to the media.

The drive price is the lowest generally available price at this time and can be assumed to use the least expensive I/O interface; you can expect SCSI versions of many devices that are also available in IDE form to cost at least 15% more (and sometimes much more). Similarly, at about $100, a USB floppy drive costs 10 times that of an ordinary one.

The media prices are the lowest commonly available when the media is purchased in large quantities (e.g., 50-100 for CDs) and in no-frills packaging (e.g., on a spindle for CDs rather than in individual jewel cases). All prices are domestic prices in the United States, in U.S. dollars, as of mid-2002.

The minimum lifetime column gives an approximate rule-of-thumb time period when you can expect some media to begin failing. Of course, individual media will fail even sooner in some cases.

Table 11-1. Popular backup devices and media

Type

Media capacity

Drive price[12]

Media price[12]

Minimum lifetime

Floppy disk

1.44 MB[13]

$10

$0.25

2 years

Super disk

120 MB

$120

$8

2-3 years

Zip Disk

100 MB

$70

$5

3-5 years

250 MB

$140

$12

3-5 years

Jaz Disk

1 GB

$300

$80

4-5 years

2 GB

$340

$100

4-5 years

CD-R

700 MB (80 minutes)

$150

$0.85

5 years

CD-RW

640 MB (74 minutes)

$150

$1

5 years

DVD-R

4.7 GB (single-sided)

$700

$8

5 years?

9.4 GB (double-sided)

$700

$40

5 years?

DVD+RW

4.7 GB

$600

$8

5 years?

DAT tape 4 mm DDS

4 GB (120 m DDS-2)

$550

$6

3-4 years

12 GB (125 m DDS-3)

$700

$12.50

3-4 years

20 GB (150 m DDS-4)

$1200

$26

3-4 years

8 mm tape

7 GB (160 m)

$1200

$6

2-4 years

Mammoth-2 (AME)

20 GB

$2500

$36

3-4 years?

60 GB

$3700

$45

3-4 years?

AIT tape

35 GB

$900

$79

3-4 years?

50 GB

$2600

$85

3-4 years?

100 GB

$3900

$105

3-4 years?

DLT

40 GB

$4000

$70

10 years

SuperDLT

110 GB

$6000

$150

10 years

Magneto-optical (RW)

5.2 GB

$2300

$65

15 years?

9.1 GB

$2700

$93

15 years?

Hard disk

100 GB (IDE)

N/A

$2-3/GB

5-7 years

180 GB (SCSI)

N/A

$10/GB

5-7 years

[12] Approximate minimum price in U.S. dollars.

[13] A few floppy drives provided by Unix vendors increase the maximum capacity to 2.8 MB .

11.2.10 Tape Special Files

Traditionally, special files used to access tape drives had names of the form /dev/rmtn or /dev/rmt/n, where n indicates the drive number. Tape drives are virtually always accessed via the character (raw) special file. Currently, special file names usually include other characters as prefixes and/or suffixes, which indicate the way the device is to be accessed: the density setting to use, whether to use the drive's built-in hardware compression, whether to rewind the tape after the operation is completed, and so on.

AIX systems also use suffixes to select whether the tape should beretensioned before use. Retensioning refers to equalizing the tension on a tape, and it consists of moving the tape to the beginning, then the end, and then rewinding back to the beginning; it's even slower than it sounds. The idea is to eliminate any latent slackness in the tape, but it is seldom necessary in practice.

Table 11-2 lists the current tape special file naming conventions for the various operating systems we are considering.

Table 11-2. Tape special file names

Unix version

Format and examples[14]

Prefixes/suffixes

man page

AIX

/dev/rmt n[.m]

/dev/rmt0.1/dev/rmt0.5

Note: Compression is enabled and disabled with the chdev command.

m:

none=rewind, no retension, low density1=no
rewind, no retension, low density2=rewind,
retension, low density3=no rewind, retension,
low density4=rewind, no retension, high
density5=no rewind, no retension, high
density6=rewind, retension, high
density7=no rewind, retension, high density

rmt(4)

FreeBSD

/dev/[n]rast n/dev/[e|n]rsa n

/dev/nrast0 /dev/nrsa0

n=no rewinde=eject tape on close

(Density and compression are chosen with the mt utility.)

astsa(4)

HP-UX

/dev/rmt/c i t j d0 TYPE[b][n]

/dev/c0t3d0DDSbn/dev/c0t3d0BESTbn

i=controllerj=SCSI IDn=no rewindb=use BSD-style error controlTYPE=keyword indicating tape type and/or density (e.g., BEST, DDS)

mt(7)

Linux

/dev/[n]stnx

/dev/nst0/dev/nst0m

n=no rewind

x:

none=default densityl=low
densitym=medium
densitya=autoselect density

st

Solaris

/dev/rmt/nx[b][n]

/dev/rmt/0lbn/dev/rmt/0hbn

b=use BSD-style error controln=no rewind

x:

none=default densityl=low
densitym=medium
densityh=high densityc=use
hardware compression

st

Tru64[15]

/dev/[n]rmt/tapen_dm

/dev/nrmt/tape0_d2/dev/nrmt/tape0_d3

m:

0=low density, use
compression1=high density, use
compression2=low density, no
compression3=high density, no compression(values
4-7 are also defined for some drives)

tz

[14] In all cases, n refers to the tape drive number. The examples are all for a non-rewinding tape device with hardware compression disabled using the lowest and highest density (as available).

[15] Older Tru64 systems use the now-obsolete device names of the form /dev/tz* and /dev/ta*.

Some systems provide simpler names as links to commonly-used tape devices. You can figure out which device they refer to by looking at a long directory listing. Here is an example from an HP-UX system:

crw-rw-rw- 2 bin bin 205 0x003000 Oct 7 1999 0m
crw-rw-rw-  2 bin    bin    205 0x003080 Oct  7  1999 0mb
crw-rw-rw-  2 bin    bin    205 0x003040 Oct  7  1999 0mn
crw-rw-rw-  2 bin    bin    205 0x0030c0 Oct  7  1999 0mnb
crw-rw-rw-  2 bin    bin    205 0x003000 Oct  7  1999 c0t3d0BEST
crw-rw-rw-  2 bin    bin    205 0x003080 Oct  7  1999 c0t3d0BESTb
crw-rw-rw-  2 bin    bin    205 0x003040 Oct  7  1999 c0t3d0BESTn
crw-rw-rw-  2 bin    bin    205 0x0030c0 Oct  7  1999 c0t3d0BESTnb
crw-rw-rw-  1 bin    bin    205 0x003001 Oct  7  1999 c0t3d0DDS
crw-rw-rw-  1 bin    bin    205 0x003081 Oct  7  1999 c0t3d0DDSb
crw-rw-rw-  1 bin    bin    205 0x003041 Oct  7  1999 c0t3d0DDSn
crw-rw-rw-  1 bin    bin    205 0x0030c1 Oct  7  1999 c0t3d0DDSnb

In this case, 0m and c0t3d0BEST refer to the same tape drive and access mode (as do their corresponding suffixed forms).

The default tape drive on a system is usually the first drive in its default (rewinding) mode:

AIX
/dev/rmt0
FreeBSD
/dev/rsa0
HP-UX
/dev/rmt/0m
Linux
/dev/st0
Solaris
/dev/rmt/0
Tru64
/dev/rmt/tape0_d0

On Linux systems (and some others), the device /dev/tape is a link to the default tape device on the system. You can make the link point to whatever drive you want to by recreating the link. On FreeBSD systems, some commands use the TAPE environment variable to locate the default tape drive.

11.2.10.1 AIX tape device attributes

On AIX systems, you can use the lsattr command to view the attributes of a tape drive:

$ lsattr -E -H -l rmt0
attribute      value  description                    user_settable

block_size     1024   BLOCK size (0=variable length)     True
compress       yes    Use data COMPRESSION               True
density_set_1  140    DENSITY setting #1                 True
density_set_2  20     DENSITY setting #2                 True
extfm          yes    Use EXTENDED file marks            True
mode           yes    Use DEVICE BUFFERS during writes   True

This 8 mm tape drive will use data compression and a block size of 1024 by default.

You must use the chdev command to change the many attributes of a tape drive (rather than having these selections encoded into the special file name as with other systems). For example, the following command changes the block size to 1024 and turns off compression and retensioning for drive 1:

# chdev -l rmt0 -a block_size=1024 -a compress=no -a ret=no


11.3 Backing Up Files and Filesystems

Most systems offer a variety of utilities for performing backups, ranging from general-purpose archiving programs like tar and cpio to programs designed for implementing multilevel incremental backup schemes on a per-filesystem basis. When the largest tapes held only a couple hundred megabytes, choosing the right utility for system backups was easy. tar and cpio were used for small and ad hoc backups and other data transfer needs, and the more sophisticated utilities specifically designed for the task were used for system backups, because their specialized abilities—the ability to span tapes and to automatically perform incremental backups—were essential to getting the job done.

This distinction breaks down to a great extent when a single tape can hold gigabytes of data. For example, incrementals are less important when you can fit all the important data on a system onto one or two tapes—and you have the time to do so. Large tapes also make it practical to back up a system in logically grouped chunks of files, which may be spread arbitrarily throughout the physical filesystem. A successful system backup process can be built around whatever utilities make sense for your system.

One dubious piece of advice about backups that is frequently given is that you should limit filesystem size to the maximum backup media capacity available on the system. In this view, multi-tape backup sets are simply too much trouble, and the backup process is simplified if all of the data from a filesystem will fit onto a single tape.

While being able to back up a filesystem with a single tape is certainly convenient, I think it is a mistake to let current media capacity dictate filesystem planning to such a degree. Breaking disks into more, smaller filesystems limits flexibility in allocating their resources, a concern that is almost always far more important than reducing the complexity of backing them up. Designing the filesystem needs to take all of the factors affecting the system and its efficient use into account. If tape-sized backup sets are what is desired, it's easy enough to write scripts to do so when overall circumstances dictate that some individual filesystems need to be bigger.

11.3.1 When tar or cpio Is Enough

In some cases, especially single-user systems, an elaborate backup process is not needed. Rather, since the administrator and the user are one and the same person, it will be obvious which files are important, how often they change, and so on. In cases like this, the simpler tape commands, tar and cpio, may be sufficient to periodically save important files to tape (or other media).

While the canonical model for this situation is Unix running on a workstation, these utilities may also be sufficient for systems with relatively small amounts of critical data. tar and cpio also have the advantage that they will back up both local and remote filesystems mounted via NFS.

11.3.1.1 The tar command

We'll begin with a simple example. The following tar command saves all files under /home to the default tape drive:

$ tar -c /home

-c says to create a backup archive.

tar's -C option (big C) is useful for gathering files from various parts of the filesystem into a single archive. This option causes the current directory to be set to the location specified as its argument before tar processes any subsequent pathname arguments. Multiple -C options may be used on the same command. For example, the following tar commands save all the files under the directories /home, /home2, and /chem/public:

$ tar -cf /dev/rmt1 /home /home2 /chem/public
$ tar -cf /dev/rmt1 -C /home . -C /home2 . -C /chem public

The two commands differ in this respect: the first command saves all of the files using absolute pathnames: /home/chavez/.login, for example. The second command saves files using relative pathnames: ./chavez/.login. The file from the first archive would always be restored to the same filesystem location, while the file from the second archive would be restored relative to the current directory (in other words, relative to the directory from which the restore command was given).

It is a good idea to use absolute pathnames in the arguments to -C. Relative pathnames specified to -C are interpreted with respect to the current directory at the time that option is processed rather than with respect to the initial current directory from which the tar command was issued. In other words, successive -C options accumulate, and tar commands using several of them as well as relative pathnames can become virtually uninterpretable.

Traditionally, all tar options were placed in a single group immediately following the command verb, and a preceding hyphen was not needed. The POSIX standard specifies a more traditional Unix syntax, preferring the second form to the first one for this command:

$ tar xpfb /dev/rmt1 1024 ...
$ tar -x -p -f /dev/rmt1 -b 1024 ...

The versions of tar on current operating systems usually accept both formats, but an initial hyphen may become be a requirement at some point in the future.

tar archives are often compressed, so it is very common to see compressed tar archives with names like file.tar.Z, file.tar.gz or file.tgz (the latter two files are compressed with the GNU gzip utility).

11.3.1.1.1 Solaris enhancements to the tar command

The Solaris version of tar offers enhancements that make the command more suitable for system-level backups. They allow all or part of the list of files and directories to be backed up to be placed in one or more text files (with one item per line). These files are included in the file list given to tar, preceded by -I, as in this example:

$  tar cvfX /dev/rst0 Dont_Save /home -I Other_User_Files -I Misc

This command backs up the files and directories in the two include files, as well as those in /home. The command also illustrates the use of the -X option, which specifies the name of an exclusion file listing the names of files and directories that should be skipped if encountered by tar. Note that wildcards are not permitted in either include or exclusion files. In case of conflicts, exclusion takes precedence over inclusion.

NOTE

The -I and -X options may also be used in restore operations performed with the tar command.

On Solaris and a variety of other System V systems, the file /etc/default/tar may be used to customize the mappings of the default archive destinations specified with tar's single-digit code characters (for example, the command tar 1c creates an archive on drive 1). Here is a version from a Solaris system:

#                               Block   #
#Archive=Device                 Size    Blocks
#
archive0=/dev/rmt/0             20      0
archive1=/dev/rmt/0n            20      0
archive2=/dev/rmt/1             20      0
archive3=/dev/rmt/1n            20      0
archive4=/dev/rmt/0             126     0
archive5=/dev/rmt/0n            126     0
archive6=/dev/rmt/1             126     0
archive7=/dev/rmt/1n            126     0

The first entry specifies the device that will be used when tar 0 is specified. In this case, it is the first tape drive in its default modes. The second entry defines archive 1 as the first tape drive in non-rewinding mode. The remaining two fields are optional; they specify the block size for the device and its total capacity (which may be set to zero to have the command simply detect the end-of-media marker).

11.3.1.1.2 The GNU tar utility: Linux and FreeBSD

Linux distributions and FreeBSD provide the GNU version of the tar command. It supports tar's customary features and contains some enhancements to them, including the ability to optionally span media volumes (-M) and to use gzip compression (-z). For example, the following command will extract the contents of the specified compressed tar archive:

$ tar xfz funsoftware.tgz
11.3.1.2 The cpio command

cpio can also be used to make backups. It has several advantages:

  • It is designed to easily back up completely arbitrary sets of files; tar is easiest to use with directory subtrees.

  • It packs data on tape much more efficiently than tar. If fitting all your data on one tape is an issue, cpio may be preferable.

  • On restores, it skips over bad spots on the tape, while tar just dies.

  • It can span tapes, while many versions of tar are limited to a single volume.

Using its -o option, cpio copies the files whose pathnames are passed to it via standard input (often by ls or find) to standard output; you redirect standard output to use cpio to write to floppy disk or tape. The following examples illustrate some typical backup uses of cpio:

$ find /home -print | cpio -o >/dev/rmt0
$ find /home -cpio /dev/rmt0

The first command copies all files in /home and its subdirectories to the tape in drive 0. The second command performs the identical backup via a version of find that offers a -cpio option.

11.3.1.3 Incremental backups with tar and cpio

Combining find with tar or cpio is one easy way to perform incremental backups, especially when only two or three distinct backup levels are needed. For example, the following commands both copy all files under /home which have been modified today into an archive on /dev/rmt1, excluding any object (.o) files:

$ find /home -mtime -1 ! -name \*.o -print | cpio -o >/dev/rmt1
$ tar c1 `find /home -mtime -1 ! -name `*.o' ! -type d -print`

The find command used with tar needs to exclude directories, because tar will automatically archive every file underneath any directory named in the file list, and all directories in which any file has changed will appear in the output from find.

You can also use find's -newer option to perform an incremental backup in this way:

$ touch /backup/home_full
$ find /home -print | cpio -o > /dev/rmt0
A day later . . .
$ touch /backup/home_incr_1
$ find /home -newer /backup/home_full -print | cpio -o > /dev/rmt0

The first command timestamps the file /backup/home_full using the touch command (/backup is a directory created for such backup time records), and the second command performs a full backup of /home. Some time later, the second two commands could be used to archive all files that whose data has changed since the first backup and to record when it began. Timestamping the record files before this backup begins ensures that any files that are modified while it is being written will be backed up during a subsequent incremental, regardless of whether such files have been included in the current backup or not.

11.3.1.4 pax: Detente between tar and cpio

The pax command attempts to bridge the gap between tar and cpio by providing a single general-purpose archiving utility.[16] It can read and write archives in either format (by default, it writes tar archives), and offers enhancements over both of them, making it an excellent utility for system backups in many environments. pax is available for all of the Unix versions we are considering. Like cpio, pax archives may span multiple media volumes.

[16] Indeed, on systems offering pax, cpio and tar are often just links to it. pax's syntax is an amalgamation of the two, which is not surprising for a peace imposed by POSIX (although the name purportedly stands for portable archive exchange).

pax's general syntax is:

pax [mode_option] other_options files_to_backup

The mode_option indicates whether files are being written to or extracted from an archive, where -w says to write to an archive, -r says to read and extract from an archive, and -rw indicates a pass-through mode in which files are copied to an alternate directory on disk (as with cpio -p); pax's default mode when no mode_option is given is to list the contents of an archive.

The following commands illustrate pax file archiving modes of operation:

$ pax -w -f /dev/rmt0 /home /chem
$ find /home /chem -mtime -1 -print | pax -w -f /dev/rmt0
$ pax -w -X -f /dev/rmt0 /

The first two commands perform a full and incremental backup of the files in /home and /chem to the default tape drive in each case. The third command saves all of the files in the disk partition corresponding to the root directory; the -X option tells pax not to cross filesystem boundaries.

AIX prefers pax over vanilla tar and cpio. The command has been enhanced to support large files (over 2 GB).

Getting Users to Do Backups

At some sites, certain backup responsibilities are left to individual users: when a site has far too many workstations to make backing up all of their local disks practical, when important data resides on non-Unix systems like PCs (especially if they are not connected to the local area network), and so on.

However, even when you're not actually performing the backups yourself, you will probably still be responsible for providing technical support and, more often than not, reminders to the users who will be performing the backups. Here are some approaches I've tried to facilitate this:

  • Make a habit of encouraging users rather than threatening them (threats don't work anyway).

  • Use peer pressure to your advantage. Setting up a central backup storage location that you look after can make it obvious who is and isn't doing the backups they are supposed to. Note that this idea is inappropriate if data sensitivity is an issue.

  • Create tools that automate the backup process as much as possible for users. Everyone has time to drop in a tape and start a script before they leave for the day.

  • Provide a central repository for key files that get backed up as part of the system/site procedure. Users can copy key files and know they will be backed up when they're really in a jam and really don't have time to do a backup themselves.

11.3.2 Backing Up Individual Filesystems with dump

The BSD dump utility represents the next level of sophistication forbackup systems under Unix. It selectively backs up all of the files within a filesystem (single disk partition), doing so by copying the data corresponding to each inode to the archive on the backup device. It also has the advantage of being able to back up any type of file, including device special files and sparse files. Although there are slight variations among different versions of this command, the discussion here applies to the following Unix implementations of this command:

AIX
backup
FreeBSD
dump
HP-UX
dump and vxdump
Linux
dump (but the package is not usually installed by default)
Solaris
ufsdump
Tru64
dump and vdump

On systems supporting multiple filesystem types, dump may be limited to UFS (BSD-type) filesystems; on Linux systems, it is currently limited to ext2/ext3 filesystems, although the XFS filesystem provides the similar xfsdump utility. Under HP-UX, vxdump and vxrestore support VxFS filesystems. Tru64 provides vdump for AdvFS filesystems.

dump keeps track of when it last backed up each filesystem and the level at which it was saved. This information is stored in the file /etc/dumpdates (except on HP-UX systems, which use /var/adm/dumpdates). A typical entry in this file looks like this:

/dev/disk2e       2 Sun Feb  5 13:14:56 1995

This entry indicates that the filesystem /dev/disk2e was last backed up on Sunday, February 5 during a level 2 backup. If dump does not find a filesystem in this list, it assumes that it has never been backed up.

If dumpdates doesn't exist, the following command will create it:

# touch /path/dumpdates

The dumpdates file must be owned by the user root. If it does not exist, dump will not create it and won't record when filesystem backups occur, so create the file before running dump for the first time.

The dump command takes two general forms:

$ dump options-with-arguments  filesystem

$ dump option-letters corresponding-arguments filesystem

where filesystem is the block special file corresponding to the filesystem to be backed up or the corresponding mount point from the filesystem configuration file. In the first, newer form, the first item is the list of options to be used for this backup, with their arguments immediately following the option letters in the normal way (e.g., -f /dev/tape).

In the second, older form, option-letters is a list of argument letters corresponding to the desired options, and corresponding-arguments are the values associated with each argument, in the same order. This syntax is still the only one available under Solaris and HP-UX.

Although not all options require arguments, the list of arguments must correspond exactly, in order and in number, to the options requiring arguments. For example, consider the set of options 0sd. The s and d options require arguments; 0 does not. Thus, a dump command specifying these options must have the form:

$ dump 0sd s-argument d-argument filesystem

Failing to observe this rule can have painful consequences if you are running the command as root, including destroying the filesystem if you swap the argument to the f option and dump's final argument when you are running the command as root. You'll get no argument from me if you want to assert that this is a design defect that ought to have been fixed long before now. When you use dump, just make sure an argument is supplied for each option requiring one. To avoid operator errors, you may want to create shell scripts that automatically invoke dump with the proper options.

dump's most important options are the following (we will use the newer form):

-0, . . . , -9

These options indicate the level of the dump this command will perform. Given any level n, dump will search dumpdates for an entry reporting the last time this filesystem was dumped at level n-1 or lower. dump then backs up all files that have been changed since this date. If n is zero, dump will back up the entire filesystem. If there is no record of a backup for this filesystem for level n-1 or lower, dump will also back up the entire filesystem. If no level option is specified, it defaults to -9. This option does not require any argument.

Older versions of dump not supporting hyphenated options require that the level option be the first option letter.

-u

If dump finishes successfully, this option updates its history file, dumpdates. It does not require an argument.

-f device

This option states that you want to send the dump to something other than the default tape drive (i.e., to a file or to another device). The defaults used by various Unix versions were listed previously. If you use this option, it must have an argument, and this argument must precede the filesystem being dumped. A value of "-" (a single hyphen) for its argument indicates standard output.

-W

Display only what will be backed up when the indicated command is invoked, but don't perform the actual backup operation.

-s feet -d dens

These options were needed on older versions of dump to determine the capacity of the backup media. Recent versions of dump generally don't need them as they keep writing until they detect an end-of-media mark.

If you do need to use them to lie to dump about the tape length because your version uses a default capacity limit suitable for ancient 9-track tapes, -s specifies the size of the backup tape, in feet; -d specifies the density of the backup tape, in bits per inch. Since dump will respect end-of-media marks that it encounters before it has reached this limit, the fix for such situations is to set the capacity to something far above the actual limit. For example, the options -d 50000 -s 90000 define a tape capacity somewhat over 4 GB.

-b factor

Specifies the block size to use on the tape, in units of 1024-byte (or sometimes 512-byte) blocks.

Here is a typical use of the dump command:

$ dump -1 -u -f /dev/tape /chem

The second command performs a level 1 incremental backup on the /chem filesystem using the tape drive linked to /dev/tape; dump will update the file the dumpdates file upon completion.

dump notifies the user whenever it requires some interaction. Most often, dump will have filled the tape currently in use and ask for another. It will also ask whether to take corrective actions if problems arise. In addition, dump prints many messages describing what it is doing, how many tapes it thinks it will need, and the like.

11.3.2.1 The HP-UX fbackup utility

HP-UX provides the fbackup and frecover utilities designed to perform system backups. One significant advantage that they have over the standard Unix utilities is that they can save and restore HP-UX access control lists along with other file metadata.

fbackup provides for nine levels of incremental backups, just like dump. fbackup stores backup records in the file /var/adm/fbackupfiles/dates, which the system administrator must create before using fbackup.

The following examples illustrate how fbackup might be used for system backup operations:

# fbackup -0u -f /dev/rmt/1m -i /chem
# fbackup -1u -i /chem -i /bio -e /bio/med
# fbackup -1u -f /dev/rmt/0m -f /dev/rmt/1m -i /chem
# fbackup -0u -g /backup/chemists.graph -I /backup/chemists.TOC

The first command performs a full backup of /chem to tape drive 1, updating the fbackup database. The second command does a level 1 backup of /chem and /bio, excluding the directory /bio/med (as many -i and -e options as you need can be included). The third command performs a level 1 backup of /chem using multiple tape drives in sequence.

The final command performs a full backup as specified by the graph file /backup/chemists.graph, writing an index of the backup to the file /backup/chemists.TOC. A graph file is a text file with the following format:

c   path

where c is a code indicating whether path is to be included (i) or excluded (e) from the backup.

11.3.3 Related Tape Utilities

There are two other Unixtape utilities you should know about, which are also of use in performing backups from time to time.

11.3.3.1 Data copying and conversion with dd

The dd utility transfers raw data between devices. It is useful for converting data between systems and for reading and writing tapes from and to non-Unix systems. It takes a number of option=value pairs as its arguments. Some of the most useful options are:

if

Input file: source for data.

of

Output file: destination for data.

ibs

Input block size, in bytes (the default is 512).

obs

Output block size, in bytes (the default is 512).

fskip

Skip tape files before transferring data (not available in all implementations).

count

The amount of data (number of blocks) to transfer.

conv

Keyword(s) specifying desired conversion of input data before outputting: swab means swap bytes, and it is the most used conversion type. lcase and ucase mean convert to lower- and uppercase, respectively, and ascii and ebcdic mean convert to ASCII or EBCDIC.

For example, the following command processes the third file on the tape in drive 0, using an input block size of 1024 bytes and swapping bytes in all data; the command writes the converted output to the file /chem/data/c70o.dat:

$ dd if=/dev/rmt0 of=/chem/data/c70o.dat \
     ibs=1024 fskip=2 conv=swab

As always, be careful to specify the appropriate devices for if and of; transposing them can have disastrous consequences.

11.3.3.2 Tape manipulation with mt

Unix provides the mt command for direct manipulation of tapes. It can be used to position tapes (to skip past backup save sets, for example), to rewind tapes, and to perform other basic tape operations. Its syntax is:

$ mt [-f tape-device] command

where tape-device specifies which tape drive to use, and command is a keyword indicating the desired action. Useful keywords include rewind (to rewind the tape), status (display device status—you can see whether it is in use, for example), fsf n (skip the next n files), and bsf n (skip back n files).

For example, to rewind the tape in the second tape drive, you might use a command like:

$ mt -f /dev/rmt1 rewind

The Solaris version of mt includes an asf subcommand, which moves the tape to the nth file on the tape (where n is given as asf's argument), regardless of the tape's current position.

Under FreeBSD, the mt command is used to set the tape drive density and compression:

$ mt -f /dev/nrsa0 comp on density 0x26

AIX also includes the tctl utility (to which mt is really a link). tctl has the same syntax as mt and offers a few additional seldom-wanted subcommands.