Running Windows under Linux KVM

    Task: run a number of virtual machines with Windows on a typical Linux server.

    Solution: any modern Linux distribution, the “native” KVM virtualization technology, Windows 2003 and the settings described below.

    See also: introductory article on configuring KVM containers for FreeBSD .

    Guest OS selection


    Windows XP is unstable under Linux KVM. The main errors are the consumption of 100% of the processor by the csrss.exe process (up to the termination of RDP sessions) and the BSOD with the IRQL_NOT_LESS_OR_EQUAL code in HAL.DLL. If you managed to achieve stable operation, be sure to disable the automatic installation of updates! In our experience, for WinXP to work under KVM, they have become a major source of problems.

    Windows 7 works fine, but according to Proxmox counters, it requires more than 3 gigabytes of RAM to work.

    The best option was the 32-bit edition of Windows 2003 R2:
    • works reliably, including with virtio,
    • does not have compatibility problems with XP (even the appearance can be made the same )
    • takes up less than 800 megabytes of RAM.

    The upper limit of 4 gigabytes of memory (without PAE) was enough for all the problems that arose.

    For informational purposes, any distribution published on RuTracker is suitable.

    First launch and virtio


    #!/bin/sh
    VM_ID="10"
    MACBASE="00:16:3e:ff:ff"
    HDA="vm_${VM_ID}.img"
    HDB="temp.img"
    HDC="w2k3_r2_ent_rus_x86/ru_win_srv_2003_r2_enterprise_with_sp2_vl_cd1_X13-46484.iso"
    HDD="virtio-win-0.1-52.iso"
    sudo kvm \
    -enable-kvm \
    -boot "menu=on,order=d" \
    -m 1024M \
    -balloon virtio \
    -name "kvm_${VM_ID}" \
    -drive "file=$HDA,index=0,media=disk,cache=writeback" \
    -drive "file=$HDB,index=1,media=disk,cache=writeback,if=virtio" \
    -drive "file=$HDC,index=2,media=cdrom,cache=writeback,readonly" \
    -drive "file=$HDD,index=3,media=cdrom,cache=writeback,readonly" \
    -net "nic,model=virtio,macaddr=${MACBASE}:${VM_ID}" \
    -net "tap,ifname=tap${VM_ID},script=no,downscript=no" \
    -vnc "0.0.0.0:${VM_ID}"

    The -vnc ... option only makes sense on a server without a GUI. By default, KVM will open a window via SDL. In both cases, Ctrl + Alt + Shift + 1 and Ctrl + Alt + Shift + 2 are used to switch between the guest and the management console inside the window.

    Parameter " -net nic,model=virtio,..." will create inside the VM a network card of an unknown Windows type, for which the hardware configuration wizard will offer to select a driver. The paired parameter " -net tap,..." will create a network interface in the host OS for communication with the VM. Assigning IP addresses, configuring DHCP, and accessing the outside world through ProxyARP, NAT, or Bridge are not directly related to Windows, so they are not considered here.

    Now about the most important at this stage, i.e. about wheels.

    HDCIs an ISO image with a Windows distribution. The file name is taken from the torrent in the previous section. From it, the first boot of the system (" -boot order=d") will occur inside the VM .

    HDD is an ISO image with virtio drivers. Download from alt.fedoraproject.org/pub/alt/virtio-win/latest/images/bin

    HDA - this is an empty disk image on which the system will be installed. Created by " kvm-img create -f qcow2 vm_10.img 50G".

    HDB is an empty disk image created through " kvm-img create -f qcow2 temp.img 1G" for the sole purpose of showing an unknown type of Windows device so that it requires a driver for it. Installing the virtio driver for the temporary disk into the system will then switch from the IDE to the virtio system disk.

    After the installation of the system and drivers is completely completed, in the start command you should remove "-boot" and all the lines of "-drive", except for the first one, because temporary disk and ISO-images will not be needed (pay attention to the added " if=virtio"!):
    kvm ...  -drive "file=$HDA,index=0,media=disk,cache=writeback,if=virtio" ...
    

    For the benefit of virtio, network configuration options and kvm command line options read in habrahabr.ru/post/167099

    Recommended Windows Settings


    First, by default, Windows creates a full memory dump with BSODs. In the best case, this will significantly slow down the reboot. At worst, will lead to a complete hang.

    Secondly, automatic updates are enabled by default, and there is a risk that one of them will make work under KVM unstable.

    Therefore, after the installation is completed in the very first place (before installing the drivers!) It is recommended to go to the Control Panel => System:
    • Auto Update: Disable
    • Advanced => Error Report => Disable
    • Advanced => Download and restore => Settings => System crash => Write debugging information => Small memory dump (64KB)

    TCP / IP settings are optional, but will slightly improve performance, as In a virtual environment, there are no problems that need to be considered when transmitting over a physical network.

    Description: www.linux-kvm.org/page/WindowsGuestDrivers/kvmnet/registry

    Ready REG file: svn1.sytes.net/linuxkvm/tune-guest-tcpip.reg

    After that you can start installing drivers for the disk (virt-stor ) and a network card (virt-net). After installing them, the “Red Hat VirtIO SCSI Controller”, “Red Hat VirtIO SCSI Disk Device” and “Red Hat VirtIO Ethernet Adapter” will appear in the Hardware Manager.

    Ballooning


    The traditional approach is to immediately allocate a RAM block of a given size, for example, 512 megabytes, at the start of the virtual machine (VM). Its disadvantage is in those moments when there is unused space in the VM memory, it may be missed in other VMs and the host system.

    Memory balling is a mechanism for dynamically (a) allocating host RAM for VMs as necessary and (b) returning unused blocks as they become available. Thanks to it, it becomes possible to simultaneously launch many VMs, the total amount of virtual RAM in which is more than the amount of physical RAM in the host system, provided that they do not use the maximum allowed volume all at once. Thanks to this, the memory of the host system is distributed among the VMs as flexibly as between ordinary processes.

    The creation of virtual resources that exceed physical in volume is indicated by the terms “overcommit” and “overselling” , beloved by many hosting companies .

    Balloning requires the coordinated operation of two software components:
    • MOM (memory overcommitment manager) in the host system, which changes the amount of RAM for the VM based on requests from it,
    • VMM (virtual memory manager) in a guest OS that interacts with MOM through a virtual PCI controller.

    MOM in the latest versions of KVM is turned on automatically, the old ones demanded to enable it using "kvm ... -balloon virtio" on the command line.

    Windows will see the guest device for communicating with the MOM hardware manager (devmgmt.msc) as an "unknown type of PCI standard RAM controller." Unlike virt-stor and virt-net, the driver for it will not be offered to install automatically. Instead, go to the device’s properties, select the update on the “Driver” tab and manually specify the path to balloon.inf on the VirtIO CD ( proof ). After that, the device is renamed to “VirtIO Balloon Driver”.

    ACPI


    By default, Windows 2003 allows you to turn off itself in the only way - enter the login password, select Start => "Shutdown", enter a note, click "OK". Of course, this approach is not acceptable on a VDS farm. KVM (and QEMU) can emulate ACPI. The "system_powerdown" command is similar to pressing the power button on a physical computer, but Windows will ignore it. It is treated with the following .reg file:
    Windows Registry Editor Version 5.00
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system]
    "ShutdownWithoutLogon"=dword:00000001
    "DisableCAD"=dword:00000001
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
    "ShutdownWarningDialogTimeout"=dword:00000003
    

    It is in a ready-to-run form: svn1.sytes.net/linuxkvm/win-acpi-kvm.reg

    Original source with detailed explanations: umgum.com/acpi-windows2003-shutdown

    Caching


    If the image of the guest disk is stored on the VDS farm as a file, the caching of guest files may turn out to be double - first, the guest OS caches them when accessing the virtual disk, then the farm OS when accessing the physical one.

    In total, 3 main modes are possible :
    • none - the host system does not cache the image file either for reading or writing
    • writeback - write immediately, reading is cached
    • writethrough - read and write are cached

    In different versions of qemu / kvm and in different operating systems, different modes can be used by default. For example, Qemu prior to version 1.2 uses writethrough, 1.2 switched to writeback, cache = none is selected in Proxmox.

    Without exception, sources on the Web advise against using writethrough as the slowest. According to a subjective assessment, writeback is optimal for VMs with Windows, none for VMs with Linux and FreeBSD.

    Network hangs


    The only serious problem that the KVM error definitely causes is the freezing of the guest network during heavy traffic: bugs.centos.org/view.php?id=5526 (besides the error description itself, there are important links to other bugtrackers).

    The recommendations proposed by the participants in the discussion (updating qemu-kvm and the kernel, changing command line parameters, using vhost-net), unfortunately, have not yet been able to solve it.

    With each freeze, you have to go to the VM console via VNC and reset the network interface, after which the traffic starts to go normal again.

    You can automate this action in Windows using AutoIt if you create the PingFailed_ResetNic.au3 file and call it by the Task Manager every few minutes:
    #include «EventLog.au3»Local$PingHost = "192.168.0.1"
    Local $Interface = "LAN"
    Ping($PingHost, 250)
    If @error = 0 Then Exit
    Local $hEventLog = _EventLog__Open("", "RestartNicOnPingFailure")
    Local $aEmpty[1] = [0]
    _EventLog__Report($hEventLog, 2, 0, 1, "", "Restart NIC " & Interface & " on failed ping to " & PingHost, $aEmpty)
    _EventLog__Close($hEventLog)
    RunWait("netsh interface set interface " & $Interface & " DISABLED", "", @SW_HIDE)
    RunWait("netsh interface set interface " & $Interface &  " ENABLED", "", @SW_HIDE)
    

    Option for CMD.EXE: rickosborne.org/blog/2007/02/stupid-windows-tricks-restart-network-adapter-when-it-hangs

    Such a "solution" may not always be considered satisfactory, but in some cases it is enough to reduce the negative effect to an acceptable minimum, allowing you to wait for the release of the fix instead of more drastic measures.

    Also popular now: