virtual machine

Work has kept me busy lately so it's been a while since my last post... I have been doing lots of research and collecting lots of information over the holiday break and I'm happy to say that in the coming days I will be posting a new server setup guide, this time for a server that is capable of running redundant storage (ZFS RAIDZ2), sharing home media (Plex Media Server, SMB, AFP) as well as a full Windows 7 gaming rig simultaneously!

Windows runs in a virtual machine and is assigned it's own real graphics card from the host's hardware using the using the brand-new VFIO PCI passthrough technique with the VGA quirks enabled. This does require a motherboard and CPU with support for IOMMU, more commonly known as VT-d or AMD-Vi.

I had the need to setup a new VM for software testing today, and I kept running into intermittent problems where VirtualBox would freeze and then an OS X kernel panic, freezing/crashing the entire machine.

Luckily, I had made a snapshot in the OS moments earlier to the crash so I had a safe place to revert to, but the crashes kept happing at seemingly random times.

I setup a looped execution of 'dmesg' to see what was going on just before the crash and saw this at the next freeze:

VBoxDrv: host_vmxon -> vmx_use_count=1 rc=0VBoxDrv: host_vmxoff -> vmx_use_count=0VBoxDrv: host_vmxon -> vmx_use_count=1 rc=0aio_queue_async_request(): too many in flight for proc: 16.aio_queue_async_request(): too many in flight for proc: 16.aio_queue_async_request(): too many in flight for proc: 16.aio_queue_async_request(): too many in flight for proc: 16.aio_queue_async_request(): too many in flight for proc: 16.aio_queue_async_request(): too many in flight for proc: 16.

It would appear that the default limits for the OS X kernel's asynchronous I/O are very, very low. VirtualBox likely exceeds them when your VM(s) are performing heavy disk I/O, hence the 'too many in flight' message in the logs.

Luckily for us, there's a quick and easy solution:

sudo sysctl -w kern.aiomax=512 kern.aioprocmax=128 kern.aiothreads=16

then restart VirtualBox. These settings will apply until you reboot. To make the changes permanent, add/update the following lines in /etc/sysctl.conf:

kern.aiomax=512kern.aioprocmax=128kern.aiothreads=16

Note: you can probably set those limits even higher, as documentation for Sybase (by SAP) recommends values 2048 / 1024 / 16 when using its software.

On one of my development machines I triple-boot so that I can test in a variety of operating environments. My default is OS X and the other day I wanted to write documentation using DocBook. I knew that my Linux installation already had publican installed and ready to go (publican is a wonderful documentation tool written by Red Hat to facilitate the publishing of DocBook-based documentation) and I really did not want to setup a new Fedora VM that duplicated a setup I already had.

In reality, a new VM would not be all that much effort, but I though it would be really handy to know how to boot a VM up from a physical partition and this way I could kill two birds with one stone. After some research, it seemed using VMWare's VMDK (Virtual Machine Disk Format) images was the most appropriate, as the metadata could be tricked into pointing to physical partitions instead of files. Unfortunately, the tools VirtualBox provide to create them are not compatible with GPT disk tables out of the box. This blog post does mention a trick to convert the VMDK metadata to match the GPT disk layout, but it failed consistently when I tried.

I then, by fluke, found Dave Vasilevsky's vmdk-raw-parts script on GitHub which worked flawlessly! Its usage is well documented so I will not bore you with the details, but with that said after using it to create my custom VMDK, the only change required was to run chmod 666 /dev/diskXsY to grant my user write permissions to the disk (prevents you from having to start VirtualBox as root).

Some Extra Troubleshooting

These details are completely irrelevant to the above, but I wanted to mention them here for others wanting to run the same setup:

If you need USB pass-through, remember to set your VCPUs to 1; set it to anything higher and USB stops functioning.

You'll need to redo the 'chmod' when ever you reboot your machine, as the permissions on the dev node get reset upon boot.

During the trial-and-error process of getting this to work, I often needed to recreate my VMDK and reload it. VirtualBox will moan about mismatched UUIDs... The simple fix is to open File > Virtual Media Manager... to delete then re-add your VMDK file.