Das Problem mit kopierten Boot-Zeilen

Such nach Proxmox-Tuning, und du findest eine einzige lange GRUB_CMDLINE_LINUX-Zeile, als Einheit vorgestellt, ohne Hinweis darauf, welches Flag wohin gehört.

Das zählt mehr, als es klingt. Der Hypervisor und der Gast lösen entgegengesetzte Probleme.

Der Host will bestimmten Zugriff auf echte Hardware: Verhalten der IOMMU, PCIe-Link-Zustände, physische Ruhezustände. Der Gast will aufhören, überhaupt so zu tun, als hätte er Hardware — seine Timer sind Näherungen, seine Ruhezustände Erfindung, und seine Hänger sind meist der Scheduler eines anderen. Damit kann dasselbe Flag auf einer Seite richtig sein, auf der anderen sinnlos und gelegentlich schädlich.

Unten steht, wohin jedes tatsächlich gehört.

Wohin jedes Kernel-Boot-Flag gehörtNur Hosthier wohnt echte Hardwareiommu=ptamd_iommu=pgtbl_v2pcie_acs_override=…pcie_aspm=offpci=pcie_bus_perf→ pcie_bus_safe bei USB4processor.max_cstate=1+ intel_idle.max_cstate auf Intelamd_pstate=disablesetz auch einen GovernorDer Gast hat keine PCIe-Links,keine C-States und kein cpufreq.Nur Gastaufhören, Hardware zu spielencpuidle.off=1Ruhezustände im Gast sind Erfindungnmi_watchdog=0eine weggenommene vCPU löst ihn aussoftlockup_panic=0der Hänger war Schuld des HostsLass kvm-clock in Ruhe.Erzwing nicht tsc oder hpet —die Zähler sind nicht deine.Auf dem Host bedeuten diese dreialle etwas anderes, und zweidavon kosten dich etwasEchtes.Beide — andere Gründegleiches Flag, eigene Entscheidungmitigations=offHost: Lecks Gast zu HostGast: Prozess-Isolationdefault_hugepagesz + hugepagesHost: unterlegt Gast-RAMGast: unterlegt eine Anwendungwähle eine Schicht, nicht beidewatchdog_thresh / nowatchdogHost: Lärm, den du annahmstGast: war nie vertrauenswürdig„Beide“ heißt nicht, dass du esan beiden Stellen setzen sollst.Es heißt, die Entscheidung musszweimal fallen.Keines — die tun nichtsamd_iommu=onkeine gültige Option; der Kernel protokolliert „Unknown option - 'on'“ und macht weiterconsoleblank=0schon die Kernel-VorgabeEnthält eine kopierte Boot-Zeile eines von beiden, wurde sie nie gegen /proc/cmdline geprüft —die billigste Prüfung, die es gibt, und die, die auch den Fehler mit dem falschen Bootloaderauffängt.
Die Flags, die im Umlauf sind, sortiert. Zwei der beliebtesten tun auf keiner Seite etwas, und die Watchdog-Zeile ist eine echte Ermessensfrage und keine Regel.

Zuerst: bearbeitest du überhaupt die richtige Datei?

Eine Proxmox-Installation auf ZFS-Root startet mit systemd-boot, wo /etc/default/grub von niemandem gelesen wird. Sie zu bearbeiten und neu zu starten erzeugt keine Änderung und keinen Fehler. Das ist eine ärgerliche Stunde.

proxmox-boot-tool status          # tells you which bootloader is in use
# systemd-boot: edit /etc/kernel/cmdline, then
proxmox-boot-tool refresh

# GRUB: edit /etc/default/grub, then
update-grub

So oder so: prüfen statt annehmen.

cat /proc/cmdline

Und auf der GRUB-Seite nimm GRUB_CMDLINE_LINUX_DEFAULT, nicht GRUB_CMDLINE_LINUX. Letzteres gilt für jeden Boot-Eintrag, den Rettungseintrag eingeschlossen — und die Rettung ist genau der Moment, in dem du Standardverhalten willst und nicht abgeschaltete Mitigations und festgenagelte C-States.

Die Host-Zeile

IOMMU und Passthrough

iommu=pt amd_iommu=pgtbl_v2 pcie_acs_override=downstream,multifunction

iommu=pt versetzt die IOMMU in den Passthrough-Modus: Geräte, die VMs zugewiesen sind, werden übersetzt, Geräte des Hosts selbst umgehen die Übersetzung. Es ist echt und wird in arch/x86/kernel/pci-dma.c behandelt, das iommu_set_default_passthrough(true) aufruft. Der Kernel dokumentiert es als gleichwertig mit iommu.passthrough=1.

amd_iommu=on gibt es nicht. Das ist der am häufigsten kopierte nicht existierende Parameter in Proxmox-Anleitungen. Das parse_amd_iommu_options() des Kernels nimmt fullflush, force_enable, off, force_isolation, pgtbl_v1, pgtbl_v2, irtcachedis, nohugepages und v2_pgsizes_only. Alles andere landet hier:

pr_notice("Unknown option - '%s'\n", str);

AMD-Vi ist standardmäßig an, wenn die Firmware es angibt. Sieh in dein eigenes Protokoll, und du findest, dass der Parameter nie die Arbeit getan hat, die man ihm zuschrieb:

dmesg | grep -i "AMD-Vi\|Unknown option"

amd_iommu=pgtbl_v2 ist gültig — es wählt das v2-Format für DMA-Seitentabellen, das die Struktur der CPU-Seitentabellen mitnutzt statt AMDs eigener. Zwei Dinge dazu: die Dokumentation begrenzt es auf die DMA-API, also die Gerätedomänen des Hosts selbst und nicht die VFIO-Domänen für Passthrough; und es scheitert sicher, mit einer Protokollzeile, auf die du prüfen solltest:

if (amd_iommu_pgtable == PD_MODE_V2) {
    if (!amd_iommu_v2_pgtbl_supported()) {
        pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
        amd_iommu_pgtable = PD_MODE_V1;
    }
}

Es lohnt sich also, das auf einem Knoten mit schwerem IO auf der Host-Seite zu messen, und es lohnt sich zu prüfen, dass du es wirklich bekommen hast.

pcie_acs_override=downstream,multifunction ist der Patch von Proxmox außerhalb des Kernel-Baums. Er teilt IOMMU-Gruppen auf, indem er eine Isolation behauptet, die die Hardware nicht angibt, und genau das macht Passthrough auf Consumer-Platinen möglich. Es heißt aber auch, dem Kernel etwas Unwahres über die Topologie zu erzählen. In Ordnung auf einer Kiste, deren Gästen du so viel traust wie dem Host. Sonst nicht in Ordnung. Mehr zum Warum steht in dem Beitrag über die IOMMU-Steuer.

Latenz und Zittern

pcie_aspm=off processor.max_cstate=1 amd_pstate=disable

pcie_aspm=off hält PCIe-Links aus Zuständen geringer Leistung heraus, damit ein eintreffendes IO nie darauf wartet, dass einer aufwacht. Es kostet ein paar Watt pro Link und nimmt einen Latenzausläufer weg, der schwer zu diagnostizieren ist. Siehe PCIe-ASPM und Passthrough.

processor.max_cstate=1 begrenzt die ACPI-Ruhe auf C1. Achte auf den Treiber: das ist das Stellrad von processor/acpi_idle, auf Intel brauchst du also zusätzlich intel_idle.max_cstate=1, weil intel_idle Vorrang hat. Auf AMD ist dieses hier das richtige.

Es gibt ein echtes Gegenargument. Tiefer Schlaf auf ruhenden Kernen ist das, was dem Paket thermischen und Leistungsspielraum gibt, die beschäftigten Kerne hochzutakten, alles bei C1 festzunageln kann also deine Spitzenfrequenz für einen Thread senken und gleichzeitig den Verbrauch im Ruhezustand heben. Auf einem latenzempfindlichen Host ist der Handel meist gut. Auf einem Host, der Durchsatz jagt, vielleicht nicht. Miss es, statt es zu erben.

amd_pstate=disable fällt auf acpi-cpufreq zurück. Es lohnt sich, die dokumentierten Alternativen zu kennen, bevor man danach greift: passive (der Treiber verlangt eine Leistungsstufe), active (der EPP-Treiber, der zu Leistung oder Effizienz neigt) und guided. active mit Neigung zur Leistung oder passive samt Governor performance bringt oft dieselbe Latenz und behält die feinere Steuerung von CPPC. Und wenn du es abschaltest, setz bewusst einen Governor — auf acpi-cpufreq mit schedutil zu landen kann ein Rückschritt sein.

Speicher

default_hugepagesz=1G hugepages=64

default_hugepagesz=1G allein reserviert nichts. Der Kernel dokumentiert es als Festlegung von „the size of the default HugeTLB page… the default hugetlb size used for shmget(), mmap() and mounting hugetlbfs“ — also der Größe der voreingestellten HugeTLB-Seite: eine Einheit, keine Zuweisung. Die Zuweisung kommt von hugepages=, dokumentiert als „Number of HugeTLB pages to allocate at boot“, die Zahl der beim Start zuzuweisenden Seiten.

Das zählt bei 1 GiB weit mehr als bei 2 MiB, weil zusammenhängende 1-GiB-Bereiche praktisch nicht zu bekommen sind, sobald der Host gelaufen ist und den Speicher zersplittert hat. Der Start ist deine einzige verlässliche Gelegenheit.

Dann muss der Gast mitmachen (hugepages: 1024 in der VM-Konfiguration). Reservierte Seiten, die niemand nutzt, sind nur Speicher, den du nicht zurückbekommst, und du verlierst Ballooning und KSM auf den VMs, die sie nutzen.

Der Handel mit der Sicherheit

mitigations=off

Das ist nicht ein Schalter. Der Kernel klappt es in eine Liste auf, und auf einem Hypervisor sind das die Einträge, auf die es ankommt:

l1tf=off   mds=off   mmio_stale_data=off   kvm.nx_huge_pages=off
gather_data_sampling=off   retbleed=off   spec_rstack_overflow=off
nospectre_v2   nopti   indirect_target_selection=off

Die Zusammenfassung des Kernels selbst lautet „improves system performance, but it may also expose users to several CPU vulnerabilities“ — es verbessert die Leistung des Systems, kann Nutzer aber auch mehreren CPU-Schwachstellen aussetzen. L1TF, MDS und MMIO Stale Data sind speziell Lecks vom Gast zum Host und vom Gast zum Gast, und kvm.nx_huge_pages ist die Mitigation gegen iTLB-Multihit in KVM selbst.

Vertretbar auf einer Kiste mit einem Mandanten, in der jeder Gast so viel Vertrauen hat wie der Host. Nicht vertretbar dort, wo Gäste nicht vertrauenswürdig sind oder verschiedenen Mandanten gehören. Und beachte, dass es sich mit pcie_acs_override stapelt: zwei unabhängige Isolationszusagen, in derselben Zeile entfernt. Es lohnt sich, das mit Absicht zu tun statt durch Erbschaft.

PCIe über USB4 ändert zwei davon

Kommen deine PCIe-Geräte über USB4 oder Thunderbolt — eine externe GPU oder ein NVMe-Gehäuse —, ändern sich zwei der Antworten von oben.

MPS-Tuning ist nicht mehr kostenlos

Auf festen Slots ist pci=pcie_bus_perf ein kleiner kostenloser Gewinn. Der Kernel beschreibt es so:

Set device MPS to the largest allowable MPS based on its parent bus. Also set MRRS (Max Read Request Size) to the largest supported value… for best performance.

Also: die MPS eines Geräts auf den größten anhand seines übergeordneten Busses zulässigen Wert setzen, und die MRRS ebenfalls auf den größten unterstützten Wert, für die beste Leistung.

Der Haken ist, dass es Bridges beim Start konfiguriert, aus der beim Start vorhandenen Topologie. Über USB4 ist Hot-Plug der normale Fall, und ein später hinzugefügtes Gerät kann eine kleinere MPS können als die, auf die die Bridge schon gesetzt wurde.

Der Kernel sagt das Stille laut, während er eine andere Politik anpreist:

pcie_bus_peer2peer — Set every device’s MPS to 128B, which every device is guaranteed to support… This also guarantees that hot-added devices will work.

Also: die MPS jedes Geräts auf 128 B setzen, was jedes Gerät garantiert kann — und das stellt auch sicher, dass im Betrieb hinzugefügte Geräte funktionieren.

Nur eine Politik trägt diese Zusicherung, und es ist die, die alles auf 128 Byte festnagelt — genau das, dem MaxPayloadSize-Tuning entkommen will. Für eine Hot-Plug-Topologie ist pcie_bus_safe (der größte Wert, den alle Geräte unter dem Root Complex können) oder einfach tune_off stehen zu lassen der sicherere Anfang. Der Switch im Tunnel begrenzt die erreichbare MPS ohnehin, die Decke war also nie deine, sie zu heben.

Warum Hot-Plug die Antwort auf die MPS-Politik ändertBeim Start konfiguriert pcie_bus_perf die Bridge aus dem, was es sehen kannBridge — MPS 512Gerät A · 512Gerät B · 512beim Start vorhandenim Betrieb dazu · nur 256passt nichtnichts neu verhandeltIn einem Gehäuse passiert das nie — die Topologie beim Start ist die Topologie für immer. An einemUSB4-Port ist es der Normalfall.Die vier Politiken, und welche der Kernel für Hot-Plug sicher nenntpcie_bus_tune_offdie BIOS-Werte in Ruhe lassenpcie_bus_safegrößter Wert, den alle Geräte unter dem Root Complex könnenpcie_bus_perfgrößter Wert, den der übergeordnete Bus zulässt, pro Gerät — plus MRRSpcie_bus_peer2peer128 B überall —"guarantees that hot-added devices will work"Nur eine Politik trägt diese Zusicherung, und es ist die, die die Payload-Größe wegwirft, für diedu getunt hast.
Die Bridge wird einmal konfiguriert, beim Start, aus den damals vorhandenen Geräten. Alles danach muss mit der Entscheidung leben — was in einem Gehäuse in Ordnung ist und an einem Port nicht.

Der Sicherheitsstapel wird ernst

Externes PCIe heißt, dass jemand ein DMA-fähiges Gerät in deinen Hypervisor stecken kann. Die Thunderbolt-Dokumentation des Kernels ist da direkt:

…the connected devices can be DMA masters and thus read contents of the host memory without CPU and OS knowing about it. There are ways to prevent this by setting up an IOMMU but it is not always available for various reasons.

Also: die angeschlossenen Geräte können DMA-Master sein und damit den Inhalt des Host-Speichers lesen, ohne dass CPU und Betriebssystem davon wissen; es gibt Wege, das mit einer IOMMU zu verhindern, aber die ist aus verschiedenen Gründen nicht immer verfügbar.

Die IOMMU ist die Verteidigung. Zähl jetzt, was die Host-Zeile mit ihr macht. iommu=pt gibt Geräten des Hosts unübersetzte Identitätsdomänen, pcie_acs_override behauptet eine Isolation, die nicht da ist, und mitigations=off schaltet die Mitigations zur Gast-Isolation ab. Jedes ist allein vertretbar. Zusammen, auf einer Maschine mit einem körperlich erreichbaren USB4-Port, stapeln sie sich.

Prüf, wo du stehst:

cat /sys/bus/thunderbolt/devices/domain*/security   # none | user | secure | dponly | usbonly

none neben dieser Boot-Zeile ist eine offene Tür. Sind die Ports für Leute erreichbar, denen du kein Root geben würdest, wäre iommu=pt das Erste, was ich überdenken würde.

Die Gast-Zeile

Das sind die, die in die VM gehören, und drei davon bedeuten hier etwas anderes als auf dem Host.

nmi_watchdog=0 softlockup_panic=0 cpuidle.off=1

cpuidle.off=1 schaltet das cpuidle-Subsystem ab. In einem Gast ist das nahe an kostenlos: die Ruhezustände des Gasts sind Emulation, und es gibt keinen physischen Kern, den man schlafen legen könnte, das Rahmenwerk bringt dir also nur Aufwachlatenz. Auf dem Host ist dasselbe Flag ein echter Handel um Strom und Boost-Spielraum, und es überlappt mit processor.max_cstate=1. Nur auf der Gast-Seite.

softlockup_panic=0 verhindert, dass ein Soft Lockup den Gast in eine Panik schickt. Das schützt in einer VM wirklich, denn ein Soft Lockup dort ist häufig nicht die Schuld des Gasts. Eine weggenommene vCPU sieht genau aus wie eine Aufgabe, die nicht abgeben will. Das ist derselbe Mechanismus, der dahintersteht, warum der Uhr einer VM nicht zu trauen ist. Prüf aber, ob du es brauchst. Auf den meisten Bauten ist es schon 0.

sysctl kernel.softlockup_panic

nmi_watchdog=0 ist das interessante, und es verdient mehr als eine Regel.

Die Watchdog-Frage

Es gibt zwei Melder, die eine Schwelle teilen:

watchdog_thresh= — Set the hard lockup detector stall duration threshold in seconds. The soft lockup detector threshold is set to twice the value. A value of 0 disables both. Default is 10 seconds.

Also: setzt die Schwelle für die Hängedauer des Hard-Lockup-Melders in Sekunden; die Schwelle des Soft-Lockup-Melders wird auf das Doppelte gesetzt; 0 schaltet beide ab; Vorgabe sind 10 Sekunden.

Ein Hard Lockup (nmi_watchdog) schlägt an, wenn eine CPU überhaupt keine Timer-Interrupts mehr annimmt. Ein Soft Lockup schlägt an, wenn eine Aufgabe eine CPU doppelt so lange belegt, ohne abzugeben.

In einem Gast ist es richtig, den Hard-Lockup-Melder abzuschalten. Eine weggenommene vCPU kann ihn ohne eigene Schuld auslösen, und die Arbeit des Melders mit Leistungszählern erzeugt VM-Exits für ein Signal, das nichts als Lärm war.

Auf dem Host ist es eine Ermessensfrage, und sie hängt davon ab, welchem Lärm du tatsächlich nachjagst. Überbuchung hungert Gäste aus, nicht den Host-Kernel — die physischen CPUs des Hosts nehmen weiter Interrupts an, wie voll die VMs auch sind. Der Protokolllärm, den ein beschäftigter Hypervisor wirft, sind also überwiegend Meldungen zu Soft Lockups und RCU-Hängern, nicht Berichte über Hard Lockups per NMI. Ist das der Lärm, wird nmi_watchdog=0 ihn nicht abstellen, und softlockup_panic=0 auch nicht — das stoppt die Panik, nicht die Meldungen.

Die zielgenauen Stellräder sind:

watchdog_thresh=30        # hard 30s, soft 60s — scale to taste
nowatchdog                # honest single flag: disables both detectors
sysctl -w kernel.soft_watchdog=0   # runtime, keeps hard-lockup detection

Es gibt einen eigenen und besseren Grund, den Hard-Lockup-Melder auf einem beschäftigten Host abzuschalten, und er hat nichts mit Lärm zu tun: er verbraucht pro CPU einen Leistungszähler der Hardware. Deshalb nimmt der Parameter rNNN, um ein rohes Perf-Ereignis einzustellen. Machst du Profiling über die PMU oder betreibst du eine absichtlich überbuchte Kiste, in der du Latenzschwankung als Preis der Dichte schon angenommen hast, ist es ein vernünftiger Handel, diesen Zähler zurückzugeben — und kleine Hänger, für die du bewusst unterschrieben hast, sind keine Vorfälle.

Triff die Wahl bloß aus diesem Grund und nicht wegen des Lärms, denn nur einer von beiden stimmt.

consoleblank=0 tut nichts. Der Kernel dokumentiert die Abschaltzeit der Konsole als „A value of 0 disables the blank timer. Defaults to 0.“ — 0 schaltet den Abschalt-Timer ab, und die Vorgabe ist 0. Es ist schon aus. Harmlos, aber es ist der zweite verbreitete Parameter ohne Wirkung, und ihn mitzuschleppen lässt eine Zeile überlegt aussehen, wenn sie kopiert ist.

Kurzübersicht: wohin jedes Flag gehört

FlagHostGastAnmerkungen
iommu=ptjaneinDer Host besitzt die IOMMU. Im Gast nur relevant bei geschachteltem Passthrough mit vIOMMU
amd_iommu=pgtbl_v2janeinDMA-API-Domänen des Hosts. Prüf, dass du v2 bekommen hast und nicht den v1-Rückfall
amd_iommu=on——Keine gültige Option. Der Kernel protokolliert „Unknown option - ‘on’“
pcie_acs_override=…janeinProxmox-Patch, nur Host-Topologie. Schwächt die Isolation von Entwurf her
pcie_aspm=offjaneinIn einem Gast gibt es keine echten PCIe-Links; der Host besitzt den physischen Link
pci=pcie_bus_perfjanicht verlässlichDer Host setzt die MPS auf der Leitung. Nimm stattdessen pcie_bus_safe, wenn Geräte über USB4 kommen
processor.max_cstate=1janeinEchte Ruhezustände gehören dem Host. Auf Intel intel_idle.max_cstate=1 ergänzen
amd_pstate=disablejaneinGäste steuern die CPU-Frequenz nicht
cpuidle.off=1mit VorsichtjaIm Gast kostenlos. Auf dem Host kostet es Boost-Spielraum und überlappt mit max_cstate
nmi_watchdog=0ErmessenjaIm Gast richtig. Auf dem Host: wegen des PMU-Zählers, nicht wegen des Lärms
softlockup_panic=0neinjaHänger im Gast kommen oft vom Scheduler des Hosts. Meist schon die Vorgabe
consoleblank=0——Wirkungslos. Die Kernel-Vorgabe ist schon 0
mitigations=offbeidebeideAuf beiden gültig, mit anderer Risikorechnung: Lecks vom Gast zum Host auf dem Host, Prozess-Isolation im Gast
default_hugepagesz + hugepages=beidebeideHost: er unterlegt VM-Speicher. Gast: eine Last in der VM, die sie will. Andere Zwecke, gleiche Flags
watchdog_thresh= / nowatchdogbeidebeideHost: Hänger ruhigstellen, die du angenommen hast. Gast: dem Melder war nie zu trauen

Drei gehören wirklich auf beide Seiten, und es lohnt sich, genau zu sein, dass „beide“ nicht „aus demselben Grund“ heißt:

  • mitigations=off geht es auf dem Host um Lecks vom Gast zum Host und vom Gast zum Gast. Im Gast geht es um Prozess-Isolation in dieser VM. Du kannst es vernünftig an einer Stelle abschalten und an der anderen nicht.
  • Hugepages unterlegen auf dem Host den Gast-Speicher; im Gast unterlegen sie eine Anwendung. Sie zweimal für denselben Speicher zu reservieren ist Verschwendung, entscheide also, welche Schicht sie will.
  • Watchdog-Tuning ist auf dem Host eine Lärmentscheidung und im Gast eine Richtigkeitsentscheidung.

Alles andere gehört auf eine Seite oder die andere, und zwei davon sind überhaupt keine Wahl.

Die zwei Zeilen

Host, auf einer AMD-Kiste mit Passthrough und einem Mandanten:

GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=pgtbl_v2 iommu=pt pcie_acs_override=downstream,multifunction pcie_aspm=off pci=pcie_bus_perf default_hugepagesz=1G hugepages=64 processor.max_cstate=1 amd_pstate=disable mitigations=off"

Tausch pci=pcie_bus_perf gegen pcie_bus_safe, wenn etwas über USB4 kommt. Lass mitigations=off weg, wenn nicht alle Gäste deine sind. Auf Intel ersetzt intel_iommu=on die AMD-Flags, und intel_idle.max_cstate=1 kommt zur C-State-Grenze dazu.

Linux-Gast:

GRUB_CMDLINE_LINUX_DEFAULT="quiet nmi_watchdog=0 softlockup_panic=0 cpuidle.off=1"

Und lass kvm-clock im Gast in Ruhe — erzwing nicht tsc oder hpet. Die paravirtuelle Uhr gibt es genau deshalb, weil die Zähler nicht deine sind. Das ist das ganze Argument in dem Beitrag über die Zeit in VMs.

Was man löschen sollte

Hast du eine Zeile aus einem Forumsbeitrag geerbt, sind diese zwei das Erste, was rausfliegt, denn sie kosten dich nichts und beweisen, dass die Zeile nie geprüft wurde:

  • amd_iommu=on — keine gültige Option; der Kernel protokolliert „Unknown option - ‘on’“ und macht weiter
  • consoleblank=0 — schon die Vorgabe

Und prüf den Rest nach einem Neustart gegen /proc/cmdline. Jedes Flag auf dieser Zeile sollte eines sein, für das du einen Grund nennen kannst.

Kannst du nicht sagen, was ein Flag tut, ist es kein Tuning. Es ist Aberglaube. Und es wird von jemandem in den nächsten Aufbau kopiert, der dir vertraut.

Quellen