vm-run pasted by mario-goulart on Sat Dec 30 13:17:25 2023

#!/bin/sh
#| -*- scheme -*-
exec csi -s $0 "$@"
|#

(import (chicken base)
        (chicken format)
        (chicken string)
        (chicken pathname)
        (chicken process)
        (chicken process-context))

(define (usage #!optional exit-code)
  (let* ((port (if (and exit-code (not (zero? exit-code)))
                   (current-error-port)
                   (current-output-port)))
         (prog (pathname-strip-directory (program-name)))
         (msg #<#EOF
Usage: #prog [] [] 

:
-mem         RAM size in MB.  Default=2048.
-iso         Path to an iso file to boot from.
-cpus         Number of CPUs to use. Default=2.
-port        SSH port. Default=2222.
-headless          Headless mode.
-nonet             Disable networking.
-vda   Path to an extra disk image.
-emulator     Emulator and arguments to use.  Default: kvm -cpu host.

EOF
))
    (fprintf port msg)
    (when exit-code (exit exit-code))))

(define (die! fmt . args)
  (apply fprintf (cons (current-error-port)
                       (cons (string-append fmt "\n")
                             args)))
  (exit 1))

(define default-emulator "kvm -cpu host") ;; x86-64

(define (run-kvm cpus ram disk port headless? network?
                 #!key iso
                       vda
                       (qemu-params '())
                       emulator)
  (let ((cmd
         (string-append
          (or emulator default-emulator)
          (sprintf " -smp ~a" cpus)
          (sprintf " -m ~a" ram)
          (sprintf " -hda ~a" disk)
          " "
          (if network?
              (sprintf
               (string-append
                "-netdev user,id=net0,ipv6=off,hostfwd=tcp::~a-:22"
                " -device e1000,netdev=net0")
               port)
              "-nic none")
          " "
          (if headless?
              "-display none"
              "-vga std")
          (if iso
              (sprintf " -boot d -cdrom ~a" (qs iso))
              "")
          (if vda
              (sprintf " -drive file=~a,format=qcow2,if=virtio" (qs vda))
              "")
          (if (null? qemu-params)
              ""
              (string-intersperse qemu-params))
          )))
    (print cmd)
    (system* cmd)))

(let ((args (command-line-arguments)))
  (when (null? args)
    (usage 1))

  (when (or (member "-h" args)
            (member "-help" args)
            (member "--help" args))
    (usage 0))

  (let ((disk #f)
        (iso #f)
        (cpus 2)
        (ram 2048)  ;; 2GiB
        (port 2222)
        (headless? #f)
        (network? #t)
        (vda #f)
        (qemu-params '())
        (emulator #f))
    (let loop ((args args))
      (unless (null? args)
        (let ((arg (car args)))
          (cond ((string=? arg "-cpus")
                 (if (null? (cdr args))
                     (die! "-cpus: missing argument.")
                     (begin
                       (set! cpus (cadr args))
                       (loop (cddr args)))))
                ((string=? arg "-mem")
                 (if (null? (cdr args))
                     (die! "-mem: missing argument.")
                     (begin
                       (set! ram (cadr args))
                       (loop (cddr args)))))
                ((string=? arg "-port")
                 (if (null? (cdr args))
                     (die! "-port: missing argument.")
                     (begin
                       (set! port (cadr args))
                       (loop (cddr args)))))
                ((string=? arg "-iso")
                 (if (null? (cdr args))
                     (die! "-iso: missing argument.")
                     (begin
                       (set! iso (cadr args))
                       (loop (cddr args)))))
                ((string=? arg "-vda")
                 (if (null? (cdr args))
                     (die! "-vda: missing argument.")
                     (begin
                       (set! vda (cadr args))
                       (loop (cddr args)))))
                ((string=? arg "-emulator")
                 (if (null? (cdr args))
                     (die! "-emulator: missing argument.")
                     (begin
                       (set! emulator (cadr args))
                       (loop (cddr args)))))
                ((string=? arg "-headless")
                 (set! headless? #t)
                 (loop (cdr args)))
                ((string=? arg "-nonet")
                 (set! network? #f)
                 (loop (cdr args)))
                (else
                 (if (null? (cdr args))
                     (set! disk arg)
                     (begin
                       (set! qemu-params (append qemu-params (list arg)))
                       (loop (cdr args)))))))))

    (unless disk
      (usage 1))

    (run-kvm cpus ram disk port headless? network?
             iso: iso
             vda: vda
             qemu-params: qemu-params
             emulator: emulator)))

Virtio-related kernel config added by mario-goulart on Sat Dec 30 13:54:40 2023

CONFIG_VIRTIO_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS_COMMON=m
CONFIG_VIRTIO_BLK=m
CONFIG_VIRTIO_NET=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=m
CONFIG_VIRTIO_PCI_LIB=m
CONFIG_VIRTIO_PCI_LIB_LEGACY=m
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_PMEM=m
CONFIG_VIRTIO_BALLOON=m
# CONFIG_VIRTIO_MEM is not set
CONFIG_VIRTIO_INPUT=m
CONFIG_VIRTIO_MMIO=m
# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
CONFIG_VIRTIO_DMA_SHARED_BUFFER=m
# CONFIG_VIRTIO_IOMMU is not set
CONFIG_VIRTIO_FS=m