Linux System Administration

by Mark Komarinski

When you installed Linux for the first time, you made at least one filesystem to store Linux on. If you're like me at all, you quickly decided you needed more drive space. Now the problem is, how the heck do you create the new filesystems, and how do you copy the files over? This month's article will help you do that. I'm also going to go into describing the /etc/inittab file, a rather important file that gets loaded when you boot your system. When making a filesystem for expanding your system space, there are a few things you have to consider. Where do you want your new fielsystem located? Making a larger /usr directory may be what you need, but expanding your /usr/X386 directory may be a better idea. Remember that not all filesystems have to come off the / (root) directory. You can mount any directory to any filesystem, but don't put any of the following on a different filesystem other than /: /etc /dev /lib /sbin /bin /conf. Each of these directories are needed during boot-up, and other filesystems are mounted *after* Linux has booted. This could make booting up Linux a difficult or impossible task. Let's assume that you want to make your user partitions bigger, and that you have your user's home directories in the /user directory, currently on the / (root) partition. Here's what you do. NOTES: IDE drives are /dev/hda and /dev/hdb. SCSI drives use /dev/sda through /dev/sde. Your particular setup may look different than my sample setup. Please read all the instructions and be sure you understand what is going on before you start!! If you are confused, look at the manual pages for the commands that I reference. They are a great help.

Make the partition you want to use.

Go into fdisk (`fdisk' followed by the drive name—/dev/hda, /dev/hdb, etc). Make a new partition by using the n command. You will now be asked for a partition type (extended, primary, or logical). Answer with the partition type you want to use. Now, you have to give a starting cylinder. For simplicity, just type in the first number you see in the list. After this, you must now type in the size of the partitions in 1K blocks. You can also type in a number followed by M to specify that the number is 1Meg blocks. So an answer of 30M would make a 30Meg partition. Your new partition should now be set up. Type p to list your partitions and write down the block size of the partition you just created. You'll need this in your next step. Quit fdisk (with the w command), and you may want to reboot your machine at this time to make sure that the partitions are read correctly. In my setup, I have a new drive I just installed, and I'm going to make a logical partition on my second hard drive (/dev/hdb):

#fdisk /dev/hdb
Command (m for help): n
First cylinder (205-731): 205
Last cylinder or +size or +sizeM or +sizeK (205-731): +30M
Warning: partition 5 has an odd number of sectors.
Command (m for help): w
The partition table has been altered!
Calling BLKRRPART ioctl() to reread partition table
Syncing disks
Reboot your system to ensure partition table is updated
#
Make the filesystem

The command to make a Second Extended Filesystem is mke2fs. I'm using EXT2FS (as it is commonly called) because it provides a lot of features now, plus has the ability for future support built in. For example, it supports a clean bit where if you unmount a filesystem successfully, you won't get bugged later on to do a filesystem check. It makes booting up Linux much faster. There is also the ability to support a compressed filesystem, where files are automatically compressed. This is not coded into the filesystem yet, but when the kernel supports it, you'll have a compressed filesystem. But back to making your filesystem. Type the command: mke2fs -c <partition> <size in blocks> where <partition> is the hard drive partition you wish to format and <blocks> is the number of 1K blocks that you wrote down in the previous step. The -c tells mke2fs to automatically check for bad blocks. This will help avoid surprises when the hard drive tries writing to a bad block later on.

In my case:

#mke2fs -c /dev/hdb5 31019
{Various data about number of inodes, number of blocks, etc} #
Make a copy of partition you want to move

The best way to do this is to use the tar (tape archive) command. A tar file will store important information like file ownership, permissions, and file dates that a copy command would lose. Find out the size of the files you're copying with the du -s <directory> command, where <directory> is the directory you want to move to the new partition. The -s option will give a grand total of all the files and directories. I want disk usage of the /user directory, so df -s /user will tell me how much space the /user directory currently takes up:

#df -s /user
11906 #

As this number is in 1K blocks, I know that my /user direc-tory and all the user files under that take up just under 12Meg. Luckily, my root partition has 15Meg free (you can check your free space with the df command). Use the following command to make a tar file of your /user directory: tar -cvf <tar file> <directory>, where <tarfile> tells what you want to call the tar file and <directory> is the directory you want to tar up. For me, this would be:

#cd / #tar -cvf /user.tar /user user user/root user/root/.bashrc
{list of files} #

The c option tells tar you want to create a tar file, the v option tells tar to tell you what files it's adding to the tar file, and the f option tells tar that the next thing it sees is a file to create. Now, if you're in the root directory and type ls -la user.tar you should see something like:

#ls -la user.tar -rw-r-r-   1 root     root        12103680 Mar  1 01:41
user.tar #
Remove the old directory

Now for the fun part. Yes, you get to use the horrid, deadly, yet subtle, rm -r command. But be warned! Typing in this command wrong in any way has the potential to crash your system, or lose files you did not want to lose! Before you do this, make sure that your data is backed up somewhere! Make sure it is in either the tar file you just created, or create a second backup if you really want to make sure!

I'll do it step-by-step:

  1. Go into the directory you want to delete. For me, this is the /user directory, so I type:

    #cd /user #
    
  2. VERIFY that you are in the correct directory! Use the pwd command to tell you where you are. If you're not in the right directory, go back to step 1. My response should be:

    #pwd /user #
    
  3. If you still have qualms about using rm -r *, go into each of the directories, delete the files in the directories, and then remove the directories by hand. This is safer, yet takes more time. Delete files using the rm <file> command, and directories can be deleted using the rmdir <directory> command. The rm -rv command will delete everything in the current directory, plus all of the subdirectories of that directory. The `v' option will list everything that gets deleted as it happens, so you will know what is going on.

    #rm -rv * {list of files and subdirectories} #
    
Mount the new partition

Make sure that the directory that you want to mount exists. For example, if I want to mount a partition on /user, the /user directory has to exist. Now you get to mount the partition you created a few minutes ago, and make it a functional part of your system: mount -t ext2 <partition> <directory>, where <partition> is the partition you want to mount and <directory> is where you want to mount that partition off of. In my case, I'll use:

#mount -t ext2 /dev/hdb5 /user
#

If you change directory into your new directory, it looks just like it did before, only there is a new directory - lost+found. This directory is where e2fsck places blocks it has no idea about. This is similar to the files created by the DOS chkdsk command. However, as long as you shut your system down properly and you have few power outages or system crashes, you will probably never need to go into this directory.

Copy files into directory

Now we'll use the tar command as we did last time, only now we want to extract the files in user.tar. This will restore the files to their original appearance. They will have the same ownership, same file dates, and most importantly, the same data. Type:

cd / tar -xvf <tar file>

where <tar file> is the tape archive file from earlier in our procedure.

For me:

#cd / #tar -xvf user.tar user user/root user/root/.bashrc {list
        of files} #

