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.";
};
};