Practical Implementation
Below are some early thoughts and ideas. For practical implementation, please visit this project page:
http://code.google.com/p/kvmadm/
Multiuser usage of KVM: Assumptions
- The host computer runs several instances of KVM virtual machines.
- Each virtual machine runs as a process with privileges of a user it is allocated to. This makes it possible to utilize standard Linux user access control mechanisms.
- Users may logon in various ways (see below), but even if a user possesses a shell account on the host computer, they should be prevented from direct execution of KVM (e. g. from command line), i. e. from uncontrolled creation of virtual machine instances. Therefore, a secure wrapper is necessary to run KVM on users' behalf.
User Logon Possibilities
- Logon via ssh to the host computer, then launch a VM by invoking the wrapper passing desired ID of VM to start, then ssh into the VM (or xdm, or http)
- VM is already running for a user (variant: frozen when user logs off, and unfrozen when they log on), so user logs on via ssh (or xdm, ot http) into a running VM instance
- VM is running as a daemon, providing some services to other VMs (e. g. NFS/SAMBA server), and users access it indirectly from their own VMs by appropriate protocols
Virtual Machine Layout
Classification of QEMU/KVM Options (as of 0.17)
Options that Users Are Allowed to Set
-fda/-fdb file use 'file' as floppy disk 0/1 image
-hda/-hdb file use 'file' as IDE hard disk 0/1 image
-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)
-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)
-snapshot write to temporary files instead of disk image files
-localtime set the real time clock to local time [default=utc]
-kernel bzImage use 'bzImage' as kernel image
-append cmdline use'cmdline' as kernel command line
-initrd file use 'file' as initial ramdisk
-no-acpi disable ACPI-no-reboot exit instead of rebooting
-loadvm file start right away with a saved state (loadvm in monitor)
-vnc display start a VNC server on display
-option-rom rom load a file, rom, into the option ROM space
Options that Users Are Not Allowed to Set
-m megs set virtual RAM size to megs MB [default=128]
-nographic disable graphical output and redirect serial I/Os to console
-win2k-hack use it when installing Windows 2000 to avoid a disk full bug
-usb enable the USB driver (will be the default soon)
-usbdevice name add the host or guest USB device 'name'
-net nic[,vlan=n][,macaddr=addr][,model=type] create a new Network Interface Card and connect it to VLAN 'n'
-net user[,vlan=n][,hostname=host] connect the user mode network stack to VLAN 'n' and send hostname 'host' to DHCP clients
-net tap[,vlan=n][,fd=h][,ifname=name][,script=file] connectthe host TAP network interface to VLAN 'n' and use the network script'file' (default=/etc/qemu-ifup); use 'script=no' to disable scriptexecution; use 'fd=h' to connect to an already opened TAP interface
-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port] connect the vlan 'n' to another VLAN using a socket connection
-net socket[,vlan=n][,fd=h][,mcast=maddr:port] connect the vlan 'n' to multicast maddr and port
-net none use it alone to have zero network devices; if no -net option is provided, the default is '-net nic -net user'
-tftp prefix allow tftp access to files starting with prefix [-net user]
-smb dir allow SMB access to files in 'dir'[-net user]
-redir [tcp|udp]:host-port:[guest-host]:guest-port redirect TCP or UDP connections from host to guest [-net user]
-monitor dev redirect the monitor to char device 'dev'
-vmchanneldi:DI,dev redirect the hypercall device with device id DI, to chardevice 'dev'
-balloon dev redirect the balloon hypercall device to chardevice 'dev'
-serial dev redirect the serial port to char device 'dev'
-parallel dev redirect the parallel port to char device 'dev'
-pidfile file Write PID to 'file'
-no-rtc don't use /dev/rtc for timer alarm (do use gettimeofday)
Options that Are Not Used
-M machine select emulated machine (-M ? for list) -hdc/-hdd file use 'file' as IDE hard disk 2/3 image
-no-quit disable SDL window close capability
-no-fd-bootchk disable boot signature checking for floppy disks
-smp n set the number of CPUs to 'n' [default=1]
-k language use keyboard layout (for example "fr" for French)
-audio-help print list of audio drivers and their options
-soundhw c1,... enable audio support and only specified sound cards (comma separated list) use -soundhw ? to get the list of supported cards use -soundhw all to enable all of them
-full-screen start in full screen
-S freeze CPU at startup (use 'c' to start execution)
-s wait gdb connection to port 1234
-p port change gdb connection port
-d item1,... output log to /tmp/qemu.log (use -d ? for a list of log items)
-L path set the directory for the BIOS, VGA BIOS and keymaps
-no-kvm disable KVM hardware virtualization
-std-vga simulate a standard VGA card with VESA Bochs Extensions (default is CL-GD5446 PCI VGA)
-daemonize daemonize QEMU after initializing
-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS translation (t=none or lba) (usually qemu can guess them)
VM ID Structure
Virtual machine identifier serves two purposes:
- to identify a VM in human-readable way
- to encode the options to run KVM with, that are not allowed to be set by user
An identifier therefore consists of two parts:
- a human-readable part which is a symlink to the second part
- a KVM options part which is a directory containing the VM components.
In the simplest case, the second part of a VM identifier may be just a string containing all options set for this particular VM, encoded in base64 to avoid special characters and whitespace in the directory name. To distinguish between two VMs with the same options, the second part of VM identifier also contains the human-readable name, but it is not passed to KVM as an option.
VM Directory Structure
This project especially pursues simplicity of design. Because of this, it is necessary to avoid another database or a configuration file for VM configuration management. The file system may serve this purpose on its own, both providing storage for configuration options, and access separation mechanism.
The top level directory of VMs contains subdirectories, one per VM. Names of directories are as to inform KVM secure wrapper of all KVM options that need to be set, and all actions to be made prior to running KVM. Options are described above (those options users are not allowed to set); actions to be made prior to running KVM are to create one or more tap devices, add them to bridges, assign IP addresses.
The top level directory of VMs also contains symlinks to VM subdirectories, each symlink represents human-readable name of each VM to be used as VM ID known to users and supplied on the KVM secure wrapper's command line.
Each VM subdirectory has access permissions 0x700 and is owned by VM user. The top level directory of VMs has permissions that do not allow users modify (rename) VM subdirectories.
Inside each VM subdirectory, the following files and symlinks are located:
Name |
File/ Symlink |
Purpose |
KVM Options Affected |
Comments |
fda |
F |
Identify the floppy image |
-fda |
A file which contains a floppy disk image. If absent, -fda option will not be used. |
hda |
F |
Identify the hda image |
-hda |
A file which contains a hda device image. If absent, -hda option will not be used. |
hdb |
F |
Identify the hdb image |
-hdb |
A file which contains a hdb device image. If absent, -hdb option will not be used. |
cdrom |
F |
Identify the cdrom image |
-cdrom |
A file which contains a cdrom device image. If absent, -cdrom option will not be used. |
kernel |
F |
Linux kernel for external loading |
-kernel |
Should contain a Linux kernel image |
append |
F |
Boot options for the Linux kernel |
-append |
A text file containing one or more lines (will be concatenated into one and space-separated) to supply the boot options to the Linux kernel whose image is in the kernel file |
initrd |
F |
Init ramdisk for the Linux kernel |
-initrd |
An image to use as init ramdisk for the Linux kernel whose image is in the kernel file |
boot |
S |
Specifies the boot method |
-boot |
The -boot option is formed depending on the symlink target: fda - a, hda - b, cdrom - c, anything else - n. If the boot symlink is not present, VM will not boot. The wrapper will validate the link: if it contains "hda", and hda file is not present, VM will not boot. |
rom |
F |
File image for option ROM |
-option-rom |
If this file is present, KVM will be started with the -option-rom option |
use-vnc |
F |
Use VNC for graphic console |
-vnc |
A text file: if its first character is y or Y, KVM will be started with - vnc option, and VNC server will be listening on the Unix domain socket named vnc in the VM subdirectory |
no-acpi |
F |
Setting for the no-acpi option |
-no-acpi |
A text file whose first character (y, Y, n, N) will be used as the value for this option |
no-reboot |
F |
Setting for the -no-reboot option |
-no-reboot |
See comment for no-acpi |