And now you are back to the point you were at the beginning of this article, with the exception of a lot more user space. There is one more thing which must be done. That is to add your new filesystem to the boot files so that your new partition will automatically be mounted every time you boot Linux. This is an easy part. Go into the /etc directory, and edit the fstab file. At the end of the file, add a line of the form:

<partition> <mount point> <fstype> defaults

where <partition> is the hard drive partition, <mount point> is the directory you want to mount the partition to, and <fstype> is the filesystem type you are using. You may see other entries where the fstype is ext2, proc, or swap. These describe the EXT2FS (the filesystem we are using), the /proc filesystem which is used for system status information, and virtual memory or swap space.

The line that I have to add looks like:

/dev/hdb5  /user   ext2    defaults

Save the file, and the next time you boot Linux, the partition will be automatically mounted off of the /user partition.

Whew, that was fun, eh kids? Now on to a portion of your configuration files. I'll be going over most of the configuration files, and we'll start with one of the first programs that gets read - /etc/inittab.

You may have noticed a file running when you run ps aux called init or /etc/init. This is the parent of all other programms on your system, from the initialization files such as /etc/inetd, to the getty program that lets you log into the system, init starts it.

Since the parts of the inittab file change with the various versions of the /etc utilities, I'll show you some of the major parts of inittab. Any of the fine details can be found in the man pages for init and inittab.

First, init bases a lot on the runlevel. For example, one runlevel can be defined as a `safe boot' where only root can log in.

Another runlevel can set up your serial port to accept logins. You can set these run levels at boot time, you can manually enter a runlevel while booting, or can change the runlevel on the fly by using the /etc/telinit command.

An entry in the inittab file has four fields:

   rc:123456:wait:/etc/rc.M

Field 1 is a unique identifier, field 2 lists the runlevels that this command applies to, field 3 tells init what to do when running the program, and field 4 lists the program to run.

In your inittab file, you may see a line that has `initdefault' in the third field. The number on that line will specify what runlevel to use when booting. If that line is not in the inittab file, you will be prompted for a runlevel. Mine is set to `5', and my line looks like this:

   id:5:initdefault:

If the default runlevel is set to `S' or `s', Linux will go into a single-user mode, where /bin/sh is automatically started on the console.

The next thing that init looks for are entries that have type `boot' or `bootwait' associated with them. This allows files such as your /etc/rc files to be run so that all your partitions will be mounted before the first user logs in. The `boot' entry means to start that process and not wait for it to finish. The `bootwait' entries mean to run that program and wait until it finishes successfully before doing the next thing. I have none of these entries, as it allows me to have different /etc/rc files used.

Next, init looks for lines that have that particular runlevels listed. In the second field, you should have a list of the runlevels that a program can be started in. For example, I have a runlevel 6 which starts up X-Windows automatically, and my other 5 runlevels are currently unused. My entries for the configuration files looks like this:

rc:123456:wait:/etc/rc.d/rc.M x1:6:wait:/etc/rc.d/rc.6

Here, the /etc/rc.d/rc.M (M for multi-user) get started every time. But on runlevel 6, it will start up the extra programs necessary to start up X-Windows automatically. As you can see, the rc.M file will be executed on every runlevel except `S' (single user), since all the other runlevels are listed in the second field. The third field `wait' tells init to wait until that program is completed before going to the next init entry.

The next set of entries that are important are the ones that control getty, the program that monitors the console and serial ports for logins. Mine looks like this:

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

and a few other lines with the difference that the `tty1' is `tty2' and the `c1' is `c2'. The important part here is the third and fourth fields. The `respawn' entry tells init that if the program stops running, to start another one back up. This means that when you log out, init will automatically start another getty program so that you will get the login prompt again. Without the `respawn', after you log out, you won't be able to log back in on that Virtual Console.

There are a few other lines you may want to pay attention to if you want to connect a dumb terminal to your machine. These are two lines that are probably commented out by having a `#' at the beginning of the line:

   #s1:45:respawn:/sbin/agetty 9600 ttyS0 #s2:45:respawn:/sbin/agetty
        9600 ttyS1

If you uncomment a line and reboot (or use /etc/telinit) in runlevel 4 or 5, a getty process will get started on that particular serial port. Remember that ttyS0 relates to COM1 in DOS, ttyS1 relates to COM2, etc. After rebooting, you should see a `/sbin/agetty 9600 ttyS0' if you type in `ps aux', and you should get a login prompt if you connect a terminal or another PC to the serial port.

Load Disqus comments