diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm index 7e269b43e70f..b18f48464cee 100644 --- a/nixos/lib/test-driver/Machine.pm +++ b/nixos/lib/test-driver/Machine.pm @@ -33,9 +33,20 @@ sub new { $startCommand = "qemu-kvm -m 384 " . "-net nic,model=virtio \$QEMU_OPTS "; - my $iface = $args->{hdaInterface} || "virtio"; - $startCommand .= "-drive file=" . Cwd::abs_path($args->{hda}) . ",if=$iface,werror=report " - if defined $args->{hda}; + + if (defined $args->{hda}) { + if ($args->{hdaInterface} eq "scsi") { + $startCommand .= "-drive id=hda,file=" + . Cwd::abs_path($args->{hda}) + . ",werror=report,if=none " + . "-device scsi-hd,drive=hda "; + } else { + $startCommand .= "-drive file=" . Cwd::abs_path($args->{hda}) + . ",if=" . $args->{hdaInterface} + . ",werror=report "; + } + } + $startCommand .= "-cdrom $args->{cdrom} " if defined $args->{cdrom}; $startCommand .= "-device piix3-usb-uhci -drive id=usbdisk,file=$args->{usb},if=none,readonly -device usb-storage,drive=usbdisk " diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 3d4bd315f812..66ff43c8547d 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -27,6 +27,21 @@ let kernelConsole = if cfg.graphics then "" else "console=${qemuSerialDevice}"; ttys = [ "tty1" "tty2" "tty3" "tty4" "tty5" "tty6" ]; + # XXX: This is very ugly and in the future we really should use attribute + # sets to build ALL of the QEMU flags instead of this mixed mess of Nix + # expressions and shell script stuff. + mkDiskIfaceDriveFlag = idx: driveArgs: let + inherit (cfg.qemu) diskInterface; + # The drive identifier created by incrementing the index by one using the + # shell. + drvId = "drive$((${idx} + 1))"; + # NOTE: DO NOT shell escape, because this may contain shell variables. + commonArgs = "index=${idx},id=${drvId},${driveArgs}"; + isSCSI = diskInterface == "scsi"; + devArgs = "${diskInterface}-hd,drive=${drvId}"; + args = "-drive ${commonArgs},if=none -device lsi53c895a -device ${devArgs}"; + in if isSCSI then args else "-drive ${commonArgs},if=${diskInterface}"; + # Shell script to start the VM. startVM = '' @@ -68,7 +83,7 @@ let if ! test -e "empty$idx.qcow2"; then ${qemu}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M" fi - extraDisks="$extraDisks -drive index=$idx,file=$(pwd)/empty$idx.qcow2,if=${cfg.qemu.diskInterface},werror=report" + extraDisks="$extraDisks ${mkDiskIfaceDriveFlag "$idx" "file=$(pwd)/empty$idx.qcow2,werror=report"}" idx=$((idx + 1)) '')} @@ -83,14 +98,14 @@ let -virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \ -virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \ ${if cfg.useBootLoader then '' - -drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=${cfg.qemu.diskInterface},cache=writeback,werror=report \ - -drive index=1,id=drive2,file=$TMPDIR/disk.img,media=disk \ + ${mkDiskIfaceDriveFlag "0" "file=$NIX_DISK_IMAGE,cache=writeback,werror=report"} \ + ${mkDiskIfaceDriveFlag "1" "file=$TMPDIR/disk.img,media=disk"} \ ${if cfg.useEFIBoot then '' -pflash $TMPDIR/bios.bin \ '' else '' ''} '' else '' - -drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=${cfg.qemu.diskInterface},cache=writeback,werror=report \ + ${mkDiskIfaceDriveFlag "0" "file=$NIX_DISK_IMAGE,cache=writeback,werror=report"} \ -kernel ${config.system.build.toplevel}/kernel \ -initrd ${config.system.build.toplevel}/initrd \ -append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${kernelConsole} $QEMU_KERNEL_PARAMS" \ @@ -338,11 +353,8 @@ in mkOption { default = "virtio"; example = "scsi"; - type = types.str; - description = '' - The interface used for the virtual hard disks - (virtio or scsi). - ''; + type = types.enum [ "virtio" "scsi" "ide" ]; + description = "The interface used for the virtual hard disks."; }; };