Spielereien mit KVM (Kernelbased Virtual Machine)

Moin! :)

Diesmal ist es etwas anspruchsvoller, dafür aber auch alles relevante zusammen (hoffentlich):


Vorab:

Da die Skripte die Laufwerke direkt einbinden, funktionieren sie nur, wenn zur Gruppe "disk" gehört - Vorsicht: Man sollte wissen was das bedeutet!

Ansonsten die VM besser mit sudo qemu-system-x86_64 -run-with user=$USER […] starten ($USER ist eine Variable und muss nicht geändert werden)starten: Die Rootrechte braucht es, um die Laufwerke einzubinden, aber dann wechselt es sofort (also noch bevor es die VM bootet) auf normale Benutzerrechte. - Das erste Skript muss man für die Passwortabfrage dann aber auch per Terminal starten. - Außer man packt auch "/usr/bin/qemu-system-x86_64" in /etc/sudoers: s. u.

Wichtig: Keine der Partitionen auf diesen Laufwerken darf beim Host eingehängt sein: Kokurierende Zugriffe (Host+Gast) können schnell das Dateisystem zerstören!

Zusätzlich habe ich "%disk ALL=(ALL:ALL) NOPASSWD:/usr/bin/umount" zu /etc/sudoers hinzugefügt, damit "sudo umount -at vfat,exfat,ntfs3" ohne Passwortabfrage funktioniert. - Wobei mir gerade das ntfs3 auffällt: Wessen System noch ntfs-3g nutzt, muss das entsprechend anpassen.

Die benötigten Windows-VirtIO-Treiber bekommt man bei fedorapeople/virtio-win/latest/

Das ISO bindet man einfach mit "-cdrom (ISO-Datei)" ein.


Ich habe die letzten Tage mit meinem VM-WinXP experimentiert, um beim Videoschnitt mit VideoReDo (Streamcopy, kein Recoding) damit auch die RAM-Disk des Host mit bestmöglicher Geschwindigkeit nutzen zu können: "Gemeinsame Ordner" lassen sich bei KVM zwar über Samba realisieren, die sind aber lahm.

Meine Idee war deshalb, für die RAM-Disk ein Festplatten-Image mit ntfs-16k Cluster zu erstellen (damit ist ntfs am effizientesten) und dass dann einfach vom Skripte, mit dem ich das VM-XP starte, vorher in die RAM-Disk zu kopieren. - Und anschließend, damit ich die dorhin geschnittene Aufnahmen mit dem Host weiterbearbeiten zu können, als Loopdevice zu mounten. - Dieses Festplatten-Image habe ich als komprimiertes .qcow2 angehängt.

Damit möchte ich der SSD unnötige Schreibzugriffe ersparen, außerdem hat es mich interessiert das zu realisieren: Eine weitere kleine Spielerei mit KVM - passend zum Thread-Titel. ;)

Die RAM-Disks habe ich in /etc/fstab so erstellt:
Code:
# <file system>                  <mount point> <type> <options>          <dump> <pass>
memory                                    /tmp  tmpfs nosuid,size=90%         0 0
memory                                    /tmph tmpfs huge=always,size=90%    0 0

/tmp habe ich schon lange im RAM. Auch aus Sicherheitgründen, da ich meine Home-Partition per LUKS verschlüselt habe und nicht wollte, dass etwas in /tmp auf der unverschlüsselten Systempartition gespeichert wird: Wenn ich damals (noch unter LinuxMint) z. B. die Text-Datei mit meinen Passwörten aus einem verschlüsselte 7z geöffnet habe, hat fileroller es in /tmp entpackt, um es mit dem Editor öffnen zu können!

/tmph ist durch "huge=always" bei sehr großen Dateien deutlich schneller (für sehr kleine aber ungeeignet, da es wie ein Dateisystem mit 4 MiB großen Clustern dabei einen riesengroßen "Verschnitt" hat).

Und 90% (standard: 50%), weil ich mit 32 GiB RAM selbst dann noch 3 GiB RAM frei habe, wenn die RAM-Disk voll ist. - Beide addieren sich zwar zum 180% (zu viel würde ausgelagert, wäre also nicht allzu schlimm), aber in /tmp kommt eigntlich nur Futzelkam, das nicht weiter ins Gewicht fällt. - Die 90% sind dort nur zur Sicherheit, falls ich doch mal so viel brauche. - /tmph lasse ich dann natürlich leer.


Geschwindigkeitsvergleich:
(mit bs=512K sind beide RAM-Disks am schnellsten - bei Datenträgern (egal ob HDD, SSD oder USB-Sticks) ist übrigens bs=64M am schnellsten)

/tmp:
Code:
$ sync;dd if=/dev/zero of=nichts.bin bs=512K count=32768;sync;time rm nichts.bin
32768+0 Datensätze ein
32768+0 Datensätze aus
17179869184 Byte (17 GB, 16 GiB) kopiert, 21,5451 s, 797 MB/s

real    0m4,893s
user    0m0,000s
sys    0m4,774s

/tmph:
Code:
$ sync;dd if=/dev/zero of=nichts.bin bs=512K count=32768;sync;time rm nichts.bin
32768+0 Datensätze ein
32768+0 Datensätze aus
17179869184 Byte (17 GB, 16 GiB) kopiert, 10,4983 s, 1,6 GB/s

real    0m0,193s
user    0m0,001s
sys    0m0,189s
Doppelt so schnell erstellt und fünfundzwanzigmal schneller gelöscht! :)

Das langsame löschen der nicht mehr benötigten Zwischendateien hat mich immer wieder genervt: Löschen und weg - so muss das sein! ;)


Ich nutze dafür immer noch Windows XP (Home SP3 ohne weitere Aktualisierungen), da das noch schlank und effizient war, während aktuelle Windowsen (10+11 tun sich da nichts) beim Videoschnitt im direkten Vergleich nicht mal mehr halb so schnell sind!

Das Image (Windows inkl. aller dort noch benötigter Software):
Code:
$ qemu-img info WinXP.qcow2
image: WinXP.qcow2
file format: qcow2
virtual size: 1 GiB (1073348608 bytes)
disk size: 303 MiB
Format specific information:
    compat: 1.1
    compression type: zstd

Die Datenträgerbelegung:

VM-WinXP.png


Normalerweise nutze ich Windows nur noch um ntfs per chkdsk prüfen und ggfs. reparieren zu können (dazu hatte ich hier im Thread früher schon genug geschrieben und letztens ein Video veröffentlich), brauche also keine RAM-Disk.
(dass es in "Downloads" ist, hat sich von früher so ergeben und diesmal habe ich schon genug zu bedenken, um auch noch darauf zu achten, das wie bisher aus allen Pfaden zu entfernen)

Dann starte ich es mit diesem Skript (per Win+V):
Code:
#!/bin/bash
cd ~/Downloads/Images/VM-XP/
sudo umount -at vfat,exfat,ntfs3
cl="qemu-system-x86_64 -nodefaults -enable-kvm -cpu host -smp cores=2 -m 2G -vga none -device qxl-vga -display sdl,gl=on,window-close=off -device piix3-usb-uhci -device usb-tablet -audio sdl,model=ac97 \
-drive file=WinXP.qcow2,if=virtio,aio=io_uring,snapshot=on"
for lw in $(fdisk -lo Device,Type|grep FAT|cut -b 1-8|sort -u)
 do df -t{vfat,exfat,ntfs3} $lw"1" || cl=$cl" -drive file="$lw",if=virtio,aio=io_uring,format=raw"
done
sleep 1            # um umount etwas Zeit zu geben
$cl 2> /dev/null    # die in "$cl" zusammengesetzte Befehlszeile wird ausgeführt
espeak-ng -a50 "Check!"
Zuerst werden alle vfat,exfat,ntfs-Dateisysteme ausgehängt, da konkurrierende Zugriffe (Host und VM gleichzeitig) nicht "gut" ist. Sie werden aber nicht gesperrt, so dass man, während die VM läuft, selbst darauf achten muss, dass man sie nicht wieder einhängt! - Deshalb sind mit Datensicherungen SEHR wichtig! - gebranntes Kind… ;)


Wenn ich es doch mit der RAM-Disk brauche, starte ich es (per Win+Umschalt+V, was aber wegen der anschließenden Passwortabfrage übers Terminal laufen muss - s. u.):
Code:
#!/bin/bash
cd ~/Downloads/Images/VM-XP/
if [ ! -f /tmph/ramdisk.raw  ];then qemu-img convert -q ramdisk.qcow2 /tmph/ramdisk.raw;fi
sudo umount -at vfat,exfat,ntfs3
cl="qemu-system-x86_64 -nodefaults -enable-kvm -cpu host -smp cores=2 -m 2G -vga none -device qxl-vga -display sdl,gl=on,window-close=off -device piix3-usb-uhci -device usb-tablet -audio sdl,model=ac97 \
-drive file=WinXP.qcow2,if=virtio,aio=io_uring,snapshot=on \
-drive file=/tmph/ramdisk.raw,if=virtio,cache=none,aio=native,format=raw"
for lw in $(fdisk -lo Device,Type|grep FAT|cut -b 1-8|sort -u)
 do df -t{vfat,exfat,ntfs3} $lw"1" 2> /dev/null || cl=$cl" -drive file="$lw",if=virtio,aio=io_uring,format=raw"
done
sleep 1            # um umount etwas Zeit zu geben
$cl 2> /dev/null    # die in "$cl" zusammengesetzte Befehlszeile wird ausgeführt

espeak-ng -vde -a50 "Bitte Passwort" &
cd /tmph/
mkdir -p ramdisk && sudo mount -tntfs3 -oloop,offset=16k,noatime ramdisk.raw ramdisk/ && \
echo -ne "\nEnter für unmount";read;sudo umount ramdisk
rmdir ramdisk && rm ramdisk.raw

Da es .qcow2 schön handlich ist und sich beliebig kopieren und sichern lässt, habe ich es in dem Format auf der Platte, aber da RAW deutlich schneller ist, lasse ich es in dem Format in die RAM-Disk konvertierten: Das braucht nur einen Sekundenbruchtei und da es "sparse" erstellt wird, belegt es leer fast nichts:
Code:
$ time qemu-img convert -q ramdisk.qcow2 /tmph/ramdisk.raw

real    0m0,132s
user    0m0,159s
sys    0m0,138s

$ qemu-img info /tmph/ramdisk.raw
image: /tmph/ramdisk.raw
file format: raw
virtual size: 32 GiB (34359738368 bytes)
disk size: 64.2 MiB
Würde ich das RAW kopieren, würden dagegen die vollen 32 GiB geschrieben.

Nachdem das VM-XP kommt die Passwortabfrage, um ramdisk.raw als Loopdevice zu mounten, wie oben beschrieben.
Die Tastaturverknüpfung startet es mit dieser Befehlszeile (ich nutze Xfce):
Code:
xfce4-terminal -T VM-Win -I video-x-generic --geometry 100x10 -e Downloads/Images/VM-XP/vmwinr.sh
Wieder muss man selbst darauf achten, dass man nicht eher dort Enter drückt, als das man das aus dem ramdisk.raw nicht mehr braucht, da sie dann gelöscht wird.


Da beide Skripte alle angeschlossenen vfat,exfat,ntfs-Dateisysteme automatisch einhängen, habe ich mir auch zwei Skripte geschrieben, mit denen ich im Terminal das VM-XP nur mit bestimmten Laufwerke starten kann.

Da ich beim Win-Image "snapshot=on" nutze (Schreibzugriffe werden dann im RAM gecachet, aber nicht wirklich umgesetzt), schon damit sich Windows nicht immer weiter zumüllt, kann man es problemlos mehrfach parallel starten, um mit mehreren Windows-Instanzen verschiedene Laufwerke nutzen zu können: Braucht man (zumindest ich) fast nie, aber wenn doch mal, ist es schön dass man es kann. :)

Das "win"-Skript (im Pfad in ~/.local/bin/) ohne RAM-Disk (z. B. "win b c" nutzt es mit /dev/sdb und /dev/sdc)
Code:
#!/bin/bash
cd ~/Downloads/Images/VM-XP/
cl="qemu-system-x86_64 -nodefaults -enable-kvm -cpu host -smp cores=2 -m 2G -vga none -device qxl-vga -display sdl,gl=on,window-close=off -device piix3-usb-uhci -device usb-tablet -audio sdl,model=ac97 \
-drive file=WinXP.qcow2,if=virtio,aio=io_uring,snapshot=on"
while [ $# -gt 0 ]
 do cl=$cl" -drive file=/dev/sd$1,if=virtio,cache=none,aio=native,format=raw"
 umount -q /dev/sd$1* 2> /dev/null
shift;done
sleep 1            # um umount etwas Zeit zu geben
$cl 2> /dev/null    # die in "$cl" zusammengesetzte Befehlszeile wird ausgeführt

Und mit der RAM-Disk das "winr"-Skript:
Code:
#!/bin/bash
cd ~/Downloads/Images/VM-XP/
if [ ! -f /tmph/ramdisk.raw  ];then qemu-img convert -q ramdisk.qcow2 /tmph/ramdisk.raw;fi
cl="qemu-system-x86_64 -nodefaults -enable-kvm -cpu host -smp cores=2 -m 2G -vga none -device qxl-vga -display sdl,gl=on,window-close=off -device piix3-usb-uhci -device usb-tablet -audio sdl,model=ac97 \
-drive file=WinXP.qcow2,if=virtio,aio=io_uring,snapshot=on \
-drive file=/tmph/ramdisk.raw,if=virtio,cache=none,aio=native,format=raw"
while [ $# -gt 0 ]
 do cl=$cl" -drive file=/dev/sd$1,if=virtio,cache=none,aio=native,format=raw"
 umount -q /dev/sd$1* 2> /dev/null
shift;done
sleep 1            # um umount etwas Zeit zu geben
$cl 2> /dev/null    # die in "$cl" zusammengesetzte Befehlszeile wird ausgeführt
espeak-ng -vde -a50 "Bitte Passwort" &
cd /tmph/
mkdir -p ramdisk && sudo mount -tntfs3 -oloop,offset=16k,noatime ramdisk.raw ramdisk/ && \
echo -ne "\nEnter für unmount";read;sudo umount ramdisk
rmdir ramdisk && rm ramdisk.raw


In "echt" habe ich bei den Skripten übrigens aufeinander abgestimmte Leerzeilen eingefügt, um sie bei Änderungen direkt miteinander vergleichen zu können (z. B. bei Mousepad (leider nicht bei Xed) kann man mit Strg+Bild rauf/runter zwischen den Tabs wechseln):

VM-WinXP.gif

Update:

Die Skripte, die automatisch die für Windows nutzbaren Laufwerke einbinden und die, mit denen ich die Laufwerke gezielt wählen kann, unterscheiden sich in der Cachenutzung:

Die ersten beiden nutzen "aio=io_uring" (mit dem Stardard-Cache-Mode "writeback"), das ich bei den anderen beiden durch "cache=none,aio=native" ersetzt habe, weil ich mir Vorteile davon versprach.

Nur die RAM-Disk hat immer "cache=none,aio=native", da es ja Quatsch wäre, eine RAM-Disk im RAM zu cachen. ;)

Neulich hatte ich mal alle sinnvollen Kombinationen getestet (Beschreibungen der möglichen Cache-Modie habe ich angehängt), indem ich ein Livesystem gebootet und dann in einem RAW-Image in /tmph (s. o.) installiert habe, da hatten sich diese beiden Kombinationen in Verbindung mit "io_uring" und "native" als jeweils die schnellsten gezeigt, wobei "io_uring" insgesamt etwas schneller war.

Das habe ich jetzt mit einer Ninja-Warrior-Aufnahme (SD) von gestern bzgl. Windows-Gast und Videoschnitt getestet:

Ziel war immmer die RAM-Disk und die Host-CPU hatte ich auf "performance" gesetzt, damit Taktwechsel nichts verfälschen konnten: Alle 8 Kerne liefen mit 4 GHz (AMD FS-8380 mit deaktiviertem TurboCore), während die VM nur 2 Kerne genutzt hat, die nicht mal voll genutzt wurden.

Da ich zwei Sat-Receiver habe, die ich diesmal beide identisch programmiert hatte, gibt es zwei Quellen:

1. "Corsair" ist ein 64 GB USB-Stick an einem Xoro 8500, der 140 MB/s liefern kann und mit FAT32-64k formatiert ist, da Aufnahmen damit am besten funktionieren.

2. "LiteOn" ist eine 120 GB SSD an einem Xoro 8590, die über USB mit etwas über 400 MB/s ausgelesen werden kann und mit NTFS-64k formatiert ist, damit ich sie trimmen kann.

In dieser Reihenfolge habe ich auch es getestet:

Mit "aio=io_uring":

VM-WinXP-VRD_1.png
VM-WinXP-VRD_2.png

Erreichte Geschwindigkeit in MiB/s:

VM-WinXP-VRD_3.png

Mit "cache=none,aio=native":

VM-WinXP-VRD_4.png
VM-WinXP-VRD_5.png

Erreichte Geschwindigkeit in MiB/s:

VM-WinXP-VRD_6.png

Also nicht nur, dass das insgesamt langsamer ist, sondern wenn es von der SSD kommt, ist es damit sogar langsamer als vom Stick!

Das war reproduzierbar: Ich habe immer 1. und 2. getestet und dann nochmal 1. und 2., um Ausreißer zu vermeiden: Er variierte höchstens um eine Sekunde. - Die Shots sind vom jeweils zweiten Durchlauf.

Um zu sehen, ob das vielleicht sogar bei der RAM-Disk einen Vorteil hat, habe ich auch die auf "aio=io_uring" gesetzt (Stick und SSD sowieso), aber dadurch wurde es nicht mal eine Sekunde schneller.

Deshalb hier nur der Screenshot von SSD, dafür komplett:

VM-WinXP-VRD_7.png

Die Fehler haben übrigens nichts zu sagen. Die gibt es gelegentlich und wahren in diesem Fall offenbar kurze Störungen beim Empfang, da bei beiden Sat-Receivern identisch. - Ist dagegen der Datenträger zu langsam, werden es sehr viel mehr.

Mein Fazit:

"aio=io_uring" ist offenbar unter allen Umständen die bessere Wahl.

"cache=none,aio=native" wird zwar auf div. Seiten immer mal wieder empfohlen, aber die haben es offenbar nie wirklich verglichen.
("aio=native" funktioniert nur mit "cache=none" oder "cache=directsync", aber damit es ist nochmal deutlich langsamer)

Wobei ich NVMe-Laufwerke dabei ausklammern muss: Da mein PC nicht mal eine Anschlussmöglichkeit dafür hat, kann ich das nicht testen.

Btw:

Bei ziemlich genau 3h Sendedauer (ab 30s bis 3h 30s - sicherheitshalber hatte ich 10m länger aufnehmen lassen), blieben netto 2:09h übrig (oben habe ich der Einfachheit halber immer die vollen 3:10h kopieren lassen - wobei alles außer der Videospur und der MP2-Tonspur entfernt wird):

VM-WinXP-VRD.png

Entfernt hatte ich immer "das sehen sie gleich" (ich mag keine Spoiler), das Gewinnspiel und die "Verbraucherinformationen".
 

Anhänge

Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Crisser67
Ich habe gestern einen Vergleich der Cache-Modie zum vorherigen Beitrag hinzugefügt und ihn eben noch etwas überarbeitet. Damit sollte er jetzt abgeschlossen sein:

Windows im BIOS-Modus​

Das gleiche funktioniert auch mit anderen Windows-Versionen, wobei man bei Windows 11 die bekannten "Tricks" braucht, oder es z. B. per Ventoy-Stick installiert: Den kann man auch direkt als Laufwerk einbinden und dann davon booten.

Bei Windows 9x/ME muss man beachten, dass keine Multicore-CPUs unterstützt werden und es sich bei mehr als 512 MiB RAM schon beim booten mit einem BSOD bedankt. - Zu noch älteren Windows-Versionen kann ich nichts sagen. Dafür ist vielleicht sogar DOSbox eine bessere Wahl, aber damit kenne ich mich nicht aus.

Für Windows mit UEFI werde ich später diesen Beitrag recyceln, damit ich beides zusammen habe. - Sogar auf einer neuen Seite: Optimal! :)



Bei LMDE (und vermutlich auch jedem anderen Debian- oder Ubuntu-Derivat) reicht es "qemu-system-x86" zu installieren (per Anwendungsverwaltung, Sysnaptic, oder apt) und alles als benötigte als Abhängigkeit mit installiert zu bekommen.

Bei Arch-Derivaten muss mal das UEFI-BIOS separat mit installieren: sudo pacman -Sy qemu-desktop edk2-ovmf

Sorry, bei dem besch* Wetter habe ich zu mehr keine Lust.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Crisser67
Caramon2 schrieb:
Um hier zu zeigen, wie man openSUSE neben Windows installiert, habe ich mir eine Standard-Installation im UEFI-Modus von Windows 11 erstellt:

[IMG]https://www.computerbase.de/forum/attachments/vm-win11_1-png.1619433/[/IMG]

[IMG]https://www.computerbase.de/forum/attachments/vm-win11_2-png.1619434/[/IMG]
(.fd ist der UEFI-Flash-Speicher)
Damit ich das für beliebige Distributionen nutzen kann, habe ich mir angelesen, wie man ein diff-Image erstellt (also das originale Windows-Image unverändert bleibt) und dazu ein Skript geschrieben, dass das diff-Image in einer zRAM-Disk erstellt: Da ich nur die Installation dokumentieren will, kommt es anschließend gleich wieder weg.
Um das zu demonstrieren, habe ich eben den Beginn einer LMDE 7 Installation aufgezeichnet (näheres dazu hier): s. Anhang

Die zweite Dateiverwaltung öffne ich, um zu zeigen, dass nur die Diff-Daten (links) verändert wird, während das originale Win11-qcow2 (rechts) unverändert auf dem 11.05. bleibt. So kann ich immer vom selben Stand ausgehen.

Das Bootmenü nach der Installation:

LMDE-neben-Windows.png
 

Anhänge

  • LMDE-neben-Windows.mp4
    2,3 MB
  • Gefällt mir
Reaktionen: Crisser67
Das war interessant:

Da ein 100 GB Laufwerk für die "parallel zu Win11 installieren"-Tests (s. Video am vorherigen Beitrag) realitätsfremd war, habe ich es jetzt mit qemu-img resize Windows11.qcow2 $((10**12)) auf praktikablere 1 TB vergrößert.

Dann habe ich LMDE 7 mit dem Laufwerksimage in der VM gebootet, mit GParted einfach die Wiederherstellungspartition ans Ende geschoben und die Windows-Partition auf den vollen Bereich vergrößert. Als nächstes dann noch beide Partitionen eingehängt und mit sudo fstrim -va getrimmt, damit die leeren Bereiche wirklich leer sind und nachdem ich die VM runter gefahren habe, das Laufwerksimage neu komprimiert.

Fazit:

Obwohl ich die Laufwerksgröße von 100 GB auf 1000 GB verzehnfacht habe, ist das Image (bei ansonsten unverändertem Inhalt) jetzt sogar ca. 11 MiB kleiner. - Das fällt bei den 4,8 GiB zwar nicht auf, fand ich aber trotzdem erstaunlich.

Überrascht hat mich, dass das bei solchen Sachen sehr empfindlich gewordene Windows *) immer noch bootet und nicht mal Fehler anzeigt:

Win1-1TB.png

*) XP kann man z. B. einfach per Linux-Dateimanager auf eine andere NTFS-Partition kopieren, boot.ini anpassen: läuft
 
  • Gefällt mir
Reaktionen: Crisser67
Zurück
Oben