Sunday, May 30, 2010

Compressed RAM disk for Windows, The Virtual Way!

Recently, I developed Linux kernel driver which creates generic RAM based compressed block devices (called zram). Being RAM disks, they do not provide persistent storage but there are many use cases where persistence is not required: /tmp, various caches under /var, swap disks etc. These cases can benefit greatly from high speed RAM disks along with savings which compression brings!
However, all this seems to be completely Linux centric. But with virtualization, zram can be used for Windows too! The trick is a expose zram as a ‘raw disk’ to Windows running inside a Virtual Machine (VM). I will be using VirtualBox as example but exposing raw disks should be supported by other Virtualization solutions like VMware, KVM too.
Of course, you need to have Linux as the host and have the zram driver loaded. Here are the steps we need to do:
  • Get zram sources, compile and load the driver
  • Set zram disksize
  • Create VMDK file with raw disk set as /dev/zram0
  • Add this disk to Windows VM
Once this much is done, the disk will be detected in Windows as ‘VBox HardDisk’ and after disk initialization (as is needed for any new harddisk), you can format it with NTFS (or any other) filesystem.

Get zram sources, compile and load the driver

zram is not yet available as a downloadable tarball, so you need to checkout the source directly from repository:
hg clone compcache
Now, to compile it against your running kernel, just run:
If you get lots of compilation errors, then you are probably missing kernel-devel and kernel-headers package. This driver has been well tested with Linux kernel 2.6.33-xx which ships with Fedora 13 (x86_64).If compilation went fine, you should now have the zram.ko driver. Load it along with its dependencies:
modprobe lzo_compress
modprobe lzo_decompress
insmod ./zram.ko

Set zram disk size

Disksize is set using zramconfig userspace utility which is compiled along with the driver. You can find it in <sourcedir>/sub-projects/zramconfig/zramconfig. Following sets disksize as 2GB and initializes the disk:
zramconfig /dev/zram0 –-disksize_kb=2097152 --init

Create VMDK file with raw disk set as /dev/zram0

Now we will create a VMDK file which simply points to /dev/zram0 device as its data source. This VMDK will later be added to Windows VM in VirtualBox.
VBoxManage internalcommands createrawvmdk -filename ~/temp/zram.vmdk -rawdisk /dev/zram0 –register
This command creates VMDK file in ~/temp (you can replace it with any other location) and also registers as one of the harddisks in VirtualBox.

Normal (non-root) users cannot do direct I/O to /dev/zram devices but you certainly don’t want to run VirtualBox as root! So, as a workaround, you can ‘chown’ the device:
chown username:username /dev/zram0
Of course, you need to run this as root. This gives you the ownership of the device, so you will not have to run VirtualBox as root.

Add this disk to Windows VM

This VMDK disk (~/temp/zram.vmdk in our example), can be added to any VM, be it Linux or Windows. But for now, we will stick with Windows. Go to VM’s storage configuration and add this disk. You will then get storage configuration like this:

Now poweron the VM. Windows will detect this disk as ‘VBox HardDisk’ and you need to ‘initialize’ the disk within Windows before you can start using it (as is needed for any new harddisk). To initialize the disk, goto: Control Panel –> Administrative Tools –> Computer Management –> Disk Management. Here you will automatically get a wizard to help to initialize the disk and assign it a drive letter. Make sure you set Block Size as 4096 and keep NTFS filesystem compression disabled (default) -- otherwise, you will get suboptimal performance!

After the disk initialization wizard finishes, zram disk should show up in My Computer:

Above shows zram drive highlighted, formatted with NTFS filesystem and size of about 2GB. You can now use it as any other disk.

Apart from use as a generic disk, an interesting use case it to have Windows swap file on this disk. This way, whatever is swapped from Windows goes to host (Linux) where it is compressed and stored in memory itself! In a way this is like dynamically giving more memory to a VM. Reading/Writing to this disk is way faster than rotation disks, so it should also improve your VM performance.

To setup Windows to swap on zram disk, goto: Control Panel –> System –> Advanced –> Settings (Under Performance) –> Advanced –> Change (under Virtual Memory)

Now you should get screen like this, showing target disks for swap file:


Select zram as swap target, select System managed size and click Set. You can also disable swap file in C: to make sure all swapping goes to zram only.

At any time, you can monitor zram I/O stats on (Linux) host using zramconfig. Following also shows sample output stats from my system:

[ngupta@vflare ~]$ zramconfig /dev/zram0 --stats
DiskSize:        2097152 kB
NumReads:        4214012
NumWrites:       3941172
FailedReads:           0
FailedWrites:          0
InvalidIO:             0
NotifyFree:            0
ZeroPages:        393297
GoodCompress:         98 %
NoCompress:            1 %
PagesStored:        3399
PagesUsed:           105
OrigDataSize:      13596 kB
ComprDataSize:       393 kB
MemUsedTotal:        420 kB

That’s it!
If you do try it out, do let me know! :)