#!/usr/bin/env bash
# Check which virtualization technology to use
# We prefer kvm, kqemu, userspace in that order.

export PATH=/usr/sbin:/usr/bin:/sbin:/bin
ARCH="${ARCH-$(uname -m)}"
QEMU_CPU="${QEMU_CPU:-max}"

[[ -x /usr/bin/qemu ]] && BIN=/usr/bin/qemu && ARGS=(-cpu "$QEMU_CPU")
(lsmod | grep -q '^kqemu ') && BIN=/usr/bin/qemu && ARGS=(-kernel-kqemu -cpu host)
[[ -z ${NO_KVM-} && -c /dev/kvm && -x /usr/bin/kvm ]] && BIN=/usr/bin/kvm && ARGS=(-cpu host)
[[ -z ${NO_KVM-} && -c /dev/kvm && -x /usr/bin/qemu-kvm ]] && BIN=/usr/bin/qemu-kvm && ARGS=(-cpu host)
[[ -z ${NO_KVM-} && -c /dev/kvm && -x /usr/libexec/qemu-kvm ]] && BIN=/usr/libexec/qemu-kvm && ARGS=(-cpu host)
[[ -x "/usr/bin/qemu-system-${ARCH}" ]] && BIN="/usr/bin/qemu-system-${ARCH}" && ARGS=(-cpu "$QEMU_CPU")
[[ -z ${NO_KVM-} && -c /dev/kvm && -x "/usr/bin/qemu-system-${ARCH}" ]] && BIN="/usr/bin/qemu-system-${ARCH}" && ARGS=(-enable-kvm -cpu host)

[[ $BIN ]] || {
    echo "Could not find a working KVM or QEMU to test with!" >&2
    echo "Please install kvm or qemu." >&2
    exit 1
}

case "$ARCH" in
    aarch64 | arm64)
        ARGS+=(-M "virt,gic-version=max")
        ;;
    amd64 | i?86 | x86_64)
        ARGS+=(-M q35)
        ;;
    arm | armhf | armv7l)
        ARGS+=(-M virt)
        ;;
    ppc64el | ppc64le)
        ARGS+=(-M "cap-ccf-assist=off,cap-cfpc=broken,cap-ibs=broken,cap-sbbc=broken")
        ;;
esac

# Provide rng device sourcing the hosts /dev/urandom and other standard parameters
ARGS+=(-smp 2 -m 2048 -nodefaults -vga none -display none -no-reboot -watchdog-action poweroff -device virtio-rng-pci)

if ! [[ $* == *-daemonize* ]] && ! [[ $* == *-daemonize* ]]; then
    ARGS+=(-serial stdio)
fi

# virtual hardware watchdog not available on s390x
if [[ $ARCH != "s390x" ]]; then
    ARGS+=(-device i6300esb)
fi

# only set -kernel if -initrd is specified
if [[ $* == *-initrd* ]]; then
    ARGS+=(-kernel "$VMLINUZ")
fi

echo "${0##*/}: $BIN ${ARGS[*]@Q} ${*@Q}"
exec "$BIN" "${ARGS[@]}" "$@"
