How to rebuild an initrd

To start off with, what’s an initrd? This is the initial ram disk that the system sets up to boot from. It has the Linux kernel in it, a basic set of modules and a few other things. After so long in the boot process the system gets switched over to the main partitions and then boots up the rest of the way.

How do we know we have a problem? That’s fairly simple. If we have a system that gives an error pertaining to a “switchroot” and panics we can scroll up and see if the drivers aren’t there. In the most recent case I had to deal with, it was due to there not being any 3ware modules. I have seen this happen in the past with drives moved between systems as well with radically different chipsets (think AMD versus Intel chipsets.)

Switchroot errors can happen due to a ton of reasons, these include the FS not being in existance, files missing from the FS or the modules not being loaded for the hardware in question. Use your head when you get them, but if you seem to have the above problem the solution is pretty simple.

All you have to do is run the /sbin/mkinitrd command. This is as simple as doing something along the lines of:

/sbin/mkinitrd initrd-2.6.18-194.el5PAE.img -v 2.6.18-194.el5PAE

Provided there isn’t a file with that name in the FS, a few moments later you will have a fresh initrd with whatever modules are loaded on the system at the time provided the kernel you are using has them available to it. Pretty cool huh? I will get more in depth with initrd at a later date, you can even hack them to make your own mini OS with.

Pipin ain’t easy (unless you read this guide)

I have gone over more than a few Linux based commands at this point, so I want to introduce a new way of using them; Pipes. Pipes are really cool because they will let you take the command and put its output into another command. There are a nearly infinite amount of ways to use them as well. Enough with the introductions, lets get on to the commands. Lets say that I want to determine the number of connections currently open at the moment on port 80. We can do the command

netstat -anp

And it will give us a distinct number of entries. We are left looking for traffic that is on port 80, and we have a bunch of lines we don’t care to bother with quite frankly. This is where the pipe comes in.

netstat -anp | grep :80

This will show any traffic that is to port 80, or any traffic that is going to port 80 on a remote server. Lets say we have a huge amount of traffic though, and want to just get a count. If you have a high use server counting by hand is a nuisance at best and virtually impossible at worse. At this point we would just throw the results of our grep into another pipe like this:

netstat -anp | grep :80 | wc -l

And then we have a raw number of accounts used on port 80. Pretty neat. Because pipes are an infinitely versatile tool we can use them for dealing with static files or dealing with the server in real time using utilities like tail. Want to know more about tail? Check out my next blog, I’m going to show some of the tricks on server side troubleshooting.

Some SED basics

One of my favorite tools for Sysadmin work is the Stream EDitor utility or just SED. SED is useful for many things, and is a stepping stone along the way to making variable based shell scripts as well. Don’t want to have to edit the nameservers on a million zone files? SED it. Need to do certain things to a million files at once? SED it. In conjunction with cat, find, and grep SED is devastatingly effective in finding and eliminating administrator headaches. Lets start out with something extremely basic.

sed -i ‘s/ns1.domain1.com/ns1.domain.com/’ /var/named/*.db

What does this do? It goes through and changes the instances of ns1.domain1.com to ns1.domain.com in DNS zone files. Please note I advise grepping any thing out that you are changing because if there are multiple instances of this in the file it will only do the first instance.  If you have this issue, you can always repeat the command and check again until all instances are found. the s indicates a spelling correction, the -i puts it back into the original file. If we just wanted to print to the TTY we would use the -e augment.

Well, that’s pretty cool, but what about some other situations that come up? Lets say we’re migrating a cpanel box. There are a ton of scripts out there, but we have some special needs. Say we want to run it with –skip-homedir because this is going to be a pseudo-manual migration and we’ll sync the homedir over later. All we have to do is make a copy of /etc/users and then do the following:

sed -i 's/$/\/scripts\/pkgacct /' users

sed -i 's/^/  \-\-skip\-homedir\' users

chmod +x users

./users

Yes this is a few commands, but we want to progressively look over what’s happening here. The $ means that /scripts/pkgacct is prepended to the beginning of each line. Notice that there is a space at the end of the command so that the user name doesn’t become part of the command we are trying to run and error out. Also notice the \es. These are an escape character that is used in order to allow the use of a special character such as /  – . or other characters that may otherwise be taken as part of the command. The second line is similar to the first in the fact that it will add to every line in a file as well as the use of escape characters, however ^ will add to the end of every line. The last thing we are doing is making our script executeable with the +x command (you can chmod 755 if you want and get similar results) and then runs it. If we were smart we would probably put a she-bang at the top (#!/bin/bash) so that it is run with BASH.

Our input file would look like this:

user1

user2

user3

user4

and the output would look like

/scripts/pkgacct user1 --skip-homedir

/scripts/pkgacct user2 --skip-homedir

/scripts/pkgacct user3 --skip-homedir

/scripts/pkgacct user4 --skip-homedir

There are a ton of uses for this, I love cleaning spam in Exim’s mail queue with this if you’re not allowed to BOFH the system and delete the “clean” email with the spam as well. That will be a later episode however.

Linux Daily Tip – Bulk Delete Files By Name

Ever find yourself tediously removing files by hand, across a large, complex directory structure? Luckily, there’s a simply, easy way to delete files, as long as they have a part of their name in common.

For example, to delete all PDF files in this directory, recursively, run

find . -name "*.pdf" -exec rm -f {} \;

Linux Daily Tip – Concatenate

A extremely useful tool for outputting the contents of a file is “Cat” short for Concatenate.  Cat will print the standard output onto the screen.

A useful example:

cat -n  -s /proc/cpuinfo | more

Options: -n will number the lines outputted while -s will suppress excess empty lines.

Its also useful to pipe the output into more to make it easier to read.

Want to learn more about pipe? Checkout Alex’s article here.