Using Sort to List Directories by Size

If you manage a UNIX system with a large number of directories that vary in size, chances are that you’ve needed to figure out which ones are using up the most disk space. Of course if the directories are user accounts, the best way to do this is to enable quotas and use the “repquota” command. If you just have a bunch of directories, however, you can easily figure out which ones are largest by giving the correct arguments to “du” and “sort”. Here is how:

du -sk * | sort +0nr

This will display the size of all directories and sort them from largest to smallest. If you want to sort them from smallest to largest, simply remove the “r”.

du -sk * | sort +0n

If you have nested directories, you will need to incorporate foreach to recurse through and get all the directory names.

Taking Disk Cylinders From Swap on Solaris 8

Kids… DO NOT TRY THIS AT HOME! If this is not done exactly right, you will render your system unbootable and corrupt your data. That being said, under some circumstances you can take some space from your swap partition and add it to an unused one without initializing your entire disk. This is particularly useful if you decide you want to use DiskSuite to mirror your system disk, but have not allocated the 100MB partition that is needed to hold the state databases. As always, BACK EVERYTHING UP FIRST. Better yet, make two backups and store them on two different systems. This is a risky procedure, and you don’t want to lose any data!

You can also use my instructions for copying a Solaris boot drive to a disk with a different partition layout as a safer alternative.

The first thing you need to do is figure out if your disk layout will allow for this procedure. Usually the swap partition is the second one on the disk, making it partition number 1 (Partition number 0 is root). If partition number 1 is swap on your system, and partition number 3 or 4 are unused, you are in good shape, and this should work. To figure this out, you should do something like this:

# format
Select the boot disk – usually disk 0
Specify disk (enter its number): 0
format> partition
format> print

This will show you the current disk layout.


Current partition table (original):
Total disk cylinders available: 24620 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders         Size            Blocks
  0       root    wm       0 -   725        1.00GB    (726/0/0)    2097414
  1       swap    wu     726 -  9436       11.90GB    (8635/0/0)  24946515
  2     backup    wm       0 - 24619       33.92GB    (24620/0/0) 71127180
  3 unassigned    wm       0                0         (0/0/0)            0
  4 unassigned    wm       0                0         (0/0/0)            0
  5        usr    wm    9437 - 10888        2.00GB    (1452/0/0)   4194828
  6        var    wm   10889 - 18148       10.00GB    (7260/0/0)  20974140
  7 unassigned    wm   18149 - 24619        8.91GB    (6471/0/0)  18694719

Here we see that partitions 3 and 4 are unused and directly after partition 1, so we can take some space from swap and assign it to one of these. Partition 2 is, of course the entire disk. I have not tried it, so I don’t know if you could assign non-sequential cylinders to a partition that is not directly after swap.

So to take some space from partition 1 and add it to partition 3, the first thing we have to do is disable swap, so the format utility will let us change it.

Comment out the following lines in your /etc/vfstab file and reboot the system.


#/dev/dsk/c1t0d0s1         -       -               swap    -       no      -
#swap    -       /tmp    tmpfs   -       yes     - 

This will bring the system up without swap enabled. You can now edit the disk label. Remember that our cylinders need to be sequential, so always work in cylinders when using the format utility.

Re-enter the format utility, select your system disk and view the partition table:

# format
Select the boot disk – usually disk 0
Specify disk (enter its number): 0
format> partition
format> print

Again we wee that partitions 3 and 4 are unused.


Current partition table (original):
Total disk cylinders available: 24620 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders         Size            Blocks
  0       root    wm       0 -   725        1.00GB    (726/0/0)    2097414
  1       swap    wu     726 -  9436       11.90GB    (8635/0/0)  24946515
  2     backup    wm       0 - 24619       33.92GB    (24620/0/0) 71127180
  3 unassigned    wm       0                0         (0/0/0)            0
  4 unassigned    wm       0                0         (0/0/0)            0
  5        usr    wm    9437 - 10888        2.00GB    (1452/0/0)   4194828
  6        var    wm   10889 - 18148       10.00GB    (7260/0/0)  20974140
  7 unassigned    wm   18149 - 24619        8.91GB    (6471/0/0)  18694719

The first thing we need to do is take some cylinders away from partition 1. In this example, we are looking to make partition 3 roughly 100MB, so we need to take about 75 cylinders from partition 1 so that we can add it to partition 3. Parititon 1 ends at cylinder 9436, so we need to subtract 75 from that number. 9436 – 75 = 9361, so that is the new ending cylinder for partition 1. We then subtract the beginning cylinder (726) from that number to give us the new total number of cylinders for partition 1. 9361 – 726 = 8635, so this is the number we enter when format asks for the size of the partition. Like so:


partition> 1
Part      Tag    Flag     Cylinders         Size            Blocks
  1       swap    wu     726 -  9360       11.90GB    (8635/0/0)  24946515

Enter partition id tag[swap]: 
Enter partition permission flags[wu]: 
Enter new starting cyl[726]: 
Enter partition size[24946615b, 9436c, 12880.92mb, 12.00gb]: 8635c
partition>

Now we have to add these 75 cylinders to partition 3.


partition> 3
Part      Tag    Flag     Cylinders         Size            Blocks
  3 unassigned    wm       0                0          (0/0/0)            0

Enter partition id tag[unassigned]: 
Enter partition permission flags[wm]: 
Enter new starting cyl[0]:9361
Enter partition size[0b, 0c, 0.00mb, 0.00gb]:75c
partition>

Print out the new partition table to make sure everything lines up correctly:


partition> print
Current partition table (original):
Total disk cylinders available: 24620 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders         Size            Blocks
  0       root    wm       0 -   725        1.00GB    (726/0/0)    2097414
  1       swap    wu     726 -  9360       11.90GB    (8635/0/0)  24946515
  2     backup    wm       0 - 24619       33.92GB    (24620/0/0) 71127180
  3 unassigned    wm    9361 -  9436      107.21MB    (76/0/0)      219564
  4 unassigned    wm       0                0         (0/0/0)            0
  5        usr    wm    9437 - 10888        2.00GB    (1452/0/0)   4194828
  6        var    wm   10889 - 18148       10.00GB    (7260/0/0)  20974140
  7 unassigned    wm   18149 - 24619        8.91GB    (6471/0/0)  18694719

Partition 1 ends at cylinder 9360, and partition 3 picks right up at cylinder 9361. Partition 3 ends at cylinder 9436, and partition 5 begins at cylinder 9437. Partition 4, of course, remains unused. Since none of the cylinders overlap, we can go ahead and write the disk label out. DO NOT DO THIS if you have any doubt at all about what you have just done. By writing out the disk label, you could corrupt the data on your formated filesystems if any cylinders overlap into them. The format utility is usually pretty smart about keeping you from making mistakes, but be very careful anyway! You don’t want to end up with scrambled eggs on a disk that has valuable data on it.

partition> label
This writes out the disk label, so you can now exit the format utility and re-enable swap in your /etc/vfstab file. Simply uncomment out the following two lines and reboot the system.


/dev/dsk/c1t0d0s1         -       -               swap    -       no      -
swap    -       /tmp    tmpfs   -       yes     -

Reboot your system, and if all goes well, it will come up, and you will see that partition 3 will have a little over 100MB on it. Usually people want to do this so they can store the DiskSuite meta database on the newly created partition. If this is the case for you, you can now move on to mirroring the system disk.

Controlling Services With chkconfig

Many system 5 UNIX variants use scripts in the /etc/rcN.d/ directories to control which services should be started in the various runlevels. If, for instance, you wanted the secure shell daemon to run in runlevel 4, you would put a script named something like “S55sshd” in “/etc/rc4.d”. This script would usually accept the “start” “stop” and “restart” arguments, as well as the commands to perform these functions. When the system came up, it would execute “/etc/rc4.d/S55sshd start” when it transitioned into runlevel 4. On the way down, it would execute “/etc/rc4.d/S55sshd stop” as the system passed from runlevel 4 to runlevel 3. If you had made some changes to the sshd configuration file, and wanted to restart the service, you could manually execute “/etc/rc3.d/sshd restart” to kill and then restart the daemon.

Since this model involved having multiple copies of the same script in many different directories, Linux and others have adopted the standard of putting all service control scripts in “/etc/init.d/”, and using symbolic links to these scripts in the various “/etc/rcN.d/” directories. This allowed for the SGI IRIX innovation of the “chkconfig” command, which is command line tool that manages the symbolic links for you.

How to use “chkconfig” in Red Hat Enterprise Linux:

First, all your service control scripts need to be in the “/etc/init.d/” directory. They should reflect the name of the service they control. In our example, the file is named /etc/init.d/sshd”.

Secondly, they have a tag at the head of the script that looks something like this so that “chkconfig” understands that it can controll it:

# Basic support for IRIX style chkconfig
###
# chkconfig: 2345 55 25
# description: Manages the services you are controlling with the chkconfig command
###

