Виберіть свою мову

Два и более рабочих места на одном компьютере - бесплатное решение

 В данной статье рассматривается идея и практическое руководство по создания многопользовательской рабочей станции (multiseat) с использованием виртуализации KVM, с возможностью удаленного управления через libvirt. С помощью этого руководства возможно создать два и более рабочих мест как в офисе, так и дома, которым может потребоваться возможность полного использования графической подсистемы компьютера. Причем можно на одном системном блоке реализовать одновременно работу различных операционных систем Windows, Linux, Mac OS X, остальное по вкусу.

Введение

Желание реализовать возможность совместного использования одного компьютера, хотя бы двуx людей появилась давным-давно. Идея сделать из домашнего или офисного компьютера, как минимум два рабочих места раньше реализовывалась в основном на той же операционной системе со всеми вытекающими недостатками. Трудности возникали особенно тогда, когда одному человеку нравилось работать в windows, а другому в Linux и приходилось кому-то терпеть, если решение было реализовано только через одну ОС. Впрочем были и другие трудности.

Сейчас компьютеры стали более производительные, рост частоты новых процессоров уже нас давно не радует, но зато радует рост ядер. А это значит, что мы в одном системном блоке потенциально уже имеем несколько компьютеров. И тенденция эта будет только расти. Работа нескольких человек с одним компьютером в стандартной конфигурации скоро будет вполне востребованной на рынке и уже сейчас доступна в реализации.

Установка Gentoo

Подготовка
Разметка диска
Разворачивание готового образа и подготовка к chroot
Обживаем новую систему

Настройка

Настройка BIOS

Проверяем, что в BIOS VT-d включён, для Z87 «usb intel XHCI» нужно отключить для проброса USB контролеров.

Настройка звука

usermod -G kvm,audio,pulse-access -d /home/qemu qemu
usermod -G wheel,audio,pulse-access,users testuser
Запустим pulseaudio.

echo 'PULSEAUDIO_SHOULD_NOT_GO_SYSTEMWIDE="1"' >> /etc/conf.d/pulseaudio 
rc-update add pulseaudio default 
/etc/init.d/pulseaudio start
su - testuser 
# C помощью alsamixer выставляем требуемую громкость, если ММ то нажимаем М.
alsamixer
# обратно к root
exit
# сохраняем настройки громкости
/etc/init.d/alsasound save 
/etc/init.d/alsasound start
rc-update add alsasound default
Настройка libvirt

В файл /etc/libvirt/qemu.conf определим пользователя, от которого будет запуск виртуалок

user = "qemu"
group = "qemu"
# Если все будет плохо, то можно раскомментировать
# clear_emulator_capabilities = 0

В момент написания статьи seabios в gentoo 1.7.3, а нам нужен свежий, по этому качаем и распаковываем

cd /etc/libvirt 
wget http://code.coreboot.org/p/seabios/downloads/get/bios.bin-1.7.4.gz 
gzip -d bios.bin-1.7.4.gz

Создадим вспомогательный скрипт для проброса устройств

cat > /etc/libvirt/vfio-bind << "EOF"
#!/bin/sh
for dev in "$@"; do 
  vendor=$(cat /sys/bus/pci/devices/$dev/vendor) 
  device=$(cat /sys/bus/pci/devices/$dev/device)
  if [ -e /sys/bus/pci/devices/$dev/driver ]; then
    echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
  fi                                                                                                         
  echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id
done
EOF
chmod +x /etc/libvirt/vfio-bind

Запускаем lspci и выбираем жертву для ручного проброса

03:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Turks PRO [Radeon HD 6570/7570]
03:00.1 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] Turks/Whistler HDMI Audio [Radeon HD 6000 Series
00:1a.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)

Создадим скрипт проброса конкретной видеокарты

cat > /etc/libvirt/bind-vga-1 << "EOF"
#!/bin/sh                                                                                                    
/etc/libvirt/vfio-bind 0000:03:00.0 0000:03:00.1                                                                    
# ставим права на группу 6. Найти можно здесь /sys/kernel/iommu_groups/6/devices
chown qemu /dev/vfio/6
EOF
chmod +x /etc/libvirt/bind-vga-1
# запускаем
/etc/libvirt/bind-vga-1
# создадим скрипт автозагрузки
cat > /etc/init.d/bind-vga-1 << "EOF"
#!/sbin/runscript                                                                                            
start() {
  ebegin "Starting vfio-bind"
  /etc/libvirt/bind-vga-1
  eend $? "Failed to start vfio-bind"
}
EOF
# если нужно, то в автозагрузку его
rc-update add bind-vga-1 default

Теперь создадим раздел где будет лежать образ виртуальной машины

vcreate -L70G -nwks1 vg

У меня есть машина, где лежат образы уже подготовленных виртуалок с софтом, надеюсь и у Вас такая появится. Как подготовить образ напишу ниже.

ssh Ця електронна адреса захищена від спам-ботів. Вам необхідно увімкнути JavaScript, щоб побачити її..1.3 "dd if=/dev/vg_archive/windows7 bs=1M |gzip -" |gunzip - | dd of=/dev/vg/wks1 bs=1M
Настройка домена

