User:Wacek/brudnopis QEMU

From ArchWiki
Jump to navigation Jump to search

Według QEMU about page, „QEMU to ogólny emulator i wirtualizator maszyn typu open source”.

Gdy jest używany jako emulator maszyny, QEMU może uruchamiać systemy operacyjne i programy stworzone dla jednego komputera (np. ARM) na innym komputerze (np. Komputerze x86). Dzięki zastosowaniu tłumaczenia dynamicznego osiąga bardzo dobrą wydajność.

QEMU może używać innych hiperwizorów, takich jak Xen lub KVM, aby używać rozszerzeń procesora (HVM). Gdy jest używany jako wirtualizator, QEMU osiąga niemal natywną wydajność, wykonując kod gościa bezpośrednio na CPU hosta.

Contents

Instalacja

Install qemu (lub qemu-headless dla wersji bez GUI) i poniżej opcjonalnych pakietów dla swoich potrzeb:

Graficzne nakładki na QEMU

W przeciwieństwie do innych programów do wirtualizacji, takich jak VirtualBox i VMware, QEMU nie zapewnia GUI do zarządzania maszynami wirtualnymi (innymi niż okno, które pojawia się podczas uruchamiania maszyny wirtualnej), ani nie zapewnia sposobu tworzenia trwałych maszyn wirtualnych z zapisanymi ustawieniami. Wszystkie parametry do uruchomienia maszyny wirtualnej muszą być określone w wierszu polecenia przy każdym uruchomieniu, chyba że utworzono niestandardowy skrypt do uruchomienia maszyny wirtualnej.

Libvirt zapewnia wygodny sposób zarządzania maszynami wirtualnymi QEMU. Zobacz list of libvirt clients dla dostępnych frontonów.

Inne interfejsy GUI dla QEMU:

  • AQEMU — QEMU GUI written in Qt5.
https://github.com/tobimensch/aqemu || aqemuAUR

Tworzenie nowego zwirtualizowanego systemu

Tworzenie obrazu dysku twardego

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: If I get the man page right the raw format only allocates the full size if the filesystem does not support "holes" or it is explicitly told to preallocate. See man qemu-img in section Notes. (Discuss in User talk:Wacek/brudnopis QEMU#)
Tip: więcej informacji na temat obrazów QEMU można znaleźć w QEMU Wikibook

Aby uruchomić QEMU, potrzebujesz obrazu dysku twardego, chyba że uruchamiasz system na żywo z dysku CD-ROM lub sieci (i nie robisz tego, aby zainstalować system operacyjny na obrazie dysku twardego). Obraz dysku twardego to plik, który przechowuje zawartość emulowanego dysku twardego.

Obraz dysku twardego może być surowy, dzięki czemu jest dosłownie bajt po bajcie taki sam, jak gość, i zawsze będzie wykorzystywał pełną pojemność dysku twardego gościa na hoście. Ta metoda zapewnia najmniejszy narzut we/wy, ale może zmarnować dużo miejsca, ponieważ nieużywane miejsce na gościu nie może być wykorzystane na hoście.

Alternatywnie, obraz dysku twardego może mieć format taki jak qcow2, który przydziela miejsce do pliku obrazu tylko wtedy, gdy system operacyjny gościa faktycznie zapisuje te sektory na swoim wirtualnym dysku twardym. Obraz pojawia się jako pełny rozmiar w systemie operacyjnym gościa, nawet jeśli może on zajmować bardzo mało miejsca w systemie hosta. Ten format obrazu obsługuje również funkcję migawek QEMU (zobacz #Creating and managing snapshots via the monitor console dla szczegółów). Jednak użycie tego formatu zamiast 'raw prawdopodobnie wpłynie na wydajność.

QEMU udostępnia polecenie qemu-img do tworzenia obrazów dysków twardych. Na przykład, aby utworzyć obraz 4 GB w formacie raw:

$ qemu-img create -f raw image_file 4G

Zamiast tego możesz użyć -f qcow2, aby utworzyć dysk qcow2.

Note: Możesz także po prostu utworzyć obraz raw', tworząc plik o wymaganym rozmiarze za pomocą dd lub fallocate.

.

Warning: Jeśli przechowujesz obrazy dysku twardego w systemie plików Btrfs, przed utworzeniem obrazów należy rozważyć wyłączenie opcji Copy-on-Write do katalogu przed utworzeniem jakichkolwiek obrazów.

Overlay storage images

Możesz raz utworzyć obraz pamięci (obraz 'backing' image)) i poprosić QEMU o zachowanie mutacji tego obrazu w obrazie nakładki. Pozwala to przywrócić poprzedni stan tego obrazu pamięci. Możesz przywrócić, tworząc nowy obraz nakładki w czasie, który chcesz przywrócić, na podstawie oryginalnego backing image.

Aby utworzyć obraz nakładki, wydaj polecenie takie jak:

$ qemu-img create -o backing_file=img1.raw,backing_fmt=raw -f qcow2 img1.cow

Następnie możesz uruchomić maszynę wirtualną QEMU w zwykły sposób (zobacz #Running virtualized system):

$ qemu-system-x86_64 img1.cow

backing image pozostanie nienaruszony, a mutacje w tym magazynie zostaną zapisane w pliku obrazu nakładki.

Gdy zmienia się ścieżka do backing image, wymagana jest naprawa.

Warning: Bezwzględna ścieżka do systemu plików obrazu kopii zapasowej jest przechowywana w (binarnym) pliku obrazu nakładki. Zmiana ścieżki obrazu podkładu wymaga pewnego wysiłku.

Upewnij się, że ścieżka oryginalnego obrazu podkładu nadal prowadzi do tego obrazu. W razie potrzeby utwórz dowiązanie symboliczne przy oryginalnej ścieżce do nowej ścieżki. Następnie wydaj polecenie takie jak:

$ qemu-img rebase -b /new/img1.raw /new/img1.cow

Według własnego uznania możesz alternatywnie wykonać „niebezpieczną” bazę, w której stara ścieżka do obrazu podkładu nie jest sprawdzana:

$ qemu-img rebase -u -b /new/img1.raw /new/img1.cow

Zmiana rozmiaru obrazu

Warning: Zmiana rozmiaru obrazu zawierającego rozruchowy system plików NTFS może uniemożliwić uruchomienie systemu operacyjnego zainstalowanego na nim. Zaleca się, aby najpierw utworzyć kopię zapasową.

Plik wykonywalny qemu-img ma opcję zmiany rozmiaru, która umożliwia łatwą zmianę rozmiaru obrazu dysku twardego. Działa zarówno dla raw, jak i qcow2. Na przykład, aby zwiększyć przestrzeń obrazu o 10 GB, uruchom:

$ qemu-img resize disk_image +10G

Po powiększeniu obrazu dysku musisz użyć systemu plików i narzędzi do partycjonowania wewnątrz maszyny wirtualnej, aby faktycznie zacząć korzystać z nowej przestrzeni. Podczas zmniejszania obrazu dysku należy najpierw zmniejszyć przydzielone systemy plików i rozmiary partycji za pomocą systemu plików i narzędzi do partycjonowania w maszynie wirtualnej, a następnie odpowiednio zmniejszyć obraz dysku, w przeciwnym razie zmniejszenie obrazu dysku spowoduje utrata danych! W przypadku gościa systemu Windows otwórz panel sterowania „twórz i formatuj partycje dysku twardego”.

Konwertowanie obrazu

Możesz przekonwertować obraz na inne formaty przy użyciu qemu-img convert. Ten przykład pokazuje, jak przekonwertować 'raw obraz na qcow2:

$ qemu-img convert -f raw -O qcow2 input.img output.qcow2

Nie spowoduje to usunięcia oryginalnego pliku wejściowego.

Przygotowanie nośnika instalacyjnego

Aby zainstalować system operacyjny na obrazie dysku, potrzebujesz nośnika instalacyjnego (np. Dysku optycznego, napędu USB lub obrazu ISO) dla systemu operacyjnego. Nośnika instalacyjnego nie należy montować, ponieważ QEMU uzyskuje bezpośredni dostęp do nośnika.

Tip: Jeśli używasz dysku optycznego, dobrym pomysłem jest najpierw zrzucić nośnik do pliku, ponieważ zarówno poprawia to wydajność, jak i nie wymaga bezpośredniego dostępu do urządzeń (to znaczy, możesz uruchomić QEMU jako zwykły użytkownik bez konieczności zmienić uprawnienia dostępu do pliku urządzenia nośnika). Na przykład, jeśli węzeł urządzenia CD-ROM ma nazwę /dev/cdrom możesz zrzucić go do pliku za pomocą polecenia:
$ dd if=/dev/cdrom of=cd_image.iso bs=4k

Instalowanie systemu operacyjnego

Po raz pierwszy będziesz musiał uruchomić emulator. Aby zainstalować system operacyjny na obrazie dysku, musisz podłączyć zarówno obraz dysku, jak i nośnik instalacyjny do maszyny wirtualnej i uruchomić go z nośnika instalacyjnego.

Na przykład na gościach i386, aby zainstalować z rozruchowego pliku ISO jako CD-ROM i surowy obraz dysku:

$ qemu-system-x86_64 -cdrom iso_image -boot order=d -drive file=disk_image,format=raw

Zobacz qemu(1) aby uzyskać więcej informacji o ładowaniu innych typów nośników (takich jak dyskietka, obrazy dysków lub dyski fizyczne) i #Running virtualized system dla innych przydatnych opcji.

Po zakończeniu instalacji systemu operacyjnego obraz QEMU można uruchomić bezpośrednio (patrz #Running virtualized system).

Note: Domyślnie tylko 128 MB pamięci jest przypisane do urządzenia. Ilość pamięci można regulować przełącznikiem -m, na przykład -m 512M lub -m 2G.
Tip:
  • Zamiast podawania opcji -boot order=x, niektórzy użytkownicy mogą czuć się bardziej komfortowo, korzystając z menu rozruchowego: -boot menu=on przynajmniej podczas konfiguracji i eksperymentowania.
  • Jeśli musisz wymienić dyskietki lub dyski CD w ramach procesu instalacji, możesz użyć monitora maszyny QEMU (naciśnij Ctrl+Alt+2 w oknie maszyny wirtualnej), aby usunąć i podłączyć urządzenia pamięci masowej do maszyny wirtualnej. Wpisz blok informacji, aby zobaczyć urządzenia blokowe, i użyj polecenia zmiany, aby zamienić urządzenie. Naciśnij Ctrl+Alt+1 aby wrócić do maszyny wirtualnej.

Uruchamianie zwirtualizowanego systemu

Pliki binarne qemu-system-* * (na przykład qemu-system-i386 lub qemu-system-x86_64, w zależności od architektury gościa) są używane do uruchamiania zwirtualizowanego gościa. Wykorzystanie jest:

$ qemu-system-x86_64 options disk_image

Opcje są takie same dla wszystkich plików binarnych qemu-system-* *, patrz qemu(1), aby uzyskać dokumentację wszystkich opcji.

Domyślnie QEMU wyświetla wyjście wideo maszyny wirtualnej w oknie. Należy pamiętać o jednym: kiedy klikniesz w oknie QEMU, wskaźnik myszy zostanie złapany. Aby go zwolnić, naciśnij Ctrl+Alt+g.

Warning: QEMU nigdy nie powinien być uruchamiany jako root. Jeśli musisz uruchomić go w skrypcie jako root, powinieneś użyć opcji -runas , aby QEMU upuściło uprawnienia roota.

Włączanie KVM

KVM musi być obsługiwany przez procesor i jądro, a niezbędne kernel modules muszą zostać załadowane. Aby uzyskać więcej informacji, zobacz KVM.

Aby uruchomić QEMU w trybie KVM, dołącz opcję -enable-kvm do dodatkowych opcji uruchamiania. Aby sprawdzić, czy KVM jest włączony dla działającej maszyny wirtualnej, wprowadź #QEMU monitor za pomocą Ctrl+Alt+2 i wpisz info kvm.

Note:
  • Argument accel=kvm -machine jest równoważny opcji -enable-kvm
  • Jeśli uruchomisz maszynę wirtualną za pomocą narzędzia GUI i doświadczysz bardzo niskiej wydajności, powinieneś sprawdzić poprawność obsługi KVM, ponieważ QEMU może wracać do emulacji oprogramowania.
  • KVM musi być włączony, aby poprawnie uruchomić Windows 7 i Windows 8 bez niebieskiego ekranu.

Enabling IOMMU (Intel VT-d/AMD-Vi) support

Najpierw włącz IOMMU, patrz PCI passthrough via OVMF#Setting up IOMMU.

Dodaj -device intel-iommu aby utworzyć urządzenie IOMMU:

$ qemu-system-x86_64 -enable-kvm -machine q35 -device intel-iommu -cpu host ..
Note: W systemach opartych na procesorach Intel tworzenie urządzenia IOMMU u gościa QEMU z opcją -device intel-iommu wyłączy transmisję PCI z błędem:
Device at bus pcie.0 addr 09.0 requires iommu notifier which is currently not supported by intel-iommu emulation
Podczas gdy dodawanie parametru jądra intel_iommu=on nadal potrzebne do ponownego mapowania IO (np. PCI passthrough with vfio-pci), -device intel-iommu nie powinien być ustawiony, jeśli wymagane jest PCI PCI passsthrough.

Udostępnianie danych między gospodarzem a gościem

Sieć

Dane mogą być współużytkowane przez system operacyjny hosta i gościa przy użyciu dowolnego protokołu sieciowego, który może przesyłać pliki, takiego jak NFS, SMB, NBD, HTTP, FTP lub SSH, pod warunkiem, że sieć została odpowiednio skonfigurowana i włączone odpowiednie usługi.

Domyślna sieć w trybie użytkownika umożliwia gościowi dostęp do systemu operacyjnego hosta pod adresem IP 10.0.2.2. Wszystkie serwery uruchomione w systemie operacyjnym hosta, takie jak serwer SSH lub serwer SMB, będą dostępne pod tym adresem IP. Tak więc na gościach można montować katalogi wyeksportowane na hoście przez SMB lub NFS albo uzyskać dostęp do serwera HTTP hosta itp. System operacyjny hosta nie będzie miał dostępu do serwerów działających na systemie gościa, ale może to zrobić z innymi konfiguracjami sieci (patrz #Tap networking with QEMU)

Przekierowanie portów QEMU

QEMU może przekazywać porty z hosta do gościa, aby umożliwić np. łączenie z hosta do serwera SSH działającego na gościu.

Na przykład, aby powiązać port 10022 na hoście z portem 22 (SSH) na gościu, uruchom QEMU za pomocą polecenia:

$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::10022-:22

Upewnij się, że sshd działa na gościu i połącz się z:

$ ssh guest-user@localhost -p10022

QEMU's built-in SMB server

Dokumentacja QEMU mówi, że ma „wbudowany” serwer SMB, ale tak naprawdę uruchamia Samba z automatycznie wygenerowanym plikiem smb.confznajdującym się w /tmp/qemu-smb.random_string i udostępnia go gościowi pod innym adresem IP adres (domyślnie 10.0.2.4). Działa to tylko w przypadku sieci użytkowników i jest przydatne, gdy nie chcesz uruchamiać normalnej usługi Samba na hoście, do której gość może również uzyskać dostęp, jeśli skonfigurowałeś dla niej udziały.

Tylko jeden katalog może być ustawiony jako współdzielony z opcją smb=, ale dodanie większej liczby katalogów (nawet gdy maszyna wirtualna jest uruchomiona) może być tak proste, jak utworzenie dowiązań symbolicznych w katalogu współdzielonym, jeśli QEMU skonfigurowało SMB do podążania za dowiązaniami symbolicznymi. Nie robi tego, ale konfigurację działającego serwera SMB można zmienić zgodnie z poniższym opisem.

Aby włączyć tę funkcję, uruchom QEMU za pomocą polecenia:

$ qemu-system-x86_64 disk_image -net nic -net user,smb=shared_dir_path

gdzie shared_dir_path to katalog, który chcesz udostępnić między gościem a hostem.

Następnie u gościa będzie można uzyskać dostęp do udostępnionego katalogu na hoście 10.0.2.4 o nazwie udziału „qemu”. Na przykład w Eksploratorze Windows można przejść do \\10.0.2.4\qemu.

Note:
  • Jeśli korzystasz z opcji udostępniania wiele razy, takich jak -net user,smb=shared_dir_path1 -net user,smb=shared_dir_path2 lub -net user,smb=shared_dir_path1,smb=shared_dir_path2 to będzie udostępniać tylko ostatnią zdefiniowaną.
  • Jeśli nie możesz uzyskać dostępu do folderu współdzielonego, a system-gość to Windows, sprawdź, czy NetBIOS protocol is enabled i czy zapora sieciowa nie blokuje ports używanych przez protokół NetBIOS.
  • Jeśli nie możesz uzyskać dostępu do folderu współdzielonego, a systemem-gościem jest Windows 10 Enterprise lub Education lub Windows Server 2016, enable guest access.

Jednym ze sposobów udostępniania wielu katalogów oraz dodawania lub usuwania ich podczas działania maszyny wirtualnej jest udostępnianie pustego katalogu i tworzenie / usuwanie dowiązań symbolicznych do katalogów w katalogu współdzielonym. Aby to zadziałało, konfigurację działającego serwera SMB można zmienić za pomocą następującego skryptu, który umożliwia również wykonywanie plików na gościu, które nie są ustawione jako pliki wykonywalne na hoście:

#!/bin/bash
eval $(ps h -C smbd -o pid,args | grep /tmp/qemu-smb | gawk '{print "pid="$1";conf="$6}')
echo "[global]
allow insecure wide links = yes
[qemu]
follow symlinks = yes
wide links = yes
acl allow execute always = yes" >> $conf
# in case the change is not detected automatically:
smbcontrol --configfile=$conf $pid reload-config

Można to zastosować do uruchomionego serwera uruchomionego przez qemu tylko po pierwszym połączeniu gościa z dyskiem sieciowym. Alternatywą dla tej metody jest dodanie dodatkowych udziałów do pliku konfiguracyjnego w następujący sposób:

echo "[myshare]
path=another_path
read only=no
guest ok=yes
force user=username" >> $conf

Ten udział będzie dostępny dla gościa jako \\10.0.2.4\myshare.

Using filesystem passthrough and VirtFS

Zobacz QEMU documentation.

Montowanie partycji gościa na hoście

Przydatne może być zamontowanie obrazu dysku w systemie hosta, może to być sposób przesyłania plików do iz gościa. Należy to zrobić, gdy maszyna wirtualna nie jest uruchomiona.

The procedure to mount the drive on the host depends on the type of qemu image, raw or qcow2. We detail thereafter the steps to mount a drive in the two formats in

Procedura montowania napędu na hoście zależy od typu obrazu qemu, raw lub qcow2. Następnie szczegółowo opisujemy kroki, aby zamontować dysk w dwóch formatach w #Mounting a partition from a raw image i#Mounting a partition from a qcow2 image. Pełna dokumentacja patrz QEMU/Mounting an image on the host.

Warning: You must make sure to unmount the partitions before running the virtual machine again. Otherwise, data corruption is very likely to occur.

Montowanie partycji z surowego obrazu

Możliwe jest montowanie partycji, które znajdują się w surowym pliku obrazu dysku, poprzez skonfigurowanie ich jako urządzeń pętli zwrotnej.

Z ręcznym określaniem przesunięcia bajtu

Jednym ze sposobów zamontowania partycji obrazu dysku jest zamontowanie obrazu dysku z pewnym przesunięciem za pomocą polecenia takiego jak poniżej:

# mount -o loop,offset=32256 disk_image mountpoint

Opcja offset=32256jest faktycznie przekazywana do programu losetup w celu skonfigurowania urządzenia zwrotnego, które rozpoczyna się od przesunięcia bajtu 32256 pliku i kontynuuje do końca. To urządzenie sprzężenia zwrotnego jest następnie montowane. Możesz także użyć opcji sizelimit , aby określić dokładny rozmiar partycji, ale zwykle nie jest to konieczne.

W zależności od obrazu dysku potrzebna partycja może nie rozpocząć się z przesunięciem 32256. Uruchom fdisk -l disk_image aby zobaczyć partycje na obrazie. fdisk podaje początkowe i końcowe przesunięcia w sektorach 512-bajtowych, więc pomnóż przez 512, aby uzyskać prawidłowe przesunięcie do przekazania do mount.

With loop module autodetecting partitions

Sterownik pętli systemu Linux faktycznie obsługuje partycje w urządzeniach z pętlą zwrotną, ale jest domyślnie wyłączony. Aby go włączyć, wykonaj następujące czynności:

  • Pozbądź się wszystkich urządzeń loopback devices (odmontuj wszystkie zamontowane obrazy itp.).
  • Zwolnij moduł jądra pętli i załaduj go zestawem parametrów max_part=15 . Dodatkowo maksymalna liczba urządzeń pętli może być kontrolowana za pomocą parametru max_loop.
Tip: Możesz umieścić wpis w /etc/modprobe.d, aby za każdym razem ładować moduł pętli z max_part=15, lub możesz umieścić loop.max_part=15w wierszu poleceń jądra, w zależności od tego, czy masz moduł loop.ko wbudowany w jądro lub nie.

Skonfiguruj obraz jako loopback device:

# losetup -f -P disk_image

Następnie, jeśli stworzone urządzenie to /dev/loop0, automatycznie zostaną utworzone dodatkowe urządzenia /dev/loop0pX jest numerem partycji. Te loopback devices partycji można montować bezpośrednio. Na przykład:

# mount /dev/loop0p1 mountpoint

Aby zamontować obraz dysku za pomocą udisksctl, zobacz Udisks#Mount loop devices.

With kpartx

kpartx z pakietu multipath-tools może odczytać tablicę partycji na urządzeniu i utworzyć nowe urządzenie dla każdej partycji. Na przykład:

# kpartx -a disk_image

Spowoduje to skonfigurowanie urządzenia loopback device i utworzenie niezbędnych urządzeń partycji w /dev/mapper/.

Montowanie partycji z obrazu qcow2

Użyjemy qemu-nbd, który pozwala używać protokołu NBD (network block device) do udostępniania obrazu dysku.

Najpierw musimy załadować moduł nbd:

# modprobe nbd max_part=16

Następnie możemy udostępnić dysk i utworzyć wpisy urządzenia:

# qemu-nbd -c /dev/nbd0 /path/to/image.qcow2

Odkryj partycje:

# partprobe /dev/nbd0

fdisk może być użyty do uzyskania informacji dotyczących różnych partycji w nbd0:

# fdisk -l /dev/nbd0
Disk /dev/nbd0: 25.2 GiB, 27074281472 bytes, 52879456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xa6a4d542

Device      Boot   Start      End  Sectors  Size Id Type
/dev/nbd0p1 *       2048  1026047  1024000  500M  7 HPFS/NTFS/exFAT
/dev/nbd0p2      1026048 52877311 51851264 24.7G  7 HPFS/NTFS/exFAT

Następnie zamontuj dowolną partycję obrazu dysku, na przykład partycję 2:

# mount /dev/nbd0p2 mountpoint

Po użyciu ważne jest odmontowanie obrazu i cofnięcie poprzednich kroków, tj. Odmontowanie partycji i odłączenie urządzenia nbd:

  1. umount mountpoint
  2. qemu-nbd -d /dev/nbd0

Używanie dowolnej rzeczywistej partycji jako pojedynczej partycji podstawowej obrazu dysku twardego

Czasami możesz chcieć użyć jednej ze swoich partycji systemowych z poziomu QEMU. Użycie surowej partycji dla maszyny wirtualnej poprawi wydajność, ponieważ operacje odczytu i zapisu nie przechodzą przez warstwę systemu plików na hoście fizycznym. Taka partycja zapewnia również sposób udostępniania danych między hostem a gościem.

W Arch Linux pliki urządzeń dla surowych partycji są domyślnie własnością root i grupy dysków. Jeśli chcesz, aby użytkownik inny niż root mógł czytać i zapisywać na surowej partycji, musisz zmienić właściciela pliku urządzenia partycji na tego użytkownika.

Warning:
  • Chociaż jest to możliwe, nie jest zalecane zezwalanie maszynom wirtualnym na zmianę krytycznych danych w systemie hosta, takich jak root
  • Nie wolno montować systemu plików na partycji do odczytu i zapisu na hoście i gościu w tym samym czasie. W przeciwnym razie nastąpi uszkodzenie danych.

Po wykonaniu tej czynności możesz dołączyć partycję do maszyny wirtualnej QEMU jako dysk wirtualny.

Jednak sprawy są nieco bardziej skomplikowane, jeśli chcesz mieć całą maszynę wirtualną zawartą na partycji. W takim przypadku nie byłoby pliku obrazu dysku, który faktycznie uruchomiłby maszynę wirtualną, ponieważ nie można zainstalować programu ładującego na partycji, która sama jest sformatowana jako system plików, a nie jako urządzenie podzielone na partycje z MBR. Taką maszynę wirtualną można uruchomić albo przez ręczne określenie kernel i initrd, albo przez symulację dysku z MBR za pomocą Device-mapper, liniowego RAID lub Linux Network Block Device.

By specifying kernel and initrd manually

QEMU obsługuje bezpośrednie ładowanie Linux kernels i init ramdisks init, tym samym omijając bootloadery, takie jak GRUB. Następnie można go uruchomić z partycją fizyczną zawierającą główny system plików jako dysk wirtualny, który nie wydaje się być partycjonowany. Odbywa się to poprzez wydanie polecenia podobnego do następującego:

Note: W tym przykładzie wykorzystywane są obrazy hosta, a nie gościa. Jeśli chcesz użyć obrazów gościa, albo mount /dev/sda3 tylko do odczytu (w celu ochrony systemu plików przed hostem) i określ /full/path/to/images lub użyj hakowania kexec w gościu, aby ponownie załadować jądro gościa (wydłuża czas uruchamiania).
$ qemu-system-x86_64 -kernel /boot/vmlinuz-linux -initrd /boot/initramfs-linux.img -append root=/dev/sda /dev/sda3

W powyższym przykładzie partycją fizyczną używaną dla głównego systemu plików gościa jest /dev/sda3 na hoście, ale pojawia się jako /dev/sda na gościu.

Możesz oczywiście określić dowolne jądro i initrd, a nie tylko te, które są dostarczane z Arch Linux.

Jeśli do opcji -append należy przekazać wiele kernel parameters należy je podać za pomocą pojedynczych lub podwójnych cudzysłowów. Na przykład:

... -append 'root=/dev/sda1 console=ttyS0'

Symuluj dysk wirtualny za pomocą MBR

Bardziej skomplikowanym sposobem korzystania z maszyny wirtualnej przy użyciu partycji fizycznej, przy jednoczesnym zachowaniu tej partycji jako systemu plików, a nie tylko tak, że partycja gościa jest partycją tak, jakby była dyskiem, jest symulacja MBR dla niej, aby można ją było uruchomić za pomocą programu ładującego, takiego jak GRUB.

W poniższych przypadkach załóżmy, że masz zwykłą, odmontowaną partycję /dev/hdaN z jakimś systemem plików, który chcesz dołączyć do obrazu dysku QEMU. Sztuką jest dynamiczne dodawanie głównego rekordu rozruchowego (MBR) do rzeczywistej partycji, którą chcesz osadzić w obrazie dysku surowego QEMU. Mówiąc bardziej ogólnie, partycja może być dowolną częścią większego symulowanego dysku, w szczególności urządzeniem blokowym, które symuluje oryginalny dysk fizyczny, ale udostępnia /dev/hdaN maszynie wirtualnej.

Dysk wirtualny tego typu może być reprezentowany przez plik VMDK, który zawiera odniesienia do (kopii) MBR i partycji, ale QEMU nie obsługuje tego formatu VMDK. Na przykład dysk wirtualny utworzony przez

$ VBoxManage internalcommands createrawvmdk -filename /path/to/file.vmdk -rawdisk /dev/hda

zostanie odrzucony przez QEMU z komunikatem o błędzie

Unsupported image type 'partitionedDevice'

Zauważ, że VBoxManage tworzy dwa pliki, file.vmdk i file-pt.vmdk, przy czym ten ostatni jest kopią MBR, na którą wskazuje plik tekstowy file.vmdk. Operacje odczytu poza partycją docelową lub MBR dawałyby zera, a zapisane dane byłyby odrzucane.

Mapowanie urządzeń

Metoda podobna do użycia pliku deskryptora VMDK używa mapera urządzeń do dodania urządzenia pętli dołączonego do pliku MBR do partycji docelowej. W przypadku, gdy nie potrzebujemy, aby nasz dysk wirtualny miał taki sam rozmiar jak oryginał, najpierw tworzymy plik do przechowywania MBR:

$ dd if=/dev/zero of=/path/to/mbr count=2048

Tutaj tworzony jest plik 1 MB (2048 * 512 bajtów) zgodnie z zasadami wyrównywania partycji stosowanymi przez nowoczesne narzędzia do partycjonowania dysku. W celu zapewnienia zgodności ze starszym oprogramowaniem do partycjonowania może być wymagane 63 sektory zamiast 2048. MBR potrzebuje tylko jednego 512-bajtowego bloku, dodatkowe wolne miejsce można wykorzystać na partycję rozruchową systemu BIOS, aw przypadku hybrydowego schematu partycji na tabelę partycji GUID. Następnie dołączamy urządzenie pętlowe do pliku MBR:

# losetup --show -f /path/to/mbr
/dev/loop0

W tym przykładzie wynikowym urządzeniem jest /dev/loop0. Maper urządzeń jest teraz używany do dołączenia do MBR i partycji:

# echo "0 2048 linear /dev/loop0 0
2048 `blockdev --getsz /dev/hdaN` linear /dev/hdaN 0" | dmsetup create qemu

Wynikowy /dev/mapper/qemu jest tym, co wykorzystamy jako surowy obraz dysku QEMU. Wymagane są dodatkowe kroki, aby utworzyć tablicę partycji (patrz sekcja opisująca użycie liniowego RAID na przykład) i kod modułu ładującego na dysku wirtualnym (który będzie przechowywany w /path/to/mbr)..

Poniższa konfiguracja to przykład, w którym pozycja /dev/hdaN na dysku wirtualnym ma być taka sama jak na dysku fizycznym, a reszta dysku jest ukryta, z wyjątkiem MBR, który jest dostarczany jako kopia:

# dd if=/dev/hda count=1 of=/path/to/mbr
# loop=`losetup --show -f /path/to/mbr`
# start=`blockdev --report /dev/hdaN | tail -1 | awk '{print $5}'`
# size=`blockdev --getsz /dev/hdaN`
# disksize=`blockdev --getsz /dev/hda`
# echo "0 1 linear $loop 0
1 $((start-1)) zero
$start $size linear /dev/hdaN 0
$((start+size)) $((disksize-start-size)) zero" | dmsetup create qemu

Tabela dostarczona jako standardowe wejście do dmsetup ma podobny format jak tabela w pliku deskryptora VDMK utworzonym przez VBoxManage i może być alternatywnie ładowana z pliku z dmsetup create qemu --table table_file. Dla maszyny wirtualnej dostępny jest tylko /dev/hdaN, podczas gdy reszta dysku twardego odczytuje jako zera i odrzuca zapisane dane, z wyjątkiem pierwszego sektora. Możemy wydrukować tabelę dla /dev/mapper/qemu z dmsetup table qemu (użyj udevadm info -rq name /sys/dev/block/major:minor, aby przetłumaczyć major:minor na odpowiednią nazwę /dev/blockdevice). Użyj dmsetup remove qemu i losetup -d $loop, aby usunąć utworzone urządzenia.

Sytuacja, w której ten przykład byłby przydatny, to istniejąca instalacja systemu Windows XP w konfiguracji z kilkoma systemami rozruchowymi i być może hybrydowy schemat partycjonowania (na fizycznym sprzęcie Windows XP może być jedynym systemem operacyjnym, który korzysta z tabeli partycji MBR, podczas gdy bardziej nowoczesne systemy operacyjne zainstalowane na tym samym komputerze mogłyby korzystać z tabeli partycji GUID). Windows XP obsługuje profile sprzętowe, dzięki czemu ta sama instalacja może być używana na przemian z różnymi konfiguracjami sprzętowymi (w tym przypadku goły metal vs. wirtualny), a Windows musi instalować sterowniki dla nowo wykrytego sprzętu tylko raz dla każdego profilu. Zauważ, że w tym przykładzie kod modułu ładującego rozruchu w skopiowanym MBR musi zostać zaktualizowany, aby bezpośrednio załadować system Windows XP z /dev/hdaN zamiast próbować uruchomić moduł ładujący rozruchu z wieloma systemami rozruchowymi (taki jak GRUB) obecny w oryginalnym systemie. Alternatywnie, kopia partycji rozruchowej zawierającej instalację modułu ładującego może być zawarta na dysku wirtualnym w taki sam sposób, jak MBR.

Liniowy RAID

Możesz to również zrobić za pomocą programowego RAID w trybie liniowym (potrzebujesz sterownika jądra linear.ko ) i loopback device:

Najpierw utworzysz mały plik do przechowywania MBR:

$ dd if=/dev/zero of=/path/to/mbr count=32

Tutaj tworzony jest plik 16 KB (32 * 512 bajtów). Ważne jest, aby nie uczynić go zbyt małym (nawet jeśli MBR potrzebuje tylko jednego 512-bajtowego bloku), ponieważ im mniejszy, tym mniejszy musi być rozmiar programowego urządzenia RAID, co może mieć wpływ na wydajność. Następnie ustaw loopback device na plik MBR:

# losetup -f /path/to/mbr

Załóżmy, że wynikowym urządzeniem jest /dev/loop0 ponieważ nie korzystalibyśmy już z innych pętli zwrotnych. Następnym krokiem jest utworzenie „scalonego” obrazu dysku MBR + /dev/hdaN przy użyciu programowego RAID:

# modprobe linear
# mdadm --build --verbose /dev/md0 --chunk=16 --level=linear --raid-devices=2 /dev/loop0 /dev/hdaN

Wynikowy plik /dev/md0 będzie używany jako surowy obraz dysku QEMU (nie zapomnij ustawić uprawnień, aby emulator mógł uzyskać do niego dostęp). Ostatnim (i nieco trudnym) krokiem jest ustawienie konfiguracji dysku (geometrii dysku i tabeli partycji), aby punkt początkowy partycji podstawowej w MBR był zgodny z punktem /dev/hdaN wewnątrz /dev/md0 (przesunięcie dokładnie 16 * 512 = 16384 bajtów w tym przykładzie). Zrób to za pomocą fdisk na komputerze hosta, a nie w emulatorze: domyślna procedura wykrywania surowego dysku z QEMU często powoduje przesunięcia nieobliczalne w kilobajtach (takie jak 31,5 KB, jak w poprzedniej sekcji), które nie mogą być zarządzane przez programowy kod RAID. Dlatego od gospodarza:

# fdisk /dev/md0

Naciśnij X, aby wejść do menu eksperta. Ustaw liczbę „s” wektorów na ścieżkę, aby rozmiar jednego cylindra odpowiadał rozmiarowi pliku MBR. Dla dwóch głowic i rozmiaru sektora 512 liczba sektorów na ścieżkę powinna wynosić 16, więc otrzymujemy cylindry o rozmiarze 2x16x512 = 16k.

Teraz naciśnij R, aby wrócić do menu głównego.

Naciśnij P i sprawdź, czy rozmiar cylindra wynosi teraz 16k.

Teraz utwórz pojedynczą partycję podstawową odpowiadającą /dev/hdaN. Powinien on zaczynać się od cylindra 2 i kończyć się na końcu dysku (zauważ, że liczba cylindrów różni się teraz od tego, co było po wejściu na fdisk.

Na koniec zapisz wynik do pliku: gotowe. Masz teraz partycję, którą możesz zamontować bezpośrednio z hosta, a także część obrazu dysku QEMU:

$ qemu-system-x86_64 -hdc /dev/md0 [...]

Możesz oczywiście bezpiecznie ustawić dowolny bootloader na tym obrazie dysku za pomocą QEMU, pod warunkiem, że oryginalna partycja /dev/hdaN zawiera niezbędne narzędzia.

Network Block Device

Zamiast metod opisanych powyżej możesz użyć nbd-server (z pakietu nbd), aby utworzyć opakowanie MBR dla QEMU.

Zakładając, że już skonfigurowałeś plik opakowujący MBR jak wyżej, zmień jego nazwę na wrapper.img.0. Następnie utwórz link symboliczny o nazwie wrapper.img.1 w tym samym katalogu, wskazując na twoją partycję. Następnie umieść następujący skrypt w tym samym katalogu:

#!/bin/sh
dir="$(realpath "$(dirname "$0")")"
cat >wrapper.conf <<EOF
[generic]
allowlist = true
listenaddr = 127.713705
port = 10809

[wrap]
exportname = $dir/wrapper.img
multifile = true
EOF

nbd-server \
    -C wrapper.conf \
    -p wrapper.pid \
    "$@"

Sufiksy .0 i .1 są niezbędne; resztę można zmienić. Po uruchomieniu powyższego skryptu (który może być potrzebny jako root, aby upewnić się, że serwer nbd ma dostęp do partycji), możesz uruchomić QEMU za pomocą:

qemu-system-x86_64 -drive file=nbd:127.713705:10809:exportname=wrap [...]

Networking

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: Network topologies (sections #Host-only networking, #Internal networking and info spread out across other sections) should not be described alongside the various virtual interfaces implementations, such as #User-mode networking, #Tap networking with QEMU, #Networking with VDE2. (Discuss in User talk:Wacek/brudnopis QEMU#)

Wydajność sieci wirtualnej powinna być lepsza w urządzeniach z tap devices i bridges niż w sieci w trybie użytkownika lub vde, ponieważ urządzenia z tap devices i bridges są implementowane w jądrze.

Ponadto wydajność sieci można poprawić, przypisując maszynom wirtualnym urządzenie sieciowe virtio zamiast domyślnej emulacji karty sieciowej e1000. Aby uzyskać więcej informacji, zobacz #Installing virtio drivers

Zastrzeżenie adresu na poziomie łącza

Podając QEMU argument -net nic, domyślnie przypisuje maszynie wirtualnej interfejs sieciowy z adresem na poziomie łącza 52:54:00:12:34:56. Jednak w przypadku korzystania z bridged networking z wieloma maszynami wirtualnymi istotne jest, aby każda maszyna wirtualna miała unikalny adres na poziomie łącza (MAC) po stronie maszyny wirtualnej urządzenia tap device. W przeciwnym razie bridge nie będzie działał poprawnie, ponieważ będzie odbierał pakiety z wielu źródeł, które mają ten sam adres na poziomie łącza. Ten problem występuje nawet wtedy, gdy same urządzenia dotykowe mają unikalne adresy na poziomie łącza, ponieważ źródłowy adres na poziomie łącza nie jest przepisywany, gdy pakiety przechodzą przez urządzenie.

Upewnij się, że każda maszyna wirtualna ma unikalny adres na poziomie łącza, ale zawsze powinna zaczynać się od 52:54:. :. Użyj następującej opcji, zamień X na dowolną cyfrę szesnastkową:

$ qemu-system-x86_64 -net nic,macaddr=52:54:XX:XX:XX:XX -net vde disk_image

Generowanie unikalnych adresów na poziomie łącza można wykonać na kilka sposobów:

  1. Ręcznie określ unikalny adres na poziomie łącza dla każdej karty sieciowej. Zaletą jest to, że serwer DHCP przydziela ten sam adres IP za każdym razem, gdy maszyna wirtualna jest uruchamiana, ale nie można jej używać w przypadku dużej liczby maszyn wirtualnych.
  2. Generuj losowy adres na poziomie łącza przy każdym uruchomieniu maszyny wirtualnej. Praktycznie zerowe prawdopodobieństwo kolizji, ale wadą jest to, że serwer DHCP przydziela za każdym razem inny adres IP. Możesz użyć następującego polecenia w skrypcie, aby wygenerować losowy adres na poziomie łącza w zmiennej macaddr:
    printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
    qemu-system-x86_64 -net nic,macaddr="$macaddr" -net vde disk_image
  3. Użyj następującego skryptu qemu-mac-hasher.py, aby wygenerować adres na poziomie łącza z nazwy maszyny wirtualnej za pomocą funkcji skrótu. Biorąc pod uwagę, że nazwy maszyn wirtualnych są unikalne, metoda ta łączy zalety wyżej wymienionych metod: generuje ten sam adres na poziomie łącza przy każdym uruchomieniu skryptu, ale zachowuje praktycznie zerowe prawdopodobieństwo kolizji.
    qemu-mac-hasher.py
    #!/usr/bin/env python
    
    import sys
    import zlib
    
    if len(sys.argv) != 2:
        print("usage: %s <VM Name>" % sys.argv[0])
        sys.exit(1)
    
    crc = zlib.crc32(sys.argv[1].encode("utf-8")) & 0xffffffff
    crc = str(hex(crc))[2:]
    print("52:54:%s%s:%s%s:%s%s:%s%s" % tuple(crc))
    

    W skrypcie możesz użyć na przykład:

    vm_name="VM Name"
    qemu-system-x86_64 -name "$vm_name" -net nic,macaddr=$(qemu-mac-hasher.py "$vm_name") -net vde disk_image
    

Sieć w trybie użytkownika

Domyślnie, bez żadnych argumentów -netdev, QEMU użyje sieci w trybie użytkownika z wbudowanym serwerem DHCP. Twoje maszyny wirtualne otrzymają adres IP po uruchomieniu klienta DHCP i będą mogły uzyskać dostęp do sieci hosta fizycznego za pomocą maskowania adresów IP przez QEMU.

Warning: Działa to tylko z protokołami TCP i UDP, więc ICMP, w tym ping, nie będzie działać. Nie używaj polecenia ping do testowania łączności sieciowej. Aby ping działał w gościu, zobacz Sysctl#Allow unprivileged users to create IPPROTO_ICMP sockets.

Ta domyślna konfiguracja umożliwia twoim maszynom wirtualnym łatwy dostęp do Internetu, pod warunkiem, że host jest z nim podłączony, ale maszyny wirtualne nie będą bezpośrednio widoczne w sieci zewnętrznej, ani maszyny wirtualne nie będą mogły ze sobą rozmawiać, jeśli uruchomisz więcej niż jedną jednocześnie.

Tryb sieci użytkownika QEMU może oferować więcej możliwości, takich jak wbudowane serwery TFTP lub SMB, przekierowywanie portów hosta do gościa (na przykład w celu umożliwienia połączeń SSH z gościem) lub podłączanie gości do sieci VLAN, aby mogli ze sobą rozmawiać. Więcej informacji można znaleźć w dokumentacji QEMU na temat flagi użytkownika -net user

Jednak tryb sieciowy użytkownika ma ograniczenia zarówno pod względem użyteczności, jak i wydajności. Bardziej zaawansowane konfiguracje sieciowe wymagają użycia tap devices lub innych metod.

Note: Jeśli system hosta używa systemd-networkd, pamiętaj o dowiązaniu symbolicznym pliku /etc/resolv.conf zgodnie z opisem w systemd-networkd#Required services and setup, w przeciwnym razie wyszukiwanie DNS w systemie gościa nie będzie działać.

Tap networking with QEMU

Tap devices to funkcja jądra systemu Linux, która umożliwia tworzenie wirtualnych interfejsów sieciowych, które wyglądają jak prawdziwe interfejsy sieciowe. Pakiety wysyłane do interfejsu tap są dostarczane do programu przestrzeni użytkownika, takiego jak QEMU, który związał się z interfejsem.

QEMU może używać sieci wirtualnej na maszynie wirtualnej, aby pakiety wysyłane do interfejsu wirtualnego były wysyłane na maszynę wirtualną i pojawiały się jako pochodzące z interfejsu sieciowego (zwykle interfejsu Ethernet) na maszynie wirtualnej. I odwrotnie, wszystko, co maszyna wirtualna wysyła przez interfejs sieciowy, pojawi się na tap interface.

Urządzenia Tap devices są obsługiwane przez sterowniki bridge Linuksa, więc możliwe jest łączenie ze sobą urządzeń ztap i ewentualnie z innymi interfejsami hosta, takimi jak eth0. Jest to pożądane, jeśli chcesz, aby Twoje maszyny wirtualne mogły ze sobą rozmawiać lub jeśli chcesz, aby inne maszyny w Twojej sieci LAN mogły komunikować się z maszynami wirtualnymi.


Warning: If you bridge together tap device and some host interface, such as eth0, your virtual machines will appear directly on the external network, which will expose them to possible attack. Depending on what resources your virtual machines have access to, you may need to take all the precautions you normally would take in securing a computer to secure your virtual machines. If the risk is too great, virtual machines have little resources or you set up multiple virtual machines, a better solution might be to use host-only networking and set up NAT. In this case you only need one firewall on the host instead of multiple firewalls for each guest.

Jak wskazano w sekcji dotyczącej sieci w trybie użytkownika, urządzenia z tap oferują wyższą wydajność sieci niż w trybie użytkownika. Jeśli system operacyjny gościa obsługuje sterownik sieciowy virtio, wydajność sieci również znacznie wzrośnie. Zakładając użycie urządzenia tap0, że sterownik virtio jest używany na gościu i że nie są używane żadne skrypty pomagające w uruchomieniu / zatrzymaniu sieci, następny jest częścią polecenia qemu, które należy zobaczyć:

-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no

Ale jeśli już używasz urządzenia z tap ze sterownikiem sieciowym virtio, możesz nawet zwiększyć wydajność sieci, włączając vhost, na przykład:

-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on

Zobacz http://www.linux-kvm.com/content/how-maximize-virtio-net-performance-vhost-net po więcej informacji.

Sieć tylko dla hosta

Jeśli bridge otrzyma adres IP i ruch przeznaczony dla niego jest dozwolony, ale do mostu nie jest podłączony żaden rzeczywisty interfejs (np. eth0)), wówczas maszyny wirtualne będą mogły komunikować się ze sobą i systemem hosta. Nie będą jednak mogli rozmawiać z kimkolwiek w sieci zewnętrznej, pod warunkiem, że nie skonfigurujesz maskowania IP na hoście fizycznym. Ta konfiguracja nazywana jest siecią wyłącznie hostową przez inne oprogramowanie do wirtualizacji, takie jak VirtualBox.

Tip:
  • Jeśli chcesz skonfigurować maskowanie IP, np. NAT dla maszyn wirtualnych, patrz Internet sharing#Enable NAT.
  • Zobacz [Network bridge]] aby uzyskać informacje na temat tworzenia bridge.
  • Możesz chcieć mieć serwer DHCP uruchomiony na interfejsie mostka do obsługi sieci wirtualnej. Na przykład, aby użyć podsieci 172.20.0.1/16z podsieć z dnsmasq jako serwerem DHCP:
# ip addr add 172.20.0.1/16 dev br0
# ip link set br0 up
# dnsmasq --interface=br0 --bind-interfaces --dhcp-range=172.20.0.2,172.20.255.254

Sieć wewnętrzna

Jeśli nie podasz mostowi adresu IP i dodasz regułę iptables, aby zrzucić cały ruch do mostu w łańcuchu INPUT, wówczas maszyny wirtualne będą mogły rozmawiać ze sobą, ale nie z hostem fizycznym lub siecią zewnętrzną. Ta konfiguracja nazywana jest siecią wewnętrzną przez inne oprogramowanie do wirtualizacji, takie jak VirtualBox. Musisz przypisać statyczne adresy IP maszynom wirtualnym lub uruchomić serwer DHCP na jednym z nich.

Domyślnie iptables upuszcza pakiety w bridge network. Może być konieczne użycie takiej reguły iptables, aby zezwolić na pakiety w bridged network:

# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

Bridged networking using qemu-bridge-helper

Note: This method is available since QEMU 1.1, see http://wiki.qemu.org/Features/HelperNetworking.

This method does not require a start-up script and readily accommodates multiple taps and multiple bridges. It uses /usr/lib/qemu/qemu-bridge-helper binary, which allows creating tap devices on an existing bridge.

Tip: See Network bridge for information on creating bridge.

First, create a configuration file containing the names of all bridges to be used by QEMU:

/etc/qemu/bridge.conf
allow bridge0
allow bridge1
...

Now start the VM. The most basic usage would be:

$ qemu-system-x86_64 -net nic -net bridge,br=bridge0 [...]

With multiple taps, the most basic usage requires specifying the VLAN for all additional NICs:

$ qemu-system-x86_64 -net nic -net bridge,br=bridge0 -net nic,vlan=1 -net bridge,vlan=1,br=bridge1 [...]

Creating bridge manually

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: This section needs serious cleanup and may contain out-of-date information. (Discuss in User talk:Wacek/brudnopis QEMU#)
Tip: Since QEMU 1.1, the network bridge helper can set tun/tap up for you without the need for additional scripting. See #Bridged networking using qemu-bridge-helper.

The following describes how to bridge a virtual machine to a host interface such as eth0, which is probably the most common configuration. This configuration makes it appear that the virtual machine is located directly on the external network, on the same Ethernet segment as the physical host machine.

We will replace the normal Ethernet adapter with a bridge adapter and bind the normal Ethernet adapter to it.

  • Install bridge-utils, which provides brctl to manipulate bridges.
  • Enable IPv4 forwarding:
# sysctl net.ipv4.ip_forward=1

To make the change permanent, change net.ipv4.ip_forward = 0 to net.ipv4.ip_forward = 1 in /etc/sysctl.d/99-sysctl.conf.

  • Load the tun module and configure it to be loaded on boot. See Kernel modules for details.
  • Now create the bridge. See Bridge with netctl for details. Remember to name your bridge as br0, or change the scripts below to your bridge's name.
  • Create the script that QEMU uses to bring up the tap adapter with root:kvm 750 permissions:
/etc/qemu-ifup
#!/bin/sh

echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /usr/bin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /usr/bin/brctl addif br0 $1
sleep 2
  • Create the script that QEMU uses to bring down the tap adapter in /etc/qemu-ifdown with root:kvm 750 permissions:
/etc/qemu-ifdown
#!/bin/sh

echo "Executing /etc/qemu-ifdown"
sudo /usr/bin/ip link set $1 down
sudo /usr/bin/brctl delif br0 $1
sudo /usr/bin/ip link delete dev $1
  • Use visudo to add the following to your sudoers file:
Cmnd_Alias      QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl
%kvm     ALL=NOPASSWD: QEMU
  • You launch QEMU using the following run-qemu script:
run-qemu
#!/bin/bash
USERID=$(whoami)

# Get name of newly created TAP device; see https://bbs.archlinux.org/viewtopic.php?pid=1285079#p1285079
precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
sudo /usr/bin/ip tuntap add user $USERID mode tap
postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))

# This line creates a random MAC address. The downside is the DHCP server will assign a different IP address each time
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
# Instead, uncomment and edit this line to set a static MAC address. The benefit is that the DHCP server will assign the same IP address.
# macaddr='52:54:be:36:42:a9'

qemu-system-x86_64 -net nic,macaddr=$macaddr -net tap,ifname="$IFACE" $*

sudo ip link set dev $IFACE down &> /dev/null
sudo ip tuntap del $IFACE mode tap &> /dev/null

Then to launch a VM, do something like this

$ run-qemu -hda myvm.img -m 512
/etc/sysctl.d/10-disable-firewall-on-bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

Run sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf to apply the changes immediately.

See the libvirt wiki and Fedora bug 512206. If you get errors by sysctl during boot about non-existing files, make the bridge module load at boot. See Kernel modules#Automatic module loading with systemd.

Alternatively, you can configure iptables to allow all traffic to be forwarded across the bridge by adding a rule like this:

-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

Network sharing between physical device and a Tap device through iptables

Merge-arrows-2.pngThis article or section is a candidate for merging with Internet_sharing.Merge-arrows-2.png

Notes: Duplication, not specific to QEMU. (Discuss in User talk:Wacek/brudnopis QEMU#)

Bridged networking works fine between a wired interface (Eg. eth0), and it is easy to setup. However if the host gets connected to the network through a wireless device, then bridging is not possible.

See Network bridge#Wireless interface on a bridge as a reference.

One way to overcome that is to setup a tap device with a static IP, making linux automatically handle the routing for it, and then forward traffic between the tap interface and the device connected to the network through iptables rules.

See Internet sharing as a reference.

There you can find what is needed to share the network between devices, included tap and tun ones. The following just hints further on some of the host configurations required. As indicated in the reference above, the client needs to be configured for a static IP, using the IP assigned to the tap interface as the gateway. The caveat is that the DNS servers on the client might need to be manually edited if they change when changing from one host device connected to the network to another.

To allow IP forwarding on every boot, one need to add the following lines to sysctl configuration file inside /etc/sysctl.d:

net.ipv4.ip_forward = 1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1

The iptables rules can look like:

# Forwarding from/to outside
iptables -A FORWARD -i ${INT} -o ${EXT_0} -j ACCEPT
iptables -A FORWARD -i ${INT} -o ${EXT_1} -j ACCEPT
iptables -A FORWARD -i ${INT} -o ${EXT_2} -j ACCEPT
iptables -A FORWARD -i ${EXT_0} -o ${INT} -j ACCEPT
iptables -A FORWARD -i ${EXT_1} -o ${INT} -j ACCEPT
iptables -A FORWARD -i ${EXT_2} -o ${INT} -j ACCEPT
# NAT/Masquerade (network address translation)
iptables -t nat -A POSTROUTING -o ${EXT_0} -j MASQUERADE
iptables -t nat -A POSTROUTING -o ${EXT_1} -j MASQUERADE
iptables -t nat -A POSTROUTING -o ${EXT_2} -j MASQUERADE

The prior supposes there are 3 devices connected to the network sharing traffic with one internal device, where for example:

INT=tap0
EXT_0=eth0
EXT_1=wlan0
EXT_2=tun0

The prior shows a forwarding that would allow sharing wired and wireless connections with the tap device.

The forwarding rules shown are stateless, and for pure forwarding. One could think of restricting specific traffic, putting a firewall in place to protect the guest and others. However those would decrease the networking performance, while a simple bridge does not include any of that.

Bonus: Whether the connection is wired or wireless, if one gets connected through VPN to a remote site with a tun device, supposing the tun device opened for that connection is tun0, and the prior iptables rules are applied, then the remote connection gets also shared with the guest. This avoids the need for the guest to also open a VPN connection. Again, as the guest networking needs to be static, then if connecting the host remotely this way, one most probably will need to edit the DNS servers on the guest.

Networking with VDE2

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: This section needs serious cleanup and may contain out-of-date information. (Discuss in User talk:Wacek/brudnopis QEMU#)

What is VDE?

VDE stands for Virtual Distributed Ethernet. It started as an enhancement of uml_switch. It is a toolbox to manage virtual networks.

The idea is to create virtual switches, which are basically sockets, and to "plug" both physical and virtual machines in them. The configuration we show here is quite simple; However, VDE is much more powerful than this, it can plug virtual switches together, run them on different hosts and monitor the traffic in the switches. You are invited to read the documentation of the project.

The advantage of this method is you do not have to add sudo privileges to your users. Regular users should not be allowed to run modprobe.

Basics

VDE support can be installed via the vde2 package.

In our config, we use tun/tap to create a virtual interface on my host. Load the tun module (see Kernel modules for details):

# modprobe tun

Now create the virtual switch:

# vde_switch -tap tap0 -daemon -mod 660 -group users

This line creates the switch, creates tap0, "plugs" it, and allows the users of the group users to use it.

The interface is plugged in but not configured yet. To configure it, run this command:

# ip addr add 192.168.100.254/24 dev tap0

Now, you just have to run KVM with these -net options as a normal user:

$ qemu-system-x86_64 -net nic -net vde -hda [...]

Configure networking for your guest as you would do in a physical network.

Tip: You might want to set up NAT on tap device to access the internet from the virtual machine. See Internet sharing#Enable NAT for more information.

Startup scripts

Example of main script starting VDE:

/etc/systemd/scripts/qemu-network-env
#!/bin/sh
# QEMU/VDE network environment preparation script

# The IP configuration for the tap device that will be used for
# the virtual machine network:

TAP_DEV=tap0
TAP_IP=192.168.100.254
TAP_MASK=24
TAP_NETWORK=192.168.100.0

# Host interface
NIC=eth0

case "$1" in
  start)
        echo -n "Starting VDE network for QEMU: "

        # If you want tun kernel module to be loaded by script uncomment here
	#modprobe tun 2>/dev/null
	## Wait for the module to be loaded
 	#while ! lsmod | grep -q "^tun"; do echo "Waiting for tun device"; sleep 1; done

        # Start tap switch
        vde_switch -tap "$TAP_DEV" -daemon -mod 660 -group users

        # Bring tap interface up
        ip address add "$TAP_IP"/"$TAP_MASK" dev "$TAP_DEV"
        ip link set "$TAP_DEV" up

        # Start IP Forwarding
        echo "1" > /proc/sys/net/ipv4/ip_forward
        iptables -t nat -A POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE
        ;;
  stop)
        echo -n "Stopping VDE network for QEMU: "
        # Delete the NAT rules
        iptables -t nat -D POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE

        # Bring tap interface down
        ip link set "$TAP_DEV" down

        # Kill VDE switch
        pgrep vde_switch | xargs kill -TERM
        ;;
  restart|reload)
        $0 stop
        sleep 1
        $0 start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac
exit 0

Example of systemd service using the above script:

/etc/systemd/system/qemu-network-env.service
[Unit]
Description=Manage VDE Switch

[Service]
Type=oneshot
ExecStart=/etc/systemd/scripts/qemu-network-env start
ExecStop=/etc/systemd/scripts/qemu-network-env stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Change permissions for qemu-network-env to be executable

# chmod u+x /etc/systemd/scripts/qemu-network-env

You can start qemu-network-env.service as usual.

Alternative method

If the above method does not work or you do not want to mess with kernel configs, TUN, dnsmasq, and iptables you can do the following for the same result.

# vde_switch -daemon -mod 660 -group users
# slirpvde --dhcp --daemon

Then, to start the VM with a connection to the network of the host:

$ qemu-system-x86_64 -net nic,macaddr=52:54:00:00:EE:03 -net vde disk_image

VDE2 Bridge

Based on quickhowto: qemu networking using vde, tun/tap, and bridge graphic. Any virtual machine connected to vde is externally exposed. For example, each virtual machine can receive DHCP configuration directly from your ADSL router.

Basics

Remember that you need tun module and bridge-utils package.

Create the vde2/tap device:

# vde_switch -tap tap0 -daemon -mod 660 -group users
# ip link set tap0 up

Create bridge:

# brctl addbr br0

Add devices:

# brctl addif br0 eth0
# brctl addif br0 tap0

And configure bridge interface:

# dhcpcd br0

Startup scripts

All devices must be set up. And only the bridge needs an IP address. For physical devices on the bridge (e.g. eth0), this can be done with netctl using a custom Ethernet profile with:

/etc/netctl/ethernet-noip
Description='A more versatile static Ethernet connection'
Interface=eth0
Connection=ethernet
IP=no

The following custom systemd service can be used to create and activate a VDE2 tap interface for use in the users user group.

/etc/systemd/system/vde2@.service
[Unit]
Description=Network Connectivity for %i
Wants=network.target
Before=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/vde_switch -tap %i -daemon -mod 660 -group users
ExecStart=/usr/bin/ip link set dev %i up
ExecStop=/usr/bin/ip addr flush dev %i
ExecStop=/usr/bin/ip link set dev %i down

[Install]
WantedBy=multi-user.target

And finally, you can create the bridge interface with netctl.

Shorthand configuration

If you are using QEMU with various networking options a lot, you probably have created a lot of -netdev and -device argument pairs, which gets quite repetitive. You can instead use the -nic argument to combine -netdev and -device together, so that, for example, these arguments:

-netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on -device virtio-net,netdev=network0

...become:

-nic tap,ifname=tap0,script=no,downscript=no,vhost=on,model=virtio-net

Notice the lack of network IDs, and that the device was created with model=.... The first half of the -nic parameters are -netdev parameters, whereas the second half (after model=...) are related with the device. The same parameters (for example, smb=...) are used. There is also a special parameter for -nic which completely disables the default (user-mode) networking:

-nic none

See QEMU networking documentation for more information on parameters you can use.

Graphic card

QEMU can emulate a standard graphic card text mode using -curses command line option. This allows to type text and see text output directly inside a text terminal.

QEMU can emulate several types of VGA card. The card type is passed in the -vga type command line option and can be std, qxl, vmware, virtio, cirrus or none.

std

With -vga std you can get a resolution of up to 2560 x 1600 pixels without requiring guest drivers. This is the default since QEMU 2.2.

qxl

QXL is a paravirtual graphics driver with 2D support. To use it, pass the -vga qxl option and install drivers in the guest. You may want to use #SPICE for improved graphical performance when using QXL.

On Linux guests, the qxl and bochs_drm kernel modules must be loaded in order to gain a decent performance.

Default VGA memory size for QXL devices is 16M which is sufficient to drive resolutions approximately up to QHD (2560x1440). To enable higher resolutions, increase vga_memmb.

vmware

Although it is a bit buggy, it performs better than std and cirrus. Install the VMware drivers xf86-video-vmware and xf86-input-vmmouse for Arch Linux guests.

virtio

virtio-vga / virtio-gpu is a paravirtual 3D graphics driver based on virgl. Currently a work in progress, supporting only very recent (>= 4.4) Linux guests with mesa (>=11.2) compiled with the option gallium-drivers=virgl.

To enable 3D acceleration on the guest system select this vga with -vga virtio and enable the opengl context in the display device with -display sdl,gl=on or -display gtk,gl=on for the sdl and gtk display output respectively. Successful configuration can be confirmed looking at the kernel log in the guest:

$ dmesg | grep drm 
[drm] pci: virtio-vga detected
[drm] virgl 3d acceleration enabled

cirrus

The cirrus graphical adapter was the default before 2.2. It should not be used on modern systems.

none

This is like a PC that has no VGA card at all. You would not even be able to access it with the -vnc option. Also, this is different from the -nographic option which lets QEMU emulate a VGA card, but disables the SDL display.

SPICE

The SPICE project aims to provide a complete open source solution for remote access to virtual machines in a seamless way.

Enabling SPICE support on the host

The following is an example of booting with SPICE as the remote desktop protocol, including the support for copy and paste from host:

$ qemu-system-x86_64 -vga qxl -device virtio-serial-pci -spice port=5930,disable-ticketing -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent

The parameters have the following meaning:

  1. -device virtio-serial-pci adds a virtio-serial device
  2. -spice port=5930,disable-ticketing set TCP port 5930 for spice channels listening and allow client to connect without authentication
  3. -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 opens a port for spice vdagent in the virtio-serial device,
  4. -chardev spicevmc,id=spicechannel0,name=vdagent adds a spicevmc chardev for that port. It is important that the chardev= option of the virtserialport device matches the id= option given to the chardev option (spicechannel0 in this example). It is also important that the port name is com.redhat.spice.0, because that is the namespace where vdagent is looking for in the guest. And finally, specify name=vdagent so that spice knows what this channel is for.
Tip: Using Unix sockets instead of TCP ports does not involve using network stack on the host system, so it is reportedly better for performance. Example:
$ qemu-system-x86_64 -vga qxl -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent -spice unix,addr=/tmp/vm_spice.socket,disable-ticketing

Connecting to the guest with a SPICE client

A SPICE client is necessary to connect to the guest. In Arch, the following clients are available:

virt-viewer — SPICE client recommended by the protocol developers, a subset of the virt-manager project.

https://virt-manager.org/ || virt-viewer

spice-gtk — SPICE GTK client, a subset of the SPICE project. Embedded into other applications as a widget.

https://www.spice-space.org/ || spice-gtk

For clients that run on smartphone or on other platforms, refer to the Other clients section in spice-space download.

Manually running a SPICE client

One way of connecting to the guest is to manually run the SPICE client using $ remote-viewer spice+unix:///tmp/vm_spice.socket or $ spicy --uri="spice+unix:///tmp/vm_spice.socket", depending on the desired client. Since QEMU in SPICE mode acts similarly to a remote desktop server, it may be more convenient to run QEMU in daemon mode with the -daemonize parameter.

Tip: To connect to the guest through SSH tunelling, the following type of command can be used:
$ ssh -fL 5999:localhost:5930 my.domain.org sleep 10; spicy -h 127.0.0.1 -p 5999

This example connects spicy to the local port 5999 which is forwarded through SSH to the guest's SPICE server located at the address my.domain.org, port 5930. Note the -f option that requests ssh to execute the command sleep 10 in the background. This way, the ssh session runs while the client is active and auto-closes once the client ends.

Running a SPICE client with QEMU

QEMU can automatically start a SPICE client with an appropriate socket, if the display is set to SPICE with the -display spice-app parameter. This will use the system's default SPICE client as the viewer, determined by your mimeapps.list files.

Enabling SPICE support on the guest

For Arch Linux guests, for improved support for multiple monitors or clipboard sharing, the following packages should be installed:

  • spice-vdagent: Spice agent xorg client that enables copy and paste between client and X-session and more. Enable spice-vdagentd.service after installation.
  • xf86-video-qxl: Xorg X11 qxl video driver

For guests under other operating systems, refer to the Guest section in spice-space download.

Password authentication with SPICE

If you want to enable password authentication with SPICE you need to remove disable-ticketing from the -spice argument and instead add password=yourpassword. For example:

$ qemu-system-x86_64 -vga qxl -spice port=5900,password=yourpassword -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent

Your SPICE client should now ask for the password to be able to connect to the SPICE server.

TLS encrypted communication with SPICE

You can also configure TLS encryption for communicating with the SPICE server. First, you need to have a directory which contains the following files (the names must be exactly as indicated):

  • ca-cert.pem: the CA master certificate.
  • server-cert.pem: the server certificate signed with ca-cert.pem.
  • server-key.pem: the server private key.

An example of generation of self-signed certificates with your own generated CA for your server is shown in the Spice User Manual.

Afterwards, you can run QEMU with SPICE as explained above but using the following -spice argument: -spice tls-port=5901,password=yourpassword,x509-dir=/path/to/pki_certs, where /path/to/pki_certs is the directory path that contains the three needed files shown earlier.

It is now possible to connect to the server using virt-viewer:

$ remote-viewer spice://hostname?tls-port=5901 --spice-ca-file=/path/to/ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all

Keep in mind that the --spice-host-subject parameter needs to be set according to your server-cert.pem subject. You also need to copy ca-cert.pem to every client to verify the server certificate.

Tip: You can get the subject line of the server certificate in the correct format for --spice-host-subject (with entries separated by commas) using the following command:
$ openssl x509 -noout -subject -in server-cert.pem | cut -d' ' -f2- | sed 's/\///' | sed 's/\//,/g'

The equivalent spice-gtk command is:

$ spicy -h hostname -s 5901 --spice-ca-file=ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all

VNC

One can add the -vnc :X option to have QEMU redirect the VGA display to the VNC session. Substitute X for the number of the display (0 will then listen on 5900, 1 on 5901...).

$ qemu-system-x86_64 -vnc :0

An example is also provided in the #Starting QEMU virtual machines on boot section.

Warning: The default VNC server setup does not use any form of authentication. Any user can connect from any host.

Basic password authentication

An access password can be setup easily by using the password option. The password must be indicated in the QEMU monitor and connection is only possible once the password is provided.

$ qemu-system-x86_64 -vnc :0,password -monitor stdio

In the QEMU monitor, password is set using the command change vnc password and then indicating the password.

The following command line directly runs vnc with a password:

$ printf "change vnc password\n%s\n" MYPASSWORD | qemu-system-x86_64 -vnc :0,password -monitor stdio
Note: The password is limited to 8 characters and can be guessed through brute force attack. More elaborated protection is strongly recommended for public network.

Audio

Host

The audio driver used by QEMU is set with the QEMU_AUDIO_DRV environment variable:

$ export QEMU_AUDIO_DRV=pa

Run the following command to get QEMU's configuration options related to PulseAudio:

$ qemu-system-x86_64 -audio-help | awk '/Name: pa/' RS=

The listed options can be exported as environment variables, for example:

$ export QEMU_PA_SINK=alsa_output.pci-0000_04_01.0.analog-stereo.monitor
$ export QEMU_PA_SOURCE=input

Guest

To get list of the supported emulation audio drivers:

$ qemu-system-x86_64 -soundhw help

To use e.g. hda driver for the guest use the -soundhw hda command with QEMU.

Note: Video graphic card emulated drivers for the guest machine may also cause a problem with the sound quality. Test one by one to make it work. You can list possible options with qemu-system-x86_64 -h | grep vga.

Installing virtio drivers

QEMU offers guests the ability to use paravirtualized block and network devices using the virtio drivers, which provide better performance and lower overhead.

  • A virtio block device requires the option -drive for passing a disk image, with parameter if=virtio:
$ qemu-system-x86_64 -boot order=c -drive file=disk_image,if=virtio
  • Almost the same goes for the network:
$ qemu-system-x86_64 -nic user,model=virtio-net-pci
  • To get a list of available network models:
$ qemu-system-x86_64 -nic model=help
Note: This will only work if the guest machine has drivers for virtio devices. Linux does, and the required drivers are included in Arch Linux, but there is no guarantee that virtio devices will work with other operating systems.

Preparing an (Arch) Linux guest

To use virtio devices after an Arch Linux guest has been installed, the following modules must be loaded in the guest: virtio, virtio_pci, virtio_blk, virtio_net, and virtio_ring. For 32-bit guests, the specific "virtio" module is not necessary.

If you want to boot from a virtio disk, the initial ramdisk must contain the necessary modules. By default, this is handled by mkinitcpio's autodetect hook. Otherwise use the MODULES array in /etc/mkinitcpio.conf to include the necessary modules and rebuild the initial ramdisk.

/etc/mkinitcpio.conf
MODULES=(virtio virtio_blk virtio_pci virtio_net)

Virtio disks are recognized with the prefix v (e.g. vda, vdb, etc.); therefore, changes must be made in at least /etc/fstab and /boot/grub/grub.cfg when booting from a virtio disk.

Tip: When referencing disks by UUID in both /etc/fstab and bootloader, nothing has to be done.

Further information on paravirtualization with KVM can be found here.

You might also want to install qemu-guest-agent to implement support for QMP commands that will enhance the hypervisor management capabilities. After installing the package you can enable and start the qemu-ga.service.

Preparing a Windows guest

Note: The only (reliable) way to upgrade a Windows 8.1 guest to Windows 10 seems to be to temporarily choose cpu core2duo,nx for the install [1]. After the install, you may revert to other cpu settings (8/8/2015).

Block device drivers

New Install of Windows

Windows does not come with the virtio drivers. Therefore, you will need to load them during installation. There are basically two ways to do this: via Floppy Disk or via ISO files. Both images can be downloaded from the Fedora repository.

The floppy disk option is difficult because you will need to press F6 (Shift-F6 on newer Windows) at the very beginning of powering on the QEMU. This is difficult since you need time to connect your VNC console window. You can attempt to add a delay to the boot sequence. See qemu(1) for more details about applying a delay at boot.

The ISO option to load drivers is the preferred way, but it is available only on Windows Vista and Windows Server 2008 and later. The procedure is to load the image with virtio drivers in an additional cdrom device along with the primary disk device and Windows installer:

$ qemu-system-x86_64 ... \
-drive file=/path/to/primary/disk.img,index=0,media=disk,if=virtio \
-drive file=/path/to/installer.iso,index=2,media=cdrom \
-drive file=/path/to/virtio.iso,index=3,media=cdrom \
...

During the installation, the Windows installer will ask you for your Product key and perform some additional checks. When it gets to the "Where do you want to install Windows?" screen, it will give a warning that no disks are found. Follow the example instructions below (based on Windows Server 2012 R2 with Update).

  • Select the option Load Drivers.
  • Uncheck the box for "Hide drivers that aren't compatible with this computer's hardware".
  • Click the Browse button and open the CDROM for the virtio iso, usually named "virtio-win-XX".
  • Now browse to E:\viostor\[your-os]\amd64, select it, and press OK.
  • Click Next

You should now see your virtio disk(s) listed here, ready to be selected, formatted and installed to.

Change Existing Windows VM to use virtio

Modifying an existing Windows guest for booting from virtio disk is a bit tricky.

You can download the virtio disk driver from the Fedora repository.

Now you need to create a new disk image, which will force Windows to search for the driver. For example:

$ qemu-img create -f qcow2 fake.qcow2 1G

Run the original Windows guest (with the boot disk still in IDE mode) with the fake disk (in virtio mode) and a CD-ROM with the driver.

$ qemu-system-x86_64 -m 512 -drive file=windows_disk_image,if=ide -drive file=fake.qcow2,if=virtio -cdrom virtio-win-0.1-81.iso

Windows will detect the fake disk and try to find a driver for it. If it fails, go to the Device Manager, locate the SCSI drive with an exclamation mark icon (should be open), click Update driver and select the virtual CD-ROM. Do not navigate to the driver folder within the CD-ROM, simply select the CD-ROM drive and Windows will find the appropriate driver automatically (tested for Windows 7 SP1). Do not forget to select the checkbox which says to search for directories recursively.

When the installation is successful, you can turn off the virtual machine and launch it again, now with the boot disk attached in virtio mode:

$ qemu-system-x86_64 -m 512 -drive file=windows_disk_image,if=virtio
Note: If you encounter the Blue Screen of Death, make sure you did not forget the -m parameter, and that you do not boot with virtio instead of ide for the system drive before drivers are installed.

Network drivers

Installing virtio network drivers is a bit easier, simply add the -net argument as explained above.

$ qemu-system-x86_64 -m 512 -drive file=windows_disk_image,if=virtio -net nic,model=virtio -cdrom virtio-win-0.1-74.iso

Windows will detect the network adapter and try to find a driver for it. If it fails, go to the Device Manager, locate the network adapter with an exclamation mark icon (should be open), click Update driver and select the virtual CD-ROM. Do not forget to select the checkbox which says to search for directories recursively.

Balloon driver

If you want to track you guest memory state (for example via virsh command dommemstat) or change guest's memory size in runtime (you still will not be able to change memory size, but can limit memory usage via inflating balloon driver) you will need to install guest balloon driver.

For this you will need to go to Device Manager, locate PCI standard RAM Controller in System devices (or unrecognized PCI controller from Other devices) and choose Update driver. In opened window you will need to choose Browse my computer... and select the CD-ROM (and do not forget the Include subdirectories checkbox). Reboot after installation. This will install the driver and you will be able to inflate the balloon (for example via hmp command balloon memory_size, which will cause balloon to take as much memory as possible in order to shrink the guest's available memory size to memory_size). However, you still will not be able to track guest memory state. In order to do this you will need to install Balloon service properly. For that open command line as administrator, go to the CD-ROM, Balloon directory and deeper, depending on your system and architecture. Once you are in amd64 (x86) directory, run blnsrv.exe -i which will do the installation. After that virsh command dommemstat should be outputting all supported values.

Preparing a FreeBSD guest

Install the emulators/virtio-kmod port if you are using FreeBSD 8.3 or later up until 10.0-CURRENT where they are included into the kernel. After installation, add the following to your /boot/loader.conf file:

virtio_load="YES"
virtio_pci_load="YES"
virtio_blk_load="YES"
if_vtnet_load="YES"
virtio_balloon_load="YES"

Then modify your /etc/fstab by doing the following:

sed -ibak "s/ada/vtbd/g" /etc/fstab

And verify that /etc/fstab is consistent. If anything goes wrong, just boot into a rescue CD and copy /etc/fstab.bak back to /etc/fstab.

QEMU monitor

While QEMU is running, a monitor console is provided in order to provide several ways to interact with the virtual machine running. The QEMU monitor offers interesting capabilities such as obtaining information about the current virtual machine, hotplugging devices, creating snapshots of the current state of the virtual machine, etc. To see the list of all commands, run help or ? in the QEMU monitor console or review the relevant section of the official QEMU documentation.

Accessing the monitor console

When using the std default graphics option, one can access the QEMU monitor by pressing Ctrl+Alt+2 or by clicking View > compatmonitor0 in the QEMU window. To return to the virtual machine graphical view either press Ctrl+Alt+1 or click View > VGA.

However, the standard method of accessing the monitor is not always convenient and does not work in all graphic outputs QEMU supports. Alternative options of accessing the monitor are described below:

  • telnet: Run QEMU with the -monitor telnet:127.0.0.1:port,server,nowait parameter. When the virtual machine is started you will be able to access the monitor via telnet:
 $ telnet 127.0.0.1 port
Note: If 127.0.0.1 is specified as the IP to listen it will be only possible to connect to the monitor from the same host QEMU is running on. If connecting from remote hosts is desired, QEMU must be told to listen 0.0.0.0 as follows: -monitor telnet:0.0.0.0:port,server,nowait. Keep in mind that it is recommended to have a firewall configured in this case or make sure your local network is completely trustworthy since this connection is completely unauthenticated and unencrypted.
  • UNIX socket: Run QEMU with the -monitor unix:socketfile,server,nowait parameter. Then you can connect with either socat or openbsd-netcat.

For example, if QEMU is run via:

 $ qemu-system-x86_64 [...] -monitor unix:/tmp/monitor.sock,server,nowait [...]

It is possible to connect to the monitor with:

 $ socat - UNIX-CONNECT:/tmp/monitor.sock

Or with:

 $ nc -U /tmp/monitor.sock
  • TCP: You can expose the monitor over TCP with the argument -monitor tcp:127.0.0.1:port,server,nowait. Then connect with netcat, either openbsd-netcat or gnu-netcat by running:
 $ nc 127.0.0.1 port
Note: In order to be able to connect to the tcp socket from other devices other than the same host QEMU is being run on you need to listen to 0.0.0.0 like explained in the telnet case. The same security warnings apply in this case as well.
  • Standard I/O: It is possible to access the monitor automatically from the same terminal QEMU is being run by running it with the argument -monitor stdio.

Sending keyboard presses to the virtual machine using the monitor console

Some combinations of keys may be difficult to perform on virtual machines due to the host intercepting them instead in some configurations (a notable example is the Ctrl+Alt+F* key combinations, which change the active tty). To avoid this problem, the problematic combination of keys may be sent via the monitor console instead. Switch to the monitor and use the sendkey command to forward the necessary keypresses to the virtual machine. For example:

 (qemu) sendkey ctrl-alt-f2

Creating and managing snapshots via the monitor console

Note: This feature will only work when the virtual machine disk image is in qcow2 format. It will not work with raw images.

It is sometimes desirable to save the current state of a virtual machine and having the possibility of reverting the state of the virtual machine to that of a previously saved snapshot at any time. The QEMU monitor console provides the user with the necessary utilities to create snapshots, manage them, and revert the machine state to a saved snapshot.

  • Use savevm name in order to create a snapshot with the tag name.
  • Use loadvm name to revert the virtual machine to the state of the snapshot name.
  • Use delvm name to delete the snapshot tagged as name.
  • Use info snapshots to see a list of saved snapshots. Snapshots are identified by both an auto-incremented ID number and a text tag (set by the user on snapshot creation).

Running the virtual machine in immutable mode

It is possible to run a virtual machine in a frozen state so that all changes will be discarded when the virtual machine is powered off just by running QEMU with the -snapshot parameter. When the disk image is written by the guest, changes will be saved in a temporary file in /tmp and will be discarded when QEMU halts.

However, if a machine is running in frozen mode it is still possible to save the changes to the disk image if it is afterwards desired by using the monitor console and running the following command:

 (qemu) commit all

If snapshots are created when running in frozen mode they will be discarded as soon as QEMU is exited unless changes are explicitly commited to disk, as well.

Pause and power options via the monitor console

Some operations of a physical machine can be emulated by QEMU using some monitor commands:

  • system_powerdown will send an ACPI shutdown request to the virtual machine. This effect is similar to the power button in a physical machine.
  • system_reset will reset the virtual machine similarly to a reset button in a physical machine. This operation can cause data loss and file system corruption since the virtual machine is not cleanly restarted.
  • stop will pause the virtual machine.
  • cont will resume a virtual machine previously paused.

Taking screenshots of the virtual machine

Screenshots of the virtual machine graphic display can be obtained in the PPM format by running the following command in the monitor console:

 (qemu) screendump file.ppm

QEMU machine protocol

The QEMU machine protocol (QMP) is a JSON-based protocol which allows applications to control a QEMU instance. Similarly to the #QEMU monitor it offers ways to interact with a running machine and the JSON protocol allows to do it programmatically. The description of all the QMP commands can be found in qmp-commands.

Start QMP

The usual way to control the guest using the QMP protocol, is to open a TCP socket when launching the machine using the -qmp option. Here it is using for example the TCP port 4444:

 $ qemu-system-x86_64 [...] -qmp tcp:localhost:4444,server,nowait

Then one way to communicate with the QMP agent is to use netcat:

nc localhost 4444
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 1, "major": 3}, "package": ""}, "capabilities": []} } 

At this stage, the only command that can be recognized is qmp_capabilities, so that QMP enters into command mode. Type:

 {"execute": "qmp_capabilities"}

Now, QMP is ready to receive commands, to retrieve the list of recognized commands, use:

 {"execute": "query-commands"}

Live merging of child image into parent image

It is possible to merge a running snapshot into its parent by issuing a block-commit command. In its simplest form the following line will commit the child into its parent:

 {"execute": "block-commit", "arguments": {"device": "devicename"}}

Upon reception of this command, the handler looks for the base image and converts it from read only to read write mode and then runs the commit job.

Once the block-commit operation has completed, the event BLOCK_JOB_READY will be emitted, signalling that the synchronization has finished. The job can then be gracefully completed by issuing the command block-job-complete:

 {"execute": "block-job-complete", "arguments": {"device": "devicename"}}

Until such a command is issued, the commit operation remains active. After successful completion, the base image remains in read write mode and becomes the new active layer. On the other hand, the child image becomes invalid and it is the responsibility of the user to clean it up.

Tip: The list of device and their names can be retrieved by executing the command query-block and parsing the results. The device name is in the device field, for example ide0-hd0 for the hard disk in this example:
{"execute": "query-block"}
{"return": [{"io-status": "ok", "device": "ide0-hd0", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"virtual-size": 27074281472, "filename": "parent.qcow2", ... } 

Live creation of a new snapshot

To create a new snapshot out of a running image, run the command:

 {"execute": "blockdev-snapshot-sync", "arguments": {"device": "devicename","snapshot-file": "new_snapshot_name.qcow2"}}

This creates an overlay file named new_snapshot_name.qcow2 which then becomes the new active layer.

Tips and tricks

Improve virtual machine performance

There are a number of techniques that you can use to improve the performance of the virtual machine. For example:

  • Use the -cpu host option to make QEMU emulate the host's exact CPU. If you do not do this, it may be trying to emulate a more generic CPU.
  • Especially for Windows guests, enable Hyper-V enlightenments: -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time.
  • If the host machine has multiple cores, assign the guest more cores using the -smp option.
  • Make sure you have assigned the virtual machine enough memory. By default, QEMU only assigns 128 MiB of memory to each virtual machine. Use the -m option to assign more memory. For example, -m 1024 runs a virtual machine with 1024 MiB of memory.
  • Apply #Enabling KVM: add -enable-kvm to the QEMU start command you use.
  • If supported by drivers in the guest operating system, use virtio for network and/or block devices. For example:
$ qemu-system-x86_64 -net nic,model=virtio -net tap,if=tap0,script=no -drive file=disk_image,media=disk,if=virtio
  • Use TAP devices instead of user-mode networking. See #Tap networking with QEMU.
  • If the guest OS is doing heavy writing to its disk, you may benefit from certain mount options on the host's file system. For example, you can mount an ext4 file system with the option barrier=0. You should read the documentation for any options that you change because sometimes performance-enhancing options for file systems come at the cost of data integrity.
  • If you have a raw disk image, you may want to disable the cache:
$ qemu-system-x86_64 -drive file=disk_image,if=virtio,cache=none
  • Use the native Linux AIO:
$ qemu-system-x86_64 -drive file=disk_image,if=virtio,aio=native,cache.direct=on
  • If you are running multiple virtual machines concurrently that all have the same operating system installed, you can save memory by enabling kernel same-page merging. See #Enabling KSM.
  • In some cases, memory can be reclaimed from running virtual machines by running a memory ballooning driver in the guest operating system and launching QEMU using -device virtio-balloon.
  • It is possible to use a emulation layer for an ICH-9 AHCI controller (although it may be unstable). The AHCI emulation supports NCQ, so multiple read or write requests can be outstanding at the same time:
$ qemu-system-x86_64 -drive id=disk,file=disk_image,if=none -device ich9-ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0

See http://www.linux-kvm.org/page/Tuning_KVM for more information.

Starting QEMU virtual machines on boot

With libvirt

If a virtual machine is set up with libvirt, it can be configured with virsh autostart or through the virt-manager GUI to start at host boot by going to the Boot Options for the virtual machine and selecting "Start virtual machine on host boot up".

With systemd service

To run QEMU VMs on boot, you can use following systemd unit and config.

/etc/systemd/system/qemu@.service
[Unit]
Description=QEMU virtual machine

[Service]
Environment="type=system-x86_64" "haltcmd=kill -INT $MAINPID"
EnvironmentFile=/etc/conf.d/qemu.d/%i
ExecStart=/usr/bin/qemu-${type} -name %i -nographic $args
ExecStop=/bin/sh -c ${haltcmd}
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target
Note: According to systemd.service(5) and 5 man pages it is necessary to use the KillMode=none option. Otherwise the main qemu process will be killed immediately after the ExecStop command quits (it simply echoes one string) and your guest system will not be able to shutdown correctly.

Then create per-VM configuration files, named /etc/conf.d/qemu.d/vm_name, with the variables type, args and haltcmd set. Example configs:

/etc/conf.d/qemu.d/one
type="system-x86_64"

args="-enable-kvm -m 512 -hda /dev/vg0/vm1 -net nic,macaddr=DE:AD:BE:EF:E0:00 \
 -net tap,ifname=tap0 -serial telnet:localhost:7000,server,nowait,nodelay \
 -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0"

haltcmd="echo 'system_powerdown' | nc localhost 7100" # or netcat/ncat

# You can use other ways to shut down your VM correctly
#haltcmd="ssh powermanager@vm1 sudo poweroff"
/etc/conf.d/qemu.d/two
args="-enable-kvm -m 512 -hda /srv/kvm/vm2.img -net nic,macaddr=DE:AD:BE:EF:E0:01 \
 -net tap,ifname=tap1 -serial telnet:localhost:7001,server,nowait,nodelay \
 -monitor telnet:localhost:7101,server,nowait,nodelay -vnc :1"

haltcmd="echo 'system_powerdown' | nc localhost 7101"

The description of the variables is the following:

  • type - QEMU binary to call. If specified, will be prepended with /usr/bin/qemu- and that binary will be used to start the VM.
  • args - QEMU command line to start with. Will always be prepended with -name ${vm} -nographic.
  • haltcmd - Command to shut down a VM safely. In this example, the QEMU monitor is exposed via telnet using -monitor telnet:.. and the VMs are powered off via ACPI by sending system_powerdown to monitor with the nc command. You can use SSH or some other ways as well.

To set which virtual machines will start on boot-up, enable the qemu@vm_name.service systemd unit.

Mouse integration

To prevent the mouse from being grabbed when clicking on the guest operating system's window, add the options -usb -device usb-tablet. This means QEMU is able to report the mouse position without having to grab the mouse. This also overrides PS/2 mouse emulation when activated. For example:

$ qemu-system-x86_64 -hda disk_image -m 512 -usb -device usb-tablet

If that does not work, try using -vga qxl parameter, also look at the instructions #Mouse cursor is jittery or erratic.

Pass-through host USB device

It is possible to access the physical device connected to a USB port of the host from the guest. The first step is to identify where the device is connected, this can be found running the lsusb command. For example:

lsusb
...
Bus 003 Device 007: ID 0781:5406 SanDisk Corp. Cruzer Micro U3

The outputs in bold above will be useful to identify respectively the host_bus and host_addr or the vendor_id and product_id.

In qemu, the idea is to emulate an EHCI (USB 2) or XHCI (USB 3) controller with the option -device usb-ehci,id=ehci or -device qemu-xhci,id=xhci respectively and then attach the physical device to it with the option -device usb-host,... We will consider that controller_id is either ehci or xhci for the rest of this section.

Then, there are two ways to connect to the USB of the host with qemu:

  1. Identify the device and connect to it on any bus and address it is attached to on the host, the generic syntax is:
    -device usb-host,bus=controller_id.0,vendorid=0xvendor_id,productid=0xproduct_id
    Applied to the device used in the example above, it becomes:
    -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0781,productid=0x5406
    One can also add the ...,port=port_number setting to the previous option to specify in which physical port of the virtual controller the device should be attached, useful in the case one want to add multiple usb devices to the VM.
  2. Attach whatever is connected to a given USB bus and address, the syntax is:
    -device usb-host,bus=controller_id.0,hostbus=host_bus,host_addr=host_addr
    Applied to the bus and the address in the example above, it becomes:
    -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,hostbus=3,hostaddr=7
Note: If you encounter permission errors when running QEMU, see udev#About udev rules for information on how to set permissions of the device.

USB redirection with SPICE

When using #SPICE it is possible to redirect USB devices from the client to the virtual machine without needing to specify them in the QEMU command. It is possible to configure the number of USB slots available for redirected devices (the number of slots will determine the maximum number of devices which can be redirected simultaneously). The main advantages of using SPICE for redirection compared to the previously-mentioned -usbdevice method is the possibility of hot-swapping USB devices after the virtual machine has started, without needing to halt it in order to remove USB devices from the redirection or adding new ones. This method of USB redirection also allows us to redirect USB devices over the network, from the client to the server. In summary, it is the most flexible method of using USB devices in a QEMU virtual machine.

We need to add one EHCI/UHCI controller per available USB redirection slot desired as well as one SPICE redirection channel per slot. For example, adding the following arguments to the QEMU command you use for starting the virtual machine in SPICE mode will start the virtual machine with three available USB slots for redirection:

-device ich9-usb-ehci1,id=usb \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2 \
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \
-chardev spicevmc,name=usbredir,id=usbredirchardev1 -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
-chardev spicevmc,name=usbredir,id=usbredirchardev2 -device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \
-chardev spicevmc,name=usbredir,id=usbredirchardev3 -device usb-redir,chardev=usbredirchardev3,id=usbredirdev3

See SPICE/usbredir for more information.

Both spicy from spice-gtk (Input > Select USB Devices for redirection) and remote-viewer from virt-viewer (File > USB device selection) support this feature. Please make sure that you have installed the necessary SPICE Guest Tools on the virtual machine for this functionality to work as expected (see the #SPICE section for more information).

Warning: Keep in mind that when a USB device is redirected from the client, it will not be usable from the client operating system itself until the redirection is stopped. It is specially important to never redirect the input devices (namely mouse and keyboard), since it will be then difficult to access the SPICE client menus to revert the situation, because the client will not respond to the input devices after being redirected to the virtual machine.

Enabling KSM

Kernel Samepage Merging (KSM) is a feature of the Linux kernel that allows for an application to register with the kernel to have its pages merged with other processes that also register to have their pages merged. The KSM mechanism allows for guest virtual machines to share pages with each other. In an environment where many of the guest operating systems are similar, this can result in significant memory savings.

Note: Although KSM may reduce memory usage, it may increase CPU usage. Also note some security issues may occur, see Wikipedia:Kernel same-page merging.

To enable KSM:

# echo 1 > /sys/kernel/mm/ksm/run

To make it permanent, use systemd's temporary files:

/etc/tmpfiles.d/ksm.conf
w /sys/kernel/mm/ksm/run - - - - 1

If KSM is running, and there are pages to be merged (i.e. at least two similar VMs are running), then /sys/kernel/mm/ksm/pages_shared should be non-zero. See https://www.kernel.org/doc/Documentation/vm/ksm.txt for more information.

Tip: An easy way to see how well KSM is performing is to simply print the contents of all the files in that directory:
$ grep . /sys/kernel/mm/ksm/*

Multi-monitor support

The Linux QXL driver supports four heads (virtual screens) by default. This can be changed via the qxl.heads=N kernel parameter.

The default VGA memory size for QXL devices is 16M (VRAM size is 64M). This is not sufficient if you would like to enable two 1920x1200 monitors since that requires 2 × 1920 × 4 (color depth) × 1200 = 17.6 MiB VGA memory. This can be changed by replacing -vga qxl by -vga none -device qxl-vga,vgamem_mb=32. If you ever increase vgamem_mb beyond 64M, then you also have to increase the vram_size_mb option.

Copy and paste

One way to share the clipboard between the host and the guest is to enable the SPICE remote desktop protocol and access the client with a SPICE client. One needs to follow the steps described in #SPICE. A guest run this way will support copy paste with the host.

Windows-specific notes

QEMU can run any version of Windows from Windows 95 through Windows 10.

It is possible to run Windows PE in QEMU.

Fast startup

Note: An administrator account is required to change power settings.

For Windows 8 (or later) guests it is better to disable "Turn on fast startup (recommended)" from the Power Options of the Control Panel as explained in the following forum page, as it causes the guest to hang during every other boot.

Fast Startup may also need to be disabled for changes to the -smp option to be properly applied.

Remote Desktop Protocol

If you use a MS Windows guest, you might want to use RDP to connect to your guest VM. If you are using a VLAN or are not in the same network as the guest, use:

$ qemu-system-x86_64 -nographic -net user,hostfwd=tcp::5555-:3389

Then connect with either rdesktop or freerdp to the guest. For example:

$ xfreerdp -g 2048x1152 localhost:5555 -z -x lan

Clone Linux system installed on physical equipment

Linux system installed on physical equipment can be cloned for running on QEMU vm. See Clone Linux system from hardware for QEMU virtual machine

Troubleshooting

Mouse cursor is jittery or erratic

If the cursor jumps around the screen uncontrollably, entering this on the terminal before starting QEMU might help:

$ export SDL_VIDEO_X11_DGAMOUSE=0

If this helps, you can add this to your ~/.bashrc file.

No visible Cursor

Add -show-cursor to QEMU's options to see a mouse cursor.

If that still does not work, make sure you have set your display device appropriately, for example: -vga qxl.

Two different mouse cursors are visible

Apply the tip #Mouse integration.

Keyboard issues when using VNC

When using VNC, you might experience keyboard problems described (in gory details) here. The solution is not to use the -k option on QEMU, and to use gvncviewer from gtk-vnc. See also this message posted on libvirt's mailing list.

Keyboard seems broken or the arrow keys do not work

Should you find that some of your keys do not work or "press" the wrong key (in particular, the arrow keys), you likely need to specify your keyboard layout as an option. The keyboard layouts can be found in /usr/share/qemu/keymaps.

$ qemu-system-x86_64 -k keymap disk_image

Guest display stretches on window resize

To restore default window size, press Ctrl+Alt+u.

ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy

If an error message like this is printed when starting QEMU with -enable-kvm option:

ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy
failed to initialize KVM: Device or resource busy

that means another hypervisor is currently running. It is not recommended or possible to run several hypervisors in parallel.

libgfapi error message

The error message displayed at startup:

Failed to open module: libgfapi.so.0: cannot open shared object file: No such file or directory

Install glusterfs or ignore the error message as GlusterFS is a optional dependency.

Kernel panic on LIVE-environments

If you start a live-environment (or better: booting a system) you may encounter this:

[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown block(0,0)

or some other boot hindering process (e.g. cannot unpack initramfs, cant start service foo). Try starting the VM with the -m VALUE switch and an appropriate amount of RAM, if the ram is to low you will probably encounter similar issues as above/without the memory-switch.

Windows 7 guest suffers low-quality sound

Using the hda audio driver for Windows 7 guest may result in low-quality sound. Changing the audio driver to ac97 by passing the -soundhw ac97 arguments to QEMU and installing the AC97 driver from Realtek AC'97 Audio Codecs in the guest may solve the problem. See Red Hat Bugzilla – Bug 1176761 for more information.

Could not access KVM kernel module: Permission denied

If you encounter the following error:

 libvirtError: internal error: process exited while connecting to monitor: Could not access KVM kernel module: Permission denied failed to initialize KVM: Permission denied

Systemd 234 assign it a dynamic id to group kvm (see bug). A workground for avoid this error, you need edit the file /etc/libvirt/qemu.conf and change the line:

 group = "78"

to

 group = "kvm"

"System Thread Exception Not Handled" when booting a Windows VM

Windows 8 or Windows 10 guests may raise a generic compatibility exception at boot, namely "System Thread Exception Not Handled", which tends to be caused by legacy drivers acting strangely on real machines. On KVM machines this issue can generally be solved by setting the CPU model to core2duo.

Certain Windows games/applications crashing/causing a bluescreen

Occasionally, applications running in the VM may crash unexpectedly, whereas they would run normally on a physical machine. If, while running dmesg -wH, you encounter an error mentioning MSR, the reason for those crashes is that KVM injects a General protection fault (GPF) when the guest tries to access unsupported Model-specific registers (MSRs) - this often results in guest applications/OS crashing. A number of those issues can be solved by passing the ignore_msrs=1 option to the KVM module, which will ignore unimplemented MSRs.

/etc/modprobe.d/kvm.conf
...
options kvm ignore_msrs=1
...

Cases where adding this option might help:

  • GeForce Experience complaining about an unsupported CPU being present.
  • StarCraft 2 and L.A. Noire reliably blue-screening Windows 10 with KMODE_EXCEPTION_NOT_HANDLED. The blue screen information does not identify a driver file in these cases.
Warning: While this is normally safe and some applications might not work without this, silently ignoring unknown MSR accesses could potentially break other software within the VM or other VMs.

Applications in the VM experience long delays or take a long time to start

This may be caused by insufficient available entropy in the VM. Consider allowing the guest to access the hosts's entropy pool by adding a VirtIO RNG device to the VM, or by installing an entropy generating daemon such as Haveged.

Anecdotally, OpenSSH takes a while to start accepting connections under insufficient entropy, without the logs revealing why.

High interrupt latency and microstuttering

This problem manifests itself as small pauses (stutters) and is particularly noticeable in graphics-intensive applications, such as games.

QXL video causes low resolution

QEMU 4.1.0 introduced a regression where QXL video can fall back to low resolutions, when being displayed through spice. [2] For example, when KMS starts, text resolution may become as low as 4x10 characters. When trying to increase GUI resolution, it may go to the lowest supported resolution.

As a workaround, create your device in this form:

-device qxl-vga,max_outputs=1...

Hang during VM initramfs

Linux 5.2.11 introduced a KVM regression where under some circumstances a VM may permanently hang during the early boot phase, when the initramfs is being loaded or ran. [3] Linux 5.3 fixed the regression. The host shows qemu using 100% CPU * number of virtual CPUs. Reported case is with a host using hyperthreading, and a VM being given more than host's nproc/2 virtual CPUs. It is unknown what exact circumstances trigger one of the threads to delete a memory region to cause this. The workarounds are:

  • Upgrade to Linux 5.3.
  • Downgrade to Linux 5.2.10
  • Until fixed, try giving the VM no more than the host's nproc/2 virtual CPUs
  • Custom compile linux, reverting commit 2ad350fb4c (note this re-introduces a regression triggered when removing a memslot)

See also