The first set of numbers “2345” is are the default runlevels for the service, and “55” and “25” represent the name of the “S” and “K” symbolic links, and the order in which the service will be started and stopped in the respective runlevel. You will need to change these last two numbers, making them unique.

Once these requirements are met, using the command is fairly simple. When we go into /etc/rc3.d, we see a file called “S55sshd”.

[root@calvin rc2.d]# cd /etc/rc3.d
[root@calvin rc2.d]# ls -al S55sshd
lrwxrwxrwx 1 root root 14 Nov 15 15:10 S55sshd -> ../init.d/sshd

We see this file is a symbolic link to “../init.d/sshd”. Let’s run the “chkconfig” command to turn sshd off.

[root@calvin init.d]# /sbin/chkconfig sshd off
[root@calvin init.d]# /sbin/chkconfig --list sshd
sshd 0:off 1:off 2:off 3:off 4:off 5:off 6:off

chkconfig --list sshd confirms that sshd has been disabled in all runlevels, and the symbolic link has been removed from all “/etc/rcN.d/” directories.

Let’s turn sshd back on:

[root@calvin init.d]# /sbin/chkconfig sshd on
[root@calvin rc2.d]# /sbin/chkconfig --list sshd
sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off

chkconfig --list sshd confirms that sshd has now been enabled in runlevels 2, 3, 4 and 5, and we see s symbolic link to “/etc/init.d/sshd” named “S55sshd” in “/etc/rc2.d/”, “/etc/rc3.d/”, “/etc/rc4.d/” and “/etc/rc5.d/”.

Let’s imagine now that we only want sshd to be enabled in runlevel 5. We run the following command to accomplish this:

[root@calvin rc2.d]# /sbin/chkconfig sshd --level 234 off
cd /etc/[root@calvin rc2.d]# /sbin/chkconfig --list sshd
sshd 0:off 1:off 2:off 3:off 4:off 5:on 6:off

chkconfig --list sshd confirms that sshd has been disabled in all runlevels except 5, and the “S55sshd” has been removed from “/etc/rc2.d/”, “/etc/rc3.d/” and “/etc/rc4.d/”.

There is, of course, more to it, but this should get you well on your way to happily managing your system services with “chkconfig”.

Making RHEL 3 See Multiple LUNS

For some reason RHEL 3 comes out of the box configured to see only the first Lun on a SCSI channel. This is usually not a problem, as the first Lun is all you care about, but in some instances, you will need to configure the SCSI module to see multiple Luns.

In this case we are using an Adaptec DuraStor 6200S, which is set up to present the RAID controller as Lun 00, and the actual RAID array as Lun 01. Without any modifications to the system, we plug in in, and after a reboot check /proc/scsi/scsi. We can see the RAID controller, but since we can only see the first Lun on the channel, we never get to the array:

Host: scsi2 Channel: 00 Id: 00 Lun: 00
Vendor: Adaptec Model: DuraStor 6200S Rev: V100
Type: Processor ANSI SCSI revision: 03

The actual array would show up as “Channel: 00 Id: 00 Lun: 01”, but it’s not there. To resolve this, we have to first edit “/etc/modules.conf” and add the following line:

options scsi_mod max_scsi_luns=128 scsi_allow_ghost_devices=1

In our case, modules.conf looks like this after the modification:

alias eth0 e1000
alias eth1 e1000
alias scsi_hostadapter megaraid2
alias usb-controller usb-uhci
alias usb-controller1 ehci-hcd
alias scsi_hostadapter1 aic7xxx
options scsi_mod max_scsi_luns=128 scsi_allow_ghost_devices=1

Next we have to build a new initrd image. This is done with the “mkinitrd” command.

WARNING: MAKE DARN SURE you build this against the right kernel (the kernel you want to use). If you are going to replace your current initrd image with the new one, you should make a back-up copy first. The -f option will force or overwrite the current initrd image file.

cp /boot/initrd-2.4.21-47.ELsmp.img /boot/initrd-2.4.21-47.ELsmp.img.bak
mkinitrd -f -v /boot/initrd-2.4.21-47.ELsmp.img 2.4.21-47.ELsmp

Once this is done, you can reboot your machine, and check “/proc/scsi/scsi” to see confirm that it sees the second Lun. You should see something like this:

Host: scsi2 Channel: 00 Id: 00 Lun: 00
Vendor: Adaptec Model: DuraStor 6200S Rev: V100
Type: Processor ANSI SCSI revision: 03

Host: scsi2 Channel: 00 Id: 00 Lun: 01
Vendor: Adaptec Model: DuraStor 6200S Rev: V100
Type: Direct-Access ANSI SCSI revision: 03