Ниже приведен файл настройки конечной рабочей конфигурации с комментариями.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>wks1</name> 
  <uuid>2811e544-bf4d-baf6-1135-ec5acd139999</uuid>
  <memory unit='KiB'>4145152</memory>
  <currentMemory unit='KiB'>4145152</currentMemory>
  <cpu mode='host-passthrough'/>
  <os>
    <type arch='x86_64' machine='pc-q35-2.0'>hvm</type>
    <loader>/etc/libvirt/bios.bin-1.7.4</loader>
    <boot dev='hd'/>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='localtime'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/qemu-kvm</emulator>
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source dev='/dev/vg/wks1'/>
      <!-- Вначале установки windows нужно использовать следующий target
         <target dev='sda' bus='sata'/>
      -->
      <target dev='vda' bus='virtio'/>
    </disk>
    <!-- секция для CD образов                                                                                            
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/usr/win_7.iso'/>
      <target dev='hdc' bus='sata'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
     -->
    <controller type='pci' index='0' model='pcie-root'>
      <alias name='pcie.0'/>
    </controller>
    <controller type='pci' index='1' model='dmi-to-pci-bridge'>
      <alias name='pci.1'/>
    </controller>
    <controller type='pci' index='2' model='pci-bridge'>
      <alias name='pci.2'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:12:50:01'/>
      <source bridge='br0'/>
      <!-- Вначале установки windows нужно закомментировать модель -->
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/>
    </interface>
    <!-- секция для первоночальной установки windows, через vnc
    <controller type='usb'/>
    <input type='tablet' bus='usb'/>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='5900' autoport='no' listen='192.168.1.2' passwd='mypassword'/>
    -->
    <!-- BEGIN Если устанавливаем по vnс убираем этот блок -->
    <hostdev mode='subsystem' type='pci' managed='yes'>
       <!-- Вместо source1 должно быть source. С хабра-разметкой не могу справится -->
       <source1>
        <address domain='0x0000' bus='0x00' slot='0x1a' function='0x0'/>                                     
      </source1>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x04' function='0x0'/>                            
    </hostdev>
    <!-- END Eсли устанавливаем по vnс убираем этот блок -->
    <sound model='ich9'/>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x08' function='0x0'/>
    </memballoon>
  </devices>
  <seclabel type='none'/>
  <qemu:commandline>
    <qemu:env name="HOME" value="/home/qemu"/>
    <qemu:env name="QEMU_AUDIO_DRV" value="pa"/>
    <!-- BEGIN  Если мы устанавливаем по vnc, то нужно закомментировать этот блок -->
    <qemu:arg value='-vga'/>
    <qemu:arg value='none'/>
    <qemu:arg value='-device'/>
    <qemu:arg value='vfio-pci,host=03:00.0,bus=pcie.0,addr=02.0,x-vga=on'/>
    <!-- END  Если мы устанавливаем по vnc, то нужно закомментировать этот блок -->
  </qemu:commandline>
</domain>

Данную конфигурацию записываем в файл /etc/libvirt/qemu/wks1.xml
Перечитываем файл конфигурации

/etc/init.d/libvirtd restart

Запускаем домен

virsh start wks1
# если все будет хорошо, то можно в автозагрузку добавить
# virsh autostart wks1

Первоначальная установка

Для первоначальной установки записываем нужный iso образ и раскомментируем секцию cdrom. Так же убираем все настройки virtio и пробросы устройств 03:00.0 — видео и 00:1a.0 usb контроллера. Включаем доступ по vnc. После того когда вы систему установите нужно установить драйвера virtio в гостевую OC. Драйвера под windows.
Без драйверов все работает очень медленно.

Известные засады

  • Я встречался с тем, что без полного обновления windows не вставали последние драйвера virtio.
  • Перед тем как ставить драйвер-virtio основного диска, нужно подключить второй пустой диск с уже определенным типом virtio
    lvcreate -nzero -L1M
    
    <disk type='block' device='disk'>
          <driver name='qemu' type='raw' cache='writethrough'/>
          <source dev='/dev/vg/wks1'/>
          <target dev='sda' bus='sata'/>
        </disk>
    <disk type='block' device='disk'>
          <driver name='qemu' type='raw' cache='writethrough'/>
          <source dev='/dev/vg/zero'/>
          <target dev='vda' bus='virtio'/>
        </disk>
    
  • В windows изменение параметров энергосбережения -> настройка перехода в спящий режим -> переводить компьютер в спящий режим ->
    «никогда»

Этот скрипт можно в crontab установить.

cat > /etc/libvirtd/shutdown_if_not_start.sh << "EOF"
#!/bin/sh                                                                                                    
LIST_VM=`virsh list | awk '{if($3=="running")print $2}'|wc -l`                                               
if [ ${LIST_VM} -ne  0 ] ; then                                                                              
  exit 0                                                                                                     
fi                                                                                                           
awk '{if(int($1)>300){exit 0}else{ exit 1}}' /proc/uptime                                                    
if [ $? -ne 0 ]; then                                                                                        
  exit 0                                                                                                     
fi                                                                                                           
/sbin/shutdown -h now
EOF
chmod +x /etc/libvirtd/shutdown_if_not_start.sh

Заключение

Вроде основные моменты описал. Здесь можно найти пути решения, если у Вас валится windows в BSOD. Если вы будете организовывать моментальные снимки, то не забудьте поставить QEMU Guest Agent и научитесь с ним работать.
У нас на боевых компах стоит апач, через скрипт пользователь сам может производить действия с VM с соседнего компьютера или виртуалки. Можно так же реализовать запуск виртуалок по USB ключу.
Уверен, что кто-то сможет эту конфигурацию улучшить. Пожалуйста, напишите об это в комментарии, чтобы помочь остальным.
Данную конфигурацию можно затарить и распространять на другие машины, так же как и образы гостевых OC. Не забудьте после разворачивания хостового имиджа, поправить адреса, названия хостов, интерфейсов и сгенерировать ssh ключи.

habrahabr.ru