📜 ⬆️ ⬇️

Two or more jobs on the same computer - free solution


This article discusses the idea and practical guide to creating a multi-user workstation (multiseat) using KVM virtualization, with the possibility of remote control via libvirt. With this guide, it is possible to create two or more workplaces both in the office and at home, which may require the ability to make full use of the computer’s graphics subsystem. Moreover, it is possible to simultaneously work on different operating systems Windows, Linux, Mac OS X on one system unit, the rest is to the taste.

Introduction


The desire to realize the possibility of sharing one computer, at least two people appeared a long time ago. The idea to make from a home or office computer at least two workplaces used to be implemented mainly on the same operating system with all the ensuing disadvantages. Difficulties arose especially when one person liked to work in windows, and another in Linux and someone had to endure if the solution was implemented only through one OS. However, there were other difficulties.

Now computers have become more productive, the increase in the frequency of new processors has long been unhappy for us, but it pleases the growth of the cores. And this means that we potentially already have several computers in one system unit. And this trend will only grow. The work of several people with one computer in a standard configuration will soon be in demand on the market and is now available for sale.

Gentoo Installation


Training
We download the current livecd and load.
Raise the network. What is the name of the network interface?
ifconfig eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 

For those who love windows, set up a network like this
 net-setup eno1 

I personally got used in the old fashioned way. Register your ip
 ifconfig eno1 192.168.1.2/24 

Set the default router
 route add default gw 192.168.1.1 

We specify our DNS
 echo "nameserver 8.8.8.8" >> /etc/resolv.conf 

We set the password for root
 passwd root 

Run ssh to continue the installation remotely
 /etc/init.d/sshd start 

From your favorite workplace we go via ssh
 ssh root@192.168.1.186 


Disk partitioning
It is assumed that you have one empty disk named / dev / sda
 parted -a opt /dev/sda (parted) mklabel msdos 

Create a section for download. 150M with a very large margin. Maybe we will migrate in the future sections in GPT and put EFI.
 (parted) mkpart primary ext2 1 150M (parted) set 1 boot on 

Everything else will give under lvm
 (parted) mkpart primary 150M -1s (parted) #Is this still acceptable to you? Yes/No? yes (parted) set 2 lvm on (parted) quit 

We need LVM in order to take snapshots of virtual machine disks, without stopping the system, for organizing backup copies. It will also be more convenient to change sections, add new ones.
Partitioning disk for LVM. Sizes put on your taste
 pvcreate /dev/sda2 vgcreate vg /dev/sda2 lvcreate -L 1G -n root vg lvcreate -L 1G -n tmp vg lvcreate -L 5G -n var vg lvcreate -L 10G -n usr vg 

If LVM has already been configured, you need to activate it.
 vgchange -ay 

Format all partitions
 mkfs.ext2 /dev/sda1 mkfs.ext2 /dev/vg/tmp for p in root var usr ; do mkfs.ext4 /dev/vg/$p ; done 

Mounting our future root partition
 mount /dev/vg/root /mnt/gentoo 

Create directories for the rest of the mount points
 cd /mnt/gentoo mkdir boot usr var tmp sys proc dev chmod 1777 tmp 

We mount the remaining sections
 mount /dev/vg/usr /mnt/gentoo/usr mount /dev/vg/tmp /mnt/gentoo/tmp mount /dev/vg/var /mnt/gentoo/var mount /dev/sda2 /mnt/gentoo/boot 


Expanding the finished image and preparing for chroot
 cd /mnt/gentoo 

Downloading the latest system (check the date in the file name)
 wget http://mirror.yandex.ru/gentoo-distfiles/releases/amd64/current-stage3/stage3-amd64-nomultilib-20140123.tar.bz2 

Take the portage. Portage - a description of how to build and install the programs we need.
 wget http://mirror.yandex.ru/gentoo-distfiles/snapshots/portage-latest.tar.bz2 

Unpack it all
 tar xvjpf stage3-amd64-nomultilib-20140123.tar.bz2 tar xvjf portage-latest.tar.bz2 -C /mnt/gentoo/usr 

Copy resolv.conf to the future root partition.
 cp /etc/resolv.conf /mnt/gentoo/etc/resolv.conf 

Mount system partitions
 mount --rbind /dev /mnt/gentoo/dev mount -t proc none /mnt/gentoo/proc mount --rbind /sys /mnt/gentoo/sys 

We get inside the created root partition (future system)
 chroot /mnt/gentoo env-update source /etc/profile 


We live in a new system
 nano /etc/portage/make.conf 

If necessary, change CFLAGS options for the compiler. Compiler options are almost standard except for -march = native (instead of -march = i686), which makes the compiler use all the features of the processor. If the task is to make an iron independent installation, it is better not to use, because when recovering on a new hardware, (possibly) you will have to rebuild the whole world.
USE - lists the globally basic program options that will be installed.
If there are thin clients, add “spice” to USE, if you need to forward USB ports of thin clients, add “usbredir”
 CFLAGS="-O2 -pipe -march=native" #      MAKEOPTS="-j3" USE="bindist mmx sse sse2 -ipv6 unicode device-mapper -X slang udev pulseaudio" GENTOO_MIRRORS=http://mirror.yandex.ru/gentoo-distfiles/ SYNC="rsync://rsync.ru.gentoo.org/gentoo-portage" LINGUAS="ru en" 

Let's write our sections for auto-mount
 cat > /etc/fstab << "EOF" /dev/sda1 /boot ext2 noauto,noatime 1 2 /dev/vg/root / ext4 noatime 0 1 /dev/vg/tmp /tmp ext2 noatime 0 0 /dev/vg/usr /usr ext4 noatime 0 0 /dev/vg/var /var ext4 noatime 0 0 EOF 

Update the portage tree
 emerge --sync 

If you need to change the profile, then it's time
 eselect profile list eselect profile set <> 

Create a network configuration file
 cat > /etc/conf.d/net << "EOF" config_eno1="null" config_br0="192.168.1.2/24" routes_br0="default via 192.168.1.1" bridge_br0="eno1" rc_net_br0_need="net.eno1" ethtool_offload_eno1="gro off" dns_domain="mydomain.ru" dns_servers="8.8.8.8 8.8.4.4" EOF ln -s /etc/init.d/net.lo /etc/init.d/net.eno1 ln -s /etc/init.d/net.lo /etc/init.d/net.br0 

Set a password for root
 passwd root 

Add yourself (testuser) as a user and set a password. Add to the group users, wheel, audio
 useradd -m -G users,wheel,audio -s /bin/bash testuser passwd testuser 

At the time of writing, qemu-1.7.1 was not released yet, so we’ll put two stars to pick up the developer version
 echo "app-emulation/qemu ** ~amd64" >>/etc/portage/package.accept_keywords 

This flag is needed so that pulseaudio works as an independent process. Unfortunately, by default I could not get it to work steadily with libvirt using the variable “nographics_allow_host_audio = 1” in libvirtd.conf. Maybe you will succeed?
 echo "media-sound/pulseaudio -system-wide" >>/etc/portage/make.profile/package.use.mask echo "media-sound/pulseaudio -dbus system-wide" >>/etc/portage/package.use 

Indicate that you will need to build new versions of packages
 for p in sys-kernel/gentoo-sources app-emulation/libvirt sys-apps/dtc sys-firmware/seabios; do echo $p" ~amd64" >>/etc/portage/package.accept_keywords ; done 

Install the necessary programs. The -av key allows you to view the build options, if something does not suit you, you can include the option in the USE variable, which is contained in the /etc/portage/make.conf file. app-misc / mc - if someone is comfortable
 emerge -av gentoo-sources vixie-cron lvm2 genkernel syslog-ng iproute2 libvirt ethtool bridge-utils grub terminus-font radeon-ucode app-misc/mc 

Add programs to startup
 for s in sshd vixie-cron syslog-ng net.br0 libvirtd ; do rc-update add $s default; done 

Build the Linux kernel, and in the sections
> Device Drivers> IOMMU Hardware Support> IOMMU Hardware Support
Mark all asterisks
> Device Drivers> VFIO Non-Privileged userspace driver framework
Mark all asterisks
> Device Drivers> Networking support> Universal TUN / TAP device driver support
Put an asterisk.
Everything else to taste ;-)
 genkernel --lvm --menuconfig all 

Add the flag "dolvm" for autoloading LVM
 nano /etc/default/grub #   GRUB_CMDLINE_LINUX="dolvm" 

Install the Grub loader
 grub2-install /dev/sda grub2-mkconfig -o /boot/grub/grub.cfg 

Configuring localization
 cat /usr/share/i18n/SUPPORTED | grep -E 'ru_RU|en_US' >> /etc/locale.gen && locale-gen 

Copy the new time zone file in / etc / localtime
 cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime 

Configure keyboard switching
 nano /etc/conf.d/keymaps #   dumpkeys_charset="utf8" keymap="-u ru" 

Font in the console will prescribe
 nano /etc/conf.d/consolefont #   consolefont="cyr-sun16" 

Localization of messages
 cat > /etc/env.d/02locale << "EOF" LANG="ru_RU.UTF-8" LC_ALL="ru_RU.UTF-8" LANG="ru_RU.UTF-8" LC_MESSAGES="POSIX" LC_NUMERIC="POSIX" LC_TIME="POSIX" EOF env-update && source /etc/profile rc-update add keymap default rc-update add consolefont default 


If necessary, you can update and rebuild packages with new USE flags.
 emerge -avuDN system world 

Set the host name
 nano /etc/conf.d/hostname hostname="testhost" 

Rule / etc / hosts
 nano /etc/hosts 127.0.0.1 localhost testhost testhost.mydomain.ru 

We are overloaded, if everything is good, then you are lucky ;-) Still, everyone has different iron, maybe something will need to be included in the kernel.
If everything is bad, then we understand the documentation or use google. Documentation in Russian online is enough.

Customization


BIOS setup

We check that the VT-d is enabled in the BIOS, for the Z87, “usb intel XHCI” needs to be disabled for forwarding USB controllers.
')
Sound setting

usermod -G kvm, audio, pulse-access -d / home / qemu qemu
usermod -G wheel, audio, pulse-access, users testuser
Run 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 setup

In the file /etc/libvirt/qemu.conf, we define the user, from which the virtualoks will run
 user = "qemu" group = "qemu" #    ,    # clear_emulator_capabilities = 0 

At the time of writing the article seabios in gentoo 1.7.3, and we need a fresh one, so download and unpack it
 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 


Create a helper script for forwarding devices
 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 

Run lspci and select the victim for manual forwarding.
 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) 

Create a script for forwarding a specific video card
 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 

Now we will create a partition where the virtual machine image will lie
 lvcreate -L70G -nwks1 vg 

I have a machine, where the images of already prepared virtual locks with software are lying, I hope you will have one too. How to prepare an image I will write below.
 ssh root@192.168.1.3 "dd if=/dev/vg_archive/windows7 bs=1M |gzip -" |gunzip - | dd of=/dev/vg/wks1 bs=1M 

Domain Setting


Below is the final configuration configuration file with comments.

 <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> 

We write this configuration to the /etc/libvirt/qemu/wks1.xml file.
Re-read the configuration file
 /etc/init.d/libvirtd restart 

We start the domain
 virsh start wks1 #    ,      # virsh autostart wks1 

Initial installation


For the initial installation, write the desired iso image and uncomment the cdrom section. We also remove all virtio settings and device 03: 00.0 rollouts - video and 00: 1a.0 usb controller. We include access on vnc. After that, when you install the system, you need to install the virtio driver in the guest OS. Drivers for windows.
Without drivers, everything works very slowly.

Known ambush




This script can be installed in the 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 

Conclusion


Like the highlights described. Here you can find solutions if you have windows crashes into BSOD. If you organize snapshots, do not forget to install the QEMU Guest Agent and learn how to work with it.
We have an Apache on our combat computers; through the script, the user himself can perform actions from the VM from a nearby computer or virtual machine. You can also implement the launch of virtualok via USB key.
I am sure that someone will be able to improve this configuration. Please write about it in the comments to help others.
This configuration can be packaged and distributed to other machines, as well as images of guest OCs. Do not forget after expanding the host image, correct addresses, host names, interfaces and generate ssh keys.
About spice and ARM, if it is interesting to write separately.

Source: https://habr.com/ru/post/210668/


All Articles