This set of notes is based on the wiki page on the CentOS Wiki Page on KVM

Required Hardware (Ideally)

Intel or AMD based machine that supports virtualisation. On intel based machines you can check by

grep vmx /proc/cpuinfo

On and AMD based machine you can check by

grep svm /proc/cpuinfo

Your host machine should probably be multi-core if possible, and have at least 2gigs of ram, but more is preferred. Have the appropriate kernel module loaded.

If its Intel do

modprobe kvm-intel

If it's AMD do

modproble kvm-amd

Required Software (What I used)

  • The ScientificLinux 5.4 distro installed on my host system.
    • The kmod-kvm package - it's apart of the SL repos as far as I know.
    • The kvm package - it's apart of the SL repos as far as I know.
    • The QEMU stack, which came with the kvm package.
    • The kvm-qemu-img - it's apart of the SL repos as far as I know.
    • The bridge-utils package to setup a bridged network.
    • The tunctl package which is available from the epel repository.

KVM should be apart of recent linux kernel releases (since 2.6.20 according to the releasenotes).

Specifically these were the packages I used...

[root@duo ~]# rpm -qa | egrep 'kvm|bridge-utils|tunctl'

Creating a Virtual Machine

First make sure the permissions for the KVM device node is correct

chown root:kvm /dev/kvm
chmod 0660 /dev/kvm

and add yourself to the kvm group

usermod -G kvm -a jtang

The process is

  1. Create a disk image with qemu-img or use dd
  2. Boot the disk image with qemu-kvm with a valid install media

There are some choices to be made when creating the images, you can either use the raw format which will result in pretty big full sized disk images. Or else you can use the qcow2 format which is a sparse format where the disk image will grow to the maximum size that you have defined.

Create the disk image

qemu-img create -f qcow2 disk.img 5G


dd if=/dev/zero of=disk.img bs=1G count=5

Boot the image for an install

Note in Scientific linux the qemu-kvm binary is located in /usr/libexec/qemu-kvm, you could create a symlink for it if you wish.

/usr/libexec/qemu-kvm -hda disk.img -cdrom archlinux-2009.08-core-x86_64.iso -m 512 -boot d

Once it is booted up you can just follow the instructions on installing your guest OS.

Bridged Tap Networking and KVM

By default KVM supports NAT for its guests, it's not ideal for production environments. I would prefer to have a bridged network so my guests can appear on my network with a real IP address . Edit /etc/udev/rules.d/90-kvm-rules such that

KERNEL=="kvm",          NAME="%k", GROUP="kvm", MODE="0660"
KERNEL=="tun",          NAME="net/%k", GROUP="kvm", MODE="0660"

or else do this in /etc/rc.local

chown root:kvm /dev/net/tun
chmod 0660 /dev/net/tun

Now run these commands

brctl addbr br0
ifconfig eth0
brctl addif br0 eth0
dhclient br0
tunctl -b -u jtang
ifconfig tap0 up
brctl addif br0 tap0
iptables -I RH-Firewall-1-INPUT -i br0 -j ACCEPT
qemu-kvm ~/win2k.img -m 512 -net nic -net tap,ifname=tap0,script=no

If you do not have a DHCP server to assign your NIC an address you could do this in place of the dhclient command assuming you are on a network.

ifconfig br0 netmask up
route add -net netmask br0
route add default gw br0

Attempting to run the Virtual Machine

There are some issues that I haven't addressed, such as monitoring the kvm guest.

/usr/libexec/qemu-kvm -hda disk.img  -m 512 -net nic -net tap,ifname=tap0,script=no -nographic  -daemonize

I should probably configure the guest to be accessible via a serial console as well.

Using virtio for the networking

/usr/libexec/qemu-kvm -hda disk.img  -m 512 -net nic,model=virtio -net tap,ifname=tap0,script=no

Using virtio for the storage

/usr/libexec/qemu-kvm -drive file=disk.img,if=virtio,boot=on  -m 512 -net nic,model=virtio -net tap,ifname=tap0,script=no

You will need to correct references to sda/hda to vda in grub and in your fstab, and also make sure your initrd has the virtio, virtio_blk and virtio_pci loaded up at boot. The best thing to do is to use disk labels or blkid's for fstab instead of device names.

Installing ScientificLinux 5.4 as a guest

Some notes on installing SL5.4 as a guest. There's probably more efficient ways of doing this.

First create a disk image, I chose to use qcow2 32gb is size.

qemu-img create -f qcow2 sl5x.img 32G

Then install the OS, I used the SL5.4 install dvd. I suppose you could do a network install if you wanted.

/usr/libexec/qemu-kvm -drive file=sl5x.img,if=virtio,boot=on,cache=writethrough  -m 768 -cdrom SL.54.110309.DVD.x86_64.disc1.iso

Running the virtual machine

/usr/libexec/qemu-kvm -drive file=sl54-kvm.img,if=virtio,boot=on,cache=writethrough \
-net nic,macaddr=DE:AD:BE:EF:25:12,model=virtio \
-net tap,ifname=tap0,script=no  -m 768  -nographic

I also enabled a serial console and made grub redirect its output to the serial console.

My grub.conf file is now something like this

serial --unit=0 --speed=9600 --word=8 --parity =no --stop=1
terminal --timeout=10 --dumb serial console
title Scientific Linux (2.6.18-164.2.1.el5)
    root (hd0,0)
    kernel /vmlinuz-2.6.18-164.2.1.el5 ro root=/dev/VolGroup00/LogVol00 console=tty0 console=ttyS0,9600n8
    initrd /initrd-2.6.18-164.2.1.el5.img

And in the inittab near the bottom,

# Run gettys in standard runlevels
co:2345:respawn:/sbin/agetty ttyS0 57600 vt100-nav
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6

The above changes lets me connect to the virtual machine without needing a graphical interface. This however fails to work if you daemonize the process. According to the man pages it is possible to redirect the virtual machine serial port to the hosts serial port in /dev/xxx somewhere, I didn't get this to work. However I did get the redirection to a pty to work and I was able to connect to it via minicom.

Enlarging a disk image

I found this online, its the quickest way to enlarge your disk image, note it must be a raw image (assuming you started with a 10gb image you will end up with a 20gb image with the following commands)

dd if=/dev/zero of=foo.img bs=1 count=1 seek=$(($(stat -c%s foo.img)+10*1024**3-1))


dd if=/dev/null of=foo.img bs=1b seek=20G count=0

or you could cat a file full of zeros and append it to your diskimage, its up to you.

Apparently the best method and the safest method is to do this...

qemu-img create -f raw morespace.raw <size>
qemu-img convert -f qcow2 existing.img -O raw existing.raw
cat morespace.raw >> existing.raw
qemu-img convert -f raw existing.raw -O qcow2 existing-larger.img

I haven't tried any of the above yet to confirm which is the best method.


  1. If you find that bridged networking doesn't work, make sure the tap interface has been added to the bridge.
Bookmark and Share