Hat Tip: Alan Baker for help figuring this out.
UPDATE: RHEL 4 doest not have this problem.

REL 3 Direct Connect to EonStor A12F-G2221

This summer we have been migrating a bunch of data to our shiny new InfoTrend EonStor A12F-G2221. With 1G battery backed cache, it’s a screaming box of disk, and it looks cool to boot. There is a gotcha though if you want to direct connect it to QLogic QLA2340 card on a REL 3 server. Here is what you have to do.

First, get the new driver from QLogic, or install the one that came on CD with the HBA. The one that Red Hat packages is always old and useless, and one that QLogic provides is better anyways because the installer rebuilds the rdimage for you. Once you get the package just “cd” into the “qlafc-linux-X.XX.XX-X-install” and run “qlinstall”. This will install it all for you, so let it do it’s thing, and reboot the system when it’s done.

Now, go into the management console for your EonStor A12F-G2221. For the most part, the system defaults should work, but InfoTrend sets the default Fibre Connection to “Loop Only”. This is fine if you are dealing with a san, but since we are trying to do a direct connect, we have to change it to either “Auto” or “Direct Connect”. I suggest “Auto”, since that way you can have the other port connected to a loop if you want.

EonStor

That should be all you have to do. You will have to reboot the controller for the change to take effect, so make sure you do this during a scheduled downtime if you have the disk in production.

Changing Linux Mount Points

If you’re familiar with UNIX, you know that changing mount points is really pretty easy. All you have to do is go into “/etc/fstab”, “/etc/vfstab” (or whatever your flavor of UNIX happens to call its filesystem table) and change the mount directory.

If, for instance, you had a Solaris box, and you wanted to make the disk currently mounted as “/data” be mounted as “/database”, all you would have to do is the following:

# umount /data
# mv /data /database
Change this line in “/etc/vfstab” from something like this:
/dev/dsk/c1d0s6 /dev/rdsk/c1d0s6 /data ufs 1 yes –
to something like this:
/dev/dsk/c1d0s6 /dev/rdsk/c1d0s6 /database ufs 1 yes –
and remount it as “/database”.
# mount /database

With Linux, however, it’s not quite so clear anymore… It’s still easy, but it’s just not so clear what you have to do since they have now taken to mounting filesystems using the volume label. Rather than pointing directly to the disk device, Linux points to the label, and “/etc/fstab” look more like this:

LABEL=/data /data ext3 defaults 1 2

You can always simply change the disk label, but if you don’t care, you can just tell linux where the raw device is, bypassing the need to worry about the label. The easiest way to do this is simply to replace the “LABEL=/data” value to the “/dev” entry of the disk itself. Then, simply change “/data” to “/database” and you’re all set.

Here is an example of what you would do to change the mountpoint of “/data” to /database”:

# umount /data
# mv /data /database
Change this line in “/etc/fstab” from this:
LABEL=/data /data ext3 defaults 1 2
to this:
/dev/sda6 /database ext3 defaults 1 2
and remount it as /database
# mount /database

Remembering to change the example values here with those required for your situation.

Solaris Automounter

Whenever you’re using NFS mount points, it’s really nice to use some type of automounter. Linux and FreeBSD use AMD to accomplish this, but Solaris uses automountd, and it’s fun and easy to use… Here is an example of a configuration that will automatically mount an NFS share and unmount it after 5 minuets of inactivity.

We have a system called micky which has an NFS point shared to a system called minny as /shareme.
We can see that it is set up in the /etc/dfs/dfstab file on micky:

share -F nfs -o ro=minny.yourdomain.com -d “NFS ShareMe” /shareme

The above will share the directory read-only. If you would like to map the directory as root and be able to write to it, the command would look more like this:

share -F nfs -o rw,root=minny.yourdomain.com -d “NFS ShareMe” /shareme

You can run the share command on micky to check to make sure it is shared:

# share
– /shareme ro=minny.yourdomain.com “NFS ShareMe”

If it’s not shared, run shareall to share it:

# shareall

Now, jump on over to minny and add the following line to /etc/auto_master:

/- auto_direct

Automountd will now look in /etc/auto_direct for direct mount points.

Next edit /etc/auto_direct and add the following line:

/micky-shareme micky:/shareme

Now, create the directory for the NFS mount point on minny:

# mkdir /micky-shareme

Finally, run the auromount command on minny to inform the daemon of the changes:

# automount

That should do it… Have fun with your new automount NFS share.

More information on this can be found here