Домашняя виртуализация. Citrix XenServer vs VMware vSphere ESXi. Часть 2 – 3. Citrix Xenserver. Использование одной клавиатуры в гостевой и хост системах.

xenserver-logo

При запуске железа первым запускается гипервизор, а затем запускаются виртуальные машины. Было бы очень удобно использовать одну клавиатуру как для настройки гипервизора так и для управления основной виртуальной машиной после её запуска.
В отличие от ESXi, XenServer позволяет пробрасывать usb-устройства в виртуальные машины в момент их запуска, а не в момент запуска гипервизора, что очеь удобно. Но всё же есть одно но. После выключения виртуальной машины usb-устройство не подтягивается обратно в гипервизор.
Для решения этой проблемы можно написать скрипт, который будет запускаться при старте гипервизора. Этот скрипт будет проверять статус основной виртуальной машины и, если детектировано выключение, ребиндить usb-устройство.
Для начала определим какое устройство хотим ребиндить. Для этого выполним команду

cat /proc/bus/input/devices

Найдем своё usb-устройство, например “USB Keyboard”, и запомним адрес шины, на которой оно располагается. В моём случае адрес шины устройства 0000:00:1d.0.
Далее необходимо найти драйвер, обслуживающий usb-устройство. Я это делаю по простому, просматривая соответствующие директории в папке /sys/bus/pci/drivers/
В моём случае usb-клавиатура обслуживается драйвером USB1.1 и адрес шины 0000:00:1d.0 был найден в папке /sys/bus/pci/drivers/uhci_hcd/
Теперь определим идентификатор виртуальной машины в которую будет проброшено usb-устройство. Для этого воспользуемся командой

xe vm-list

которая выдаст список всех созданных виртуальных машин. В моем случае идентификатор равен 455551ac-4439-af35-73a3-f283c1ba7363.
Итоговый работающий скрипт выглядит так:

activatedBefore=false;
while :;
do
  sleep 1;

  if ! [[ $(xe vm-list uuid=455551ac-4439-af35-73a3-f283c1ba7363 | grep halted) ]]; then
    activatedBefore=true;
    continue;
  fi 

  if [ "$activatedBefore" = true ]; then
    if ! [[ $(ls /sys/bus/pci/drivers/pciback/ | grep 0000:00:1d.0) ]]; then
      continue;
    fi

    echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/pciback/unbind;
    echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/uhci_hcd/bind;
  fi

  activatedBefore=false;
done

Не мастер писать скрипты. Например, адрес шины и идентификатор ВМ просятся перенестись в параметры. Главное, чтобы вам была ясна идея:
Итак, каждую секунду происходит считывание статуса выбранной ВМ. И, если её статус не halted, считаем что ВМ запущена и прерываем цикл. Как только ВМ останавливает работу и принимает статус halted проверяем присутствует ли адрес шины usb-устройства в списке обслуживаемых драйвером проброса(pciback). Если присутствует, отвязываем его от этого драйвера и привязываем к драйверу uhci.
Ключевые строчки в этом скрипте:

echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/pciback/unbind;
echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/uhci_hcd/bind;

Перед тестированием скрипта их лучше выполнить вручную после завершения работы ВМ, если есть такая возможность, и проверить всё ли впорядке.
Для автозапуска скрипта можно поместить его, напрмер, в файл /etc/init/usb.script выдав ему соответствующие права

chmod 755 /etc/init/usb.script

В следующей статье мы поговорим о багах XenServer.

Leave a Reply

Your email address will not be published. Required fields are marked *