1{
2 pkgs,
3 ...
4}:
5let
6 qemu-img = pkgs.lib.getExe' pkgs.vmTools.qemu "qemu-img";
7 empty = pkgs.runCommand "empty.qcow2" { } ''
8 ${qemu-img} create -f qcow2 "$out" 32M
9 '';
10in
11{
12 name = "iosched";
13 meta.maintainers = with pkgs.lib.maintainers; [ mvs ];
14
15 nodes.machine = {
16 virtualisation.qemu.options = [
17 "-drive"
18 "id=sda,if=none,format=qcow2,readonly=on,file=${empty}"
19 "-drive"
20 "id=sdb,if=none,format=qcow2,readonly=on,file=${empty}"
21 "-drive"
22 "id=nvme0n1,if=none,format=qcow2,readonly=on,file=${empty}"
23 "-drive"
24 "id=mmcblk0,if=none,format=qcow2,file=./mmcblk0.qcow2"
25 "-device"
26 "virtio-scsi-pci,id=scsi0"
27 "-device"
28 "sdhci-pci"
29 "-device"
30 "scsi-hd,rotation_rate=1,bus=scsi0.0,drive=sda"
31 "-device"
32 "scsi-hd,rotation_rate=7200,bus=scsi0.0,drive=sdb"
33 "-device"
34 "sd-card,drive=mmcblk0"
35 "-device"
36 "nvme,serial=deadbeef,drive=nvme0n1"
37 ];
38
39 hardware.block = {
40 defaultScheduler = "none";
41 defaultSchedulerRotational = "mq-deadline";
42 scheduler = {
43 "nvme[0-9]*" = "kyber";
44 "mmcblk[0-9]*" = "bfq";
45 };
46 };
47 };
48
49 testScript = ''
50 import subprocess
51
52 def check_scheduler(dev, scheduler):
53 machine.succeed("grep -F -q '[{}]' /sys/block/{}/queue/scheduler".format(scheduler, dev))
54
55 subprocess.check_call([
56 "${qemu-img}", "create", "-f", "qcow2", "vm-state-machine/mmcblk0.qcow2", "32M"
57 ])
58
59 machine.start()
60 machine.succeed("udevadm verify --no-style")
61 check_scheduler("sda", "none")
62 check_scheduler("sdb", "mq-deadline")
63 check_scheduler("nvme0n1", "kyber")
64 check_scheduler("mmcblk0", "bfq")
65
66 machine.succeed("tmp=\"$(mktemp)\"; losetup /dev/loop0 \"$tmp\"")
67 check_scheduler("loop0", "none")
68 '';
69}