Thursday, January 12, 2012

Creating ramdisk in Linux

A RAMDisk is a portion of RAM which is being used as if it were a disk drive. RAMDisks have fixed sizes, and act like regular disk partitions. Access time is much faster for a RAMDisk than for a real, physical disk. However, any data stored on a RAMDisk is lost when the system is shut down or powered off.

RAMDisks can be a great place to store temporary data. Perfect candidates would be :

1) Mounting Loopback file systems (such as run-from-floppy/CD distributions),
2) Working on unencrypted data from encrypted documents,
3) In many embedded Linux systems, a RAMDisk is used to load initrd (initial Ram Disk), initrd is the final root file system.
4) Things which do not change eg. web images or downloadable files, etc.

The Linux kernel version 2.4 or later have built-in support for ramdisks. You can check if ramdisk is setup by doing:

[root@test-db]# dmesg | grep RAMDISK
RAMDISK driver initialized: 16 RAM disks of 16384K size 1024 blocksize

You should get above output on CentOS and RHEL. Other linux flavors will have similar output as well.

1) Changing the Kernel Parameters:

Ramdisk size is controlled by a command-line option that is passed to the kernel during boot. Since GRUB is the default bootloader for CentOs 6.2, I will modify /etc/grub.conf with the new kernel option. The kernel option for ramdisk size is: ramdisk_size=xxxxxx, where xxxxxx is the size expressed in 1024-byte blocks.

Here is what I will add to /etc/grub.conf to configure 4 GB ramdisks (ramdisk_size=4194304):

[root@test-db]# vi /etc/grub.conf

Find the line which looks similar to following:

kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/vg_lvm-lv_root

add ramdisk_size=4194304 to the end of the line. Now your grub.conf should look like:

--------------------------------------------------------------------------------------
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/mapper/vg_lvm-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-220.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/vg_lvm-lv_root rd_LVM_LV=vg_lvm/lv_swap rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_lvm/lv_roo
t rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM ramdisk_size=4194304
initrd /initramfs-2.6.32-220.el6.x86_64.img
--------------------------------------------------------------------------------------

Save and exit grub.conf. At this point you have it configured to have ramdisk with new size but it does not take effect until you reboot your system.

Once you have rebooted your system, we can start doing rest of configurations.

2) Format the ramdisk :
There is no need to format the ramdisk as a journaling file system, so we will simply use the ubiquitous ext2 file system. I only want to use one ramdisk, so I will only format /dev/ram0:

[root@test-db]# mke2fs -m 0 /dev/ram0

The -m 0 option keeps mke2fs from reserving any space on the file system for the root user, which is the default behavior. I want all of the ramdisk space available to a regular user for working with encrypted files.

3) Create a mount point and mount the ramdisk :
Now that you have formatted the ramdisk, you must create a mount point for it. Then you can mount your ramdisk and use it. We will use the directory /mnt/rd for this operation.

[root@test-db]# mkdir /ramdisk

[root@test-db]# mount /dev/ram0 /ramdisk

Now verify the new ramdisk mount:
[root@test-db]# df -h | grep ram0

4) Performance benchmarking :

Now that it has been created, you can copy, move, delete, edit, and list files on the ramdisk exactly as if they were on a physical disk partiton. We can do a IO benchmark by using the dd command.

In the example below the "/hdisk" is a folder on the servers hard drive and "/ramdisk" is the mounted ramdisk.

[root@test-db]# dd if=/dev/zero of=/hdisk/X1 bs=128k count=10240
10240+0 records in
10240+0 records out
1342177280 bytes (1.3 GB) copied, 50.6943 s, 26.5 MB/s
[root@test-db]# dd if=/dev/zero of=/ramdisk/X1 bs=128k count=10240
10240+0 records in
10240+0 records out
1342177280 bytes (1.3 GB) copied, 4.34945 s, 309 MB/s

The difference is clearly visible.

RAMDisk is also a great place to view decrypted GPG or OpenSSL files, as well as a good place to create files that will be encrypted. After your host is powered down, all traces of files created on the ramdisk are gone.

To unmount the ramdisk, simply enter the following:

[root@test-db]# umount -v /ramdisk

If you remount the ramdisk, your data will still be there. Once memory has been allocated to the ramdisk, it is flagged so that the kernel will not try to reuse the memory later. Therefore, you cannot “reclaim” the RAM after you are done with using the ramdisk. For this reason, you will want to be careful not to allocate more memory to the ramdisk than is absolutely necessary. In my case, I am allocating < 10% of the physical RAM. You will have to tailor the ramdisk size to your needs. Of course, you can always free up the space with a reboot!

Automating ramdisk creation :

If you need to create and mount a ramdisk every time your system boots, you can automate the process by adding some commands to your /etc/rc.local init script.

Here are the lines that can be added:

# Formats, mounts, and sets permissions for the 4 GB ramdisk
/sbin/mke2fs -q -m 0 /dev/ram0
/bin/mount /dev/ram0 /ramdisk
/bin/chown apache:apache /ramdisk
/bin/chmod 0750 /ramdisk

Cheers !
Harish.

No comments: