суббота, 1 октября 2011 г.

KVM и Microsoft Windows XP

Решил перейти с безблагодатного VirtualBox на православный KVM. Как и ожидал, основные проблемы возникли с переводом гостевой Windows XP SP3 EN, которую держу лишь ради пары нужных программ.

Проблемы возникли следующие.

  • Просто сконвертировать контейнер с виртуалкой не получилось - из-за смены виртуального оборудования Windows вылетает при загрузке с синим экраном. Поскольку возиться с выяснением причин было лень, пришлось переустановить Windows заново
  • Низкая производительность виртуального диска - все сильно тормозит
  • В VirtualBox можно было задать Shared Folders для удобного обмена файлами между хостом и гостем, обещанная в KVM опция -smb почему-то не работает
  • Нет интеграции буфера обмена между хостом и гостевой системой
  • Можно задать только фиксированные стандартные разшения экрана у гостевой системы, при этом окно QEMU использует рабочее пространство на моем мониторе неэффективно. Нельзя задать произвольный размер окна как в VirtualBox

Устранение всех проблем и заметки по интеграции.

После внимательного чтения мануала к KVM выяснилось, что режим работы виртуального диска по-умолчанию "writethrough" является надежным, но не очень производительным, особенно для файловых контейнеров в формате QCOW2 - поэтому меняем его на гораздо более производительный режим "writeback".

Отказываемся от работы с гостевой системой через окно QEMU - вместо этого используем программу rdesktop и доступ к гостевой системе через протокол RDP-v5. Для этого нужно включить в Windows XP опцию доступа через RDP и пробросить порт RDP (3389) из гостевой системы в хост. При этом можно запускать гостевую систему KVM даже в headless режиме, т.е. без основного окна.

У програмы rdesktop кроме кучи задокументированных ключей есть отсутствующий в man-руководстве ключик -r "clipboard:PRIMARYCLIPBOARD" который дает возможность интегрировать буферы обмена между хостом и гостевой системой.

Рекламируемый seamless-rdp режим у меня так нормально и не заработал - впрочем, не очень-то и нужно

Гостевая система может получить доступ к файлам хоста с помощью опции -r disk:{name}={path} программы rdesktop. При этом гостевая система видит диск как шару \\tsclient\name

Если опция -r disk:{name}={path} включена, гостевая система Windows XP при создании файлов устанавливает у них аттрибут "+x" что не очень приемлимо. Чтобы атрибуты у создаваемых и модифицируемых файлов были нормальными нужно установить umask для процесса rdesktop в значение 0133.

Размер экрана rdesktop настраивается под конкретный монитор опцией -g, причем кроме фиксированного размера в пикселах можно задать размер окна в процентах от размера экрана.

Неочевидный момент, который поначалу вводил в сильное замешательство - после запуска гостевой системы подключение через RDP возможно лишь по истечении 40-50 секунд. Причина такого поведения не совсем ясна: возможно это происходит из-за того, что необходимые сервисы Windows подгружаются не сразу; а возможно такое поведение обуславливается политиками безопасности Windows XP.

После окончательной настройки Windows XP можно установить у виртуальной системы опцию -snapshot которая будет предохранять файловый контейнер гостевой системы от новых изменений. Таким образом при каждом повторном запуске система будет в одном и том же состоянии, независимо от производимых в ней операций.

Для Windows XP существует паравиртуализированный драйвер для сетевой карты virtio. Без этого сетевого драйвера перерисовка окон в rdesktop происходит очень медленно, также без этого драйвера в rdesktop не работает шаринг папки. Также существует драйвер и для жесткого диска virtio.

Windows XP (в отличие от Linux) предполагает что часы на материнской плате идут по локальному времени - поэтому необходима опция KVM -rtc "base=localtime"

Опция -usbdevice "tablet" позволит избежать захвата мыши окном QEMU

В режиме удаленного RDP-подключения в главном меню Windows XP отстутствует пункт Shutdown. Однако, если нажать Ctrl+Alt+Del, то в меню появившегося приложения "Windows Task Manager" операция отключения компьютера будет доступна. Кроме того, если у виртуальной машины включена опция -snapshot ее можно отключать простым закрытием окна QEMU без риска повредить файловую систему.

Финальный скрипт запуска виртуальной машины с гостевой системой Windows XP

#!/bin/bash

# user: winxp/winxp

CURRENT_DIR=`readlink -f $0`
CURRENT_DIR=`dirname ${CURRENT_DIR}`

unset NET_FWD
NET_FWD="hostfwd=tcp:127.0.0.1:13389-:3389" # RDP

XP_DISTRO="/home/archive/distro/xp/winxppro-sp3-x86-vl-en.iso"
XP_ADDONS="/home/archive/distro/xp/NETKVM-20081229.iso"

unset OPTS
OPTS=("${OPTS[@]}" -snapshot)
OPTS=("${OPTS[@]}" -daemonize)
OPTS=("${OPTS[@]}" -pidfile "${CURRENT_DIR}/vm-winxp.pid")
#OPTS=("${OPTS[@]}" -vnc "127.0.0.1:1")
#OPTS=("${OPTS[@]}" -monitor "tcp:127.0.0.1:34526,server,nowait")
OPTS=("${OPTS[@]}" -name "WinXP Workstation")
OPTS=("${OPTS[@]}" -uuid "46036849-8658-4998-a918-166d900cffc7")
OPTS=("${OPTS[@]}" -enable-kvm)
OPTS=("${OPTS[@]}" -smp 1)
OPTS=("${OPTS[@]}" -m "512M")
OPTS=("${OPTS[@]}" -drive "file=${CURRENT_DIR}/vm-winxp.qcow2,if=ide,media=disk,index=0,cache=writeback")
#OPTS=("${OPTS[@]}" -drive "file=${XP_DISTRO},if=ide,media=cdrom,index=1,cache=writeback")
#OPTS=("${OPTS[@]}" -drive "file=${XP_ADDONS},if=ide,media=cdrom,index=1,cache=writeback")
OPTS=("${OPTS[@]}" -boot "order=c")
OPTS=("${OPTS[@]}" -rtc "base=localtime")
OPTS=("${OPTS[@]}" -soundhw "es1370")
OPTS=("${OPTS[@]}" -vga "cirrus")
OPTS=("${OPTS[@]}" -net "nic,vlan=0,macaddr=52:54:00:12:34:56,model=virtio")
OPTS=("${OPTS[@]}" -net "user,vlan=0,hostname=vm-winxp,${NET_FWD}")
OPTS=("${OPTS[@]}" -usb)
OPTS=("${OPTS[@]}" -usbdevice "tablet")

kvm "${OPTS[@]}" "$@"

Финальный скрипт запуска rdesktop

#!/bin/bash

WORKAREA=$(xprop -root "_NET_WORKAREA")
WORKAREA_X1=$(echo ${WORKAREA} | awk -F'[, ]+' '{print $3}')
WORKAREA_Y1=$(echo ${WORKAREA} | awk -F'[, ]+' '{print $4}')
WORKAREA_X2=$(echo ${WORKAREA} | awk -F'[, ]+' '{print $5}')
WORKAREA_Y2=$(echo ${WORKAREA} | awk -F'[, ]+' '{print $6}')
WORKAREA_W=$(( ${WORKAREA_X2} - ${WORKAREA_X1} - 2 ))
WORKAREA_H=$(( ${WORKAREA_Y2} - ${WORKAREA_Y1} - 2 ))

unset OPTS
OPTS=("${OPTS[@]}" -u "winxp")
OPTS=("${OPTS[@]}" -p "winxp")
OPTS=("${OPTS[@]}" -T "WindowsXP Workstation")
OPTS=("${OPTS[@]}" -a 24)
OPTS=("${OPTS[@]}" -P)
OPTS=("${OPTS[@]}" -5)
OPTS=("${OPTS[@]}" -g "${WORKAREA_W}x${WORKAREA_H}")
OPTS=("${OPTS[@]}" -r "clipboard:PRIMARYCLIPBOARD")
OPTS=("${OPTS[@]}" -r "sound:local")
OPTS=("${OPTS[@]}" -r "disk:home=${HOME}")
OPTS=("${OPTS[@]}" "127.0.0.1:13389")

daemon \
    --noconfig \
    --umask=0133 \
    -- \
    rdesktop "${OPTS[@]}" "$@"

Комментариев нет:

Отправить комментарий