Skip to content

Commit 5d2e54d

Browse files
authored
fix: simplify QEMU machine config and reduce boot overhead (#2346)
Remove the QEMU_USE_MICROVM env-gated microvm machine type path. Always use q35 (x86_64) or virt (aarch64) with unnecessary subsystems disabled. Strip redundant QEMU flags already implied by -nodefaults, suppress PXE ROM loading on virtio-net, add kernel parameters to skip unneeded init work, and reduce SSH readiness polling from 500ms to 100ms. This allows for faster boot times. Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
1 parent 4aa633a commit 5d2e54d

File tree

1 file changed

+20
-49
lines changed

1 file changed

+20
-49
lines changed

pkg/container/qemu_runner.go

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -627,13 +627,6 @@ func createMicroVM(ctx context.Context, cfg *Config) error {
627627
}
628628

629629
baseargs := []string{}
630-
bios := false
631-
useVM := false
632-
if qemuVM, ok := os.LookupEnv("QEMU_USE_MICROVM"); ok {
633-
if val, err := strconv.ParseBool(qemuVM); err == nil {
634-
useVM = val
635-
}
636-
}
637630

638631
kernelConsole := ""
639632
// If the log level is debug, then crank up the logging.
@@ -662,41 +655,15 @@ func createMicroVM(ctx context.Context, cfg *Config) error {
662655
machineMemorySuffix = ",memory-backend=mem"
663656
}
664657

665-
if useVM {
666-
// load microvm profile and bios, shave some milliseconds from boot
667-
// using this will make a complete boot->initrd (with working network) In ~700ms
668-
// instead of ~900ms.
669-
for _, p := range []string{
670-
"/usr/share/qemu/bios-microvm.bin",
671-
"/usr/share/seabios/bios-microvm.bin",
672-
} {
673-
if _, err := os.Stat(p); err == nil && cfg.Arch.ToAPK() != "aarch64" {
674-
// only enable pcie for network, enable RTC for kernel, disable i8254PIT, i8259PIC and serial port
675-
baseargs = append(baseargs, "-machine", "microvm,x-option-roms=off,rtc=on,pcie=on,pit=off,pic=off,isa-serial=on"+machineMemorySuffix)
676-
baseargs = append(baseargs, "-bios", p)
677-
// microvm in qemu any version tested will not send hvc0/virtconsole to stdout
678-
if log.Enabled(ctx, slog.LevelDebug) {
679-
kernelConsole = "console=ttyS0"
680-
serialArgs = []string{"-serial", "stdio"}
681-
}
682-
bios = true
683-
break
684-
}
685-
}
686-
}
687-
688-
// we need to fall back to -machine virt if no microVM BIOS was found (or QEMU_USE_MICROVM is false)
689-
if !bios {
690-
// aarch64 supports virt machine type, let's use that if we're on it, else
691-
// if we're on x86 arch, but without microvm machine type, let's go to q35
692-
switch cfg.Arch.ToAPK() {
693-
case "aarch64":
694-
baseargs = append(baseargs, "-machine", "virt"+machineMemorySuffix)
695-
case "x86_64":
696-
baseargs = append(baseargs, "-machine", "q35"+machineMemorySuffix)
697-
default:
698-
return fmt.Errorf("unknown architecture: %s", cfg.Arch.ToAPK())
699-
}
658+
// aarch64 supports virt machine type, let's use that if we're on it, else
659+
// if we're on x86 arch, but without microvm machine type, let's go to q35
660+
switch cfg.Arch.ToAPK() {
661+
case "aarch64":
662+
baseargs = append(baseargs, "-machine", "virt"+machineMemorySuffix)
663+
case "x86_64":
664+
baseargs = append(baseargs, "-machine", "q35,hpet=off,smm=off,pit=off,i8042=off,sata=off,smbus=off,usb=off,vmport=off,graphics=off"+machineMemorySuffix)
665+
default:
666+
return fmt.Errorf("unknown architecture: %s", cfg.Arch.ToAPK())
700667
}
701668

702669
// default to use 85% of available memory, if a mem limit is set, respect it.
@@ -771,22 +738,26 @@ func createMicroVM(ctx context.Context, cfg *Config) error {
771738
baseargs = append(baseargs, "-display", "none")
772739
baseargs = append(baseargs, "-no-reboot")
773740
baseargs = append(baseargs, "-no-user-config")
774-
baseargs = append(baseargs, "-nographic")
775741
baseargs = append(baseargs, "-nodefaults")
776-
baseargs = append(baseargs, "-parallel", "none")
777742
baseargs = append(baseargs, serialArgs...)
778-
baseargs = append(baseargs, "-vga", "none")
779743
// use -netdev + -device instead of -nic, as this is better supported by microvm machine type
780744
baseargs = append(baseargs, "-netdev", "user,id=id1,hostfwd=tcp:"+cfg.SSHAddress+"-:22,hostfwd=tcp:"+cfg.SSHControlAddress+"-:2223")
781-
baseargs = append(baseargs, "-device", "virtio-net-pci,netdev=id1")
745+
baseargs = append(baseargs, "-device", "virtio-net-pci,netdev=id1,romfile=")
782746
// add random generator via pci, improve ssh startup time
783747
baseargs = append(baseargs, "-device", "virtio-rng-pci,rng=rng0", "-object", "rng-random,filename=/dev/urandom,id=rng0")
784748
// panic=-1 ensures that if the init fails, we immediately exit the machine
785749
// Add default SSH keys to the VM
786750
sshkey := base64.StdEncoding.EncodeToString(pubKey)
787751

788752
// Build kernel command line arguments
789-
kernelArgs := kernelConsole + " nomodeset random.trust_cpu=on no_timer_check cryptomgr.notests rcupdate.rcu_expedited=1 panic=-1 " + cmdlineVar + " sshkey=" + sshkey + " melange_qemu_runner=1"
753+
kernelArgs := kernelConsole +
754+
" nomodeset random.trust_cpu=on" +
755+
" noapic nomodules 8250.nr_uarts=0 tsc=reliable" +
756+
" no_timer_check cryptomgr.notests" +
757+
" rcupdate.rcu_expedited=1 panic=-1" +
758+
" pci=lastbus=0 ftrace=off swiotlb=noforce edd=off " +
759+
cmdlineVar + " sshkey=" + sshkey +
760+
" melange_qemu_runner=1"
790761

791762
// Check for TESTING environment variable and pass it to microvm-init
792763
// TESTING must be a number (0 for disabled, non-zero for enabled)
@@ -933,7 +904,7 @@ func createMicroVM(ctx context.Context, cfg *Config) error {
933904

934905
clog.FromContext(ctx).Info("qemu: waiting for SSH")
935906
go func() {
936-
// one-min timeout with a 500ms sleep
907+
// 100ms timeout with a 100ms sleep
937908
retries := 60
938909
try := 0
939910
for try < retries {
@@ -942,7 +913,7 @@ func createMicroVM(ctx context.Context, cfg *Config) error {
942913
}
943914

944915
try++
945-
time.Sleep(time.Millisecond * 500)
916+
time.Sleep(time.Millisecond * 100)
946917

947918
log.Debugf("qemu: waiting for ssh to come up, try %d of %d", try, retries)
948919
err = checkSSHServer(cfg.SSHAddress)

0 commit comments

Comments
 (0)