diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 81ba85fe27f..6c505c60745 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -25,7 +25,7 @@ jobs:
 
     steps:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
-      - uses: systemd/mkosi@13eb5b68bd5fb234dd0da3b242d80954faf91b95
+      - uses: systemd/mkosi@87c540a5cf9fe24bb79fa946b9617d10e7f02b7e
 
       # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
       # immediately, we remove the files in the background. However, we first move them to a different location
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
index 6ed7a48efa1..69bbb6f6b87 100644
--- a/.github/workflows/mkosi.yml
+++ b/.github/workflows/mkosi.yml
@@ -120,7 +120,7 @@ jobs:
 
     steps:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
-      - uses: systemd/mkosi@13eb5b68bd5fb234dd0da3b242d80954faf91b95
+      - uses: systemd/mkosi@87c540a5cf9fe24bb79fa946b9617d10e7f02b7e
 
       # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
       # immediately, we remove the files in the background. However, we first move them to a different location
diff --git a/mkosi.conf b/mkosi.conf
index 1ae273a5daf..a9d096815a8 100644
--- a/mkosi.conf
+++ b/mkosi.conf
@@ -30,6 +30,7 @@ RepartDirectories=mkosi.repart
 OutputDirectory=build/mkosi.output
 
 [Build]
+History=yes
 ToolsTree=default
 BuildDirectory=build/mkosi.builddir
 CacheDirectory=build/mkosi.cache
diff --git a/test/TEST-53-ISSUE-16347/meson.build b/test/TEST-53-ISSUE-16347/meson.build
index 4c764a21c39..cb9e6a6d4ec 100644
--- a/test/TEST-53-ISSUE-16347/meson.build
+++ b/test/TEST-53-ISSUE-16347/meson.build
@@ -3,9 +3,7 @@
 integration_tests += [
         integration_test_template + {
                 'name' : fs.name(meson.current_source_dir()),
-                'mkosi-args' : integration_test_template['mkosi-args'] + [
-                        '--configure-script', meson.current_source_dir() / 'mkosi.configure',
-                ],
+                'rtc' : true,
                 'vm' : true,
         },
 ]
diff --git a/test/TEST-53-ISSUE-16347/mkosi.configure b/test/TEST-53-ISSUE-16347/mkosi.configure
deleted file mode 100755
index d754fe46e2b..00000000000
--- a/test/TEST-53-ISSUE-16347/mkosi.configure
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-RTC="$(date -u +%Y-%m-%dT%H:%M:%S -d "+3 days")"
-jq ".QemuArgs += [\"-rtc\", \"base=$RTC\"]"
diff --git a/test/TEST-64-UDEV-STORAGE/btrfs_basic.configure b/test/TEST-64-UDEV-STORAGE/btrfs_basic.configure
deleted file mode 100755
index 85ec983fc33..00000000000
--- a/test/TEST-64-UDEV-STORAGE/btrfs_basic.configure
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
-
-for i in range(4):
-    id = f"drivebtrfsbasic{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "350M" if i == 0 else "128M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += [
-        "-device",
-        f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefbtrfs{i}",
-    ]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure b/test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure
deleted file mode 100755
index 1d7a0c5b9a1..00000000000
--- a/test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
-
-for i in range(4):
-    id = f"driveiscsibasic{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "150M" if i == 0 else "70M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += [
-        "-device",
-        f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefiscsi{i}",
-    ]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure b/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure
deleted file mode 100755
index a920171add0..00000000000
--- a/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-config["Drives"] += [
-    {
-        "Id": "drive0",
-        "Size": "64M",
-        "Options": "cache=unsafe",
-    }
-]
-config["QemuArgs"] += ["-device", "pci-bridge,id=pci_bridge0,chassis_nr=64"]
-
-# Create 25 additional PCI bridges, each one connected to the previous one
-# (basically a really long extension cable), and attach a virtio drive to
-# the last one. This should force udev into attempting to create a device
-# unit with a _really_ long name.
-for bridge in range(1, 26):
-    config["QemuArgs"] += [
-        "-device",
-        f"pci-bridge,id=pci_bridge{bridge},bus=pci_bridge{bridge - 1},chassis_nr={64 + bridge},addr=1",
-    ]
-
-config["QemuArgs"] += ["-device", f"virtio-blk-pci,drive=drive0,bus=pci_bridge25,addr=1,serial=long-sysfs-path"]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/lvm_basic.configure b/test/TEST-64-UDEV-STORAGE/lvm_basic.configure
deleted file mode 100755
index c4074becb46..00000000000
--- a/test/TEST-64-UDEV-STORAGE/lvm_basic.configure
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
-
-for i in range(4):
-    id = f"drivelvmbasic{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "32M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += [
-        "-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeeflvm{i}",
-    ]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/mdadm_basic.configure b/test/TEST-64-UDEV-STORAGE/mdadm_basic.configure
deleted file mode 100755
index d722e081e28..00000000000
--- a/test/TEST-64-UDEV-STORAGE/mdadm_basic.configure
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
-
-for i in range(5):
-    id = f"drivemdadmbasic{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "64M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += [
-        "-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefmdadm{i}",
-    ]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure b/test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure
deleted file mode 100755
index d669895925c..00000000000
--- a/test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
-
-for i in range(5):
-    id = f"drivemdadmlvm{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "64M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += [
-        "-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefmdadmlvm{i}",
-    ]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/meson.build b/test/TEST-64-UDEV-STORAGE/meson.build
index a91c23ae170..f1045e89b4a 100644
--- a/test/TEST-64-UDEV-STORAGE/meson.build
+++ b/test/TEST-64-UDEV-STORAGE/meson.build
@@ -11,31 +11,253 @@ unit = configure_file(
         },
 )
 
-foreach testcase : [
-        'btrfs_basic',
-        'iscsi_lvm',
-        'long_sysfs_path',
-        'lvm_basic',
-        'mdadm_basic',
-        'mdadm_lvm',
-        'multipath_basic_failover',
-        'nvme_basic',
-        'nvme_subsystem',
-        'simultaneous_events',
-        'virtio_scsi_basic',
-        'virtio_scsi_identically_named_partitions',
-]
+udev_storage_tests = []
+
+cmdline = []
+qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
+
+foreach i : range(4)
+        id = f'drivebtrfsbasic@i@'
+        size = i == 0 ? '350M' : '128M'
+        cmdline += [f'--drive=@id@:@size@::cache=unsafe']
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefbtrfs@i@']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'btrfs_basic',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
+
+foreach i : range(4)
+        id = f'driveiscsibasic@i@'
+        size = i == 0 ? '150M' : '70M'
+        cmdline += [f'--drive=@id@:@size@::cache=unsafe']
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefiscsi@i@']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'iscsi_lvm',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = ['--drive=drive0:64M::cache=unsafe']
+qemu_args = ['-device', 'pci-bridge,id=pci_bridge0,chassis_nr=64']
+
+# Create 25 additional PCI bridges, each one connected to the previous one
+# (basically a really long extension cable), and attach a virtio drive to
+# the last one. This should force udev into attempting to create a device
+# unit with a _really_ long name.
+foreach bridge : range(1, 26)
+        bus = bridge - 1
+        chassis = 64 + bridge
+        qemu_args += ['-device', f'pci-bridge,id=pci_bridge@bridge@,bus=pci_bridge@bus@,chassis_nr=@chassis@,addr=1']
+endforeach
+
+qemu_args += ['-device', 'virtio-blk-pci,drive=drive0,bus=pci_bridge25,addr=1,serial=long-sysfs-path']
+
+udev_storage_tests += {
+        'name' : 'long_sysfs_path',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
+
+foreach i : range(4)
+        id = f'drivelvmbasic@i@'
+        cmdline += [f'--drive=@id@:32M::cache=unsafe']
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeeflvm@i@']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'lvm_basic',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
+
+foreach i : range(5)
+        id = f'drivemdadmbasic@i@'
+        cmdline += [f'--drive=@id@:64M::cache=unsafe']
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefmdadm@i@']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'mdadm_basic',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
+
+foreach i : range(5)
+        id = f'drivemdadmlvm@i@'
+        cmdline += [f'--drive=@id@:64M::cache=unsafe']
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefmdadmlvm@i@']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'mdadm_lvm',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = []
+
+# Add 16 multipath devices, each backed by 4 paths
+foreach ndisk : range(16)
+        ndiskfmt = ndisk >= 10 ? f'00@ndisk@' : f'000@ndisk@'
+        wwn = f'0xDEADDEADBEEF@ndiskfmt@'
+        size = ndisk == 0 ? '16M' : '1M'
+
+        foreach nback : range(4)
+                id = f'drive@ndisk@x@nback@'
+                cmdline += [f'--drive=@id@:@size@::cache=unsafe:@ndisk@']
+                qemu_args += ['-device', f'scsi-hd,drive=@id@,serial=MPIO@ndisk@,wwn=@wwn@']
+        endforeach
+endforeach
+
+udev_storage_tests += {
+        'name' : 'multipath_basic_failover',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = []
+
+foreach i : range(10)
+        id = f'drivesimultaneousevents@i@'
+        cmdline += [f'--drive=@id@:128M::cache=unsafe']
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,serial=deadbeeftest@i@']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'simultaneous_events',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+cmdline = []
+qemu_args = []
+
+foreach i : range(4)
+        qemu_args += ['-device', f'virtio-scsi-pci,id=scsi@i@']
+endforeach
+
+foreach i : range(128)
+        id = f'drive@i@'
+        cmdline += [f'--drive=@id@:1M::cache=unsafe']
+        div = i / 32
+        mod = i % 32
+        qemu_args += ['-device', f'scsi-hd,drive=@id@,bus=scsi@div@.0,channel=0,scsi-id=@mod@,lun=0']
+endforeach
+
+udev_storage_tests += {
+        'name' : 'virtio_scsi_basic',
+        'cmdline' : cmdline,
+        'qemu-args' : qemu_args,
+}
+
+qemu = find_program('qemu-system-@0@'.format(host_machine.cpu_family()), 'qemu-kvm', dirs : ['/usr/libexec'], native : true, required : false)
+if qemu.found()
+        devices = run_command(qemu, '-device', 'help', check : true).stdout().strip()
+        if devices.contains('name "nvme"')
+                cmdline = []
+                qemu_args = []
+
+                foreach i : range(20)
+                        cmdline += [f'--drive=nvme@i@:1M::cache=unsafe']
+                endforeach
+
+                foreach i : range(5)
+                        qemu_args += ['-device', f'nvme,drive=nvme@i@,serial=deadbeef@i@,max_ioqpairs=8']
+                endforeach
+
+                foreach i : range(5, 10)
+                        qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial=    deadbeef  @i@   ,max_ioqpairs=8"']
+                endforeach
+
+                foreach i : range(10, 15)
+                        qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial=    dead/beef/@i@   ,max_ioqpairs=8"']
+                endforeach
+
+                foreach i : range(15, 20)
+                        qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial=dead/../../beef/@i@,max_ioqpairs=8"']
+                endforeach
+
+                udev_storage_tests += {
+                        'name' : 'nvme_basic',
+                        'cmdline' : cmdline,
+                        'qemu-args' : qemu_args,
+                }
+
+                cmdline = []
+
+                foreach id : ['nvme0', 'nvme1']
+                        cmdline += [f'--drive=@id@:1M::cache=unsafe']
+                endforeach
+
+                qemu_args = [
+                        # Create an NVM Subsystem Device
+                        '-device', 'nvme-subsys,id=nvme-subsys-64,nqn=subsys64',
+                        # Attach two NVM controllers to it
+                        '-device', 'nvme,subsys=nvme-subsys-64,serial=deadbeef',
+                        '-device', 'nvme,subsys=nvme-subsys-64,serial=deadbeef',
+                        # And create two shared namespaces attached to both controllers
+                        '-device', 'nvme-ns,drive=nvme0,nsid=16,shared=on',
+                        '-device', 'nvme-ns,drive=nvme1,nsid=17,shared=on',
+                ]
+
+                udev_storage_tests += {
+                        'name' : 'nvme_subsystem',
+                        'cmdline' : cmdline,
+                        'qemu-args' : qemu_args,
+                }
+        endif
+
+        if devices.contains('name "virtio-scsi-pci"')
+                cmdline = []
+                qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0,num_queues=4']
+
+                foreach i : range(16)
+                        id = f'drive@i@'
+                        cmdline += [f'--drive=@id@:40M::cache=unsafe']
+                        qemu_args += ['-device', f'scsi-hd,drive=@id@,bus=scsi0.0,channel=0,scsi-id=0,lun=@i@']
+                endforeach
+
+                udev_storage_tests += {
+                        'name' : 'virtio_scsi_identically_named_partitions',
+                        'cmdline' : cmdline,
+                        'qemu-args' : qemu_args,
+                }
+        endif
+endif
+
+
+foreach testcase : udev_storage_tests
+        qemu_args = ' '.join(testcase['qemu-args'])
+        cmdline = testcase['cmdline'] + [f'--qemu-args=@qemu_args@']
+
         integration_tests += [
                 integration_test_template + {
-                        'name' : '@0@-@1@'.format(name, testcase),
+                        'name' : '@0@-@1@'.format(name, testcase['name']),
                         # Make sure the service is still named TEST-64-UDEV-STORAGE.service.
                         'unit' : unit,
                         'cmdline' : integration_test_template['cmdline'] + [
-                                'systemd.setenv=TEST_FUNCTION_NAME=testcase_@0@'.format(testcase)
-                        ],
-                        'mkosi-args' : integration_test_template['mkosi-args'] + [
-                                '--configure-script', files('@0@.configure'.format(testcase)),
+                                'systemd.setenv=TEST_FUNCTION_NAME=testcase_@0@'.format(testcase['name'])
                         ],
+                        'mkosi-args' : integration_test_template['mkosi-args'] + cmdline,
                         'priority' : 10,
                         'vm' : true,
                         # Suppress ASan error
diff --git a/test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure b/test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure
deleted file mode 100755
index a59927c3b7f..00000000000
--- a/test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-# Add 16 multipath devices, each backed by 4 paths
-# We don't use --qemu-drive for this since they have to share the file.
-for ndisk in range(16):
-    wwn = f"0xDEADDEADBEEF{ndisk:04d}"
-    if ndisk == 0:
-        size = "16M"
-    else:
-        size = "1M"
-
-    for nback in range(4):
-        id = f"drive{ndisk}x{nback}"
-        config["Drives"] += [
-            {
-                "Id": id,
-                "Size": size,
-                "Options": "cache=unsafe",
-                "FileId": str(ndisk),
-            }
-        ]
-        config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},serial=MPIO{ndisk},wwn={wwn}"]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/nvme_basic.configure b/test/TEST-64-UDEV-STORAGE/nvme_basic.configure
deleted file mode 100755
index ed8304d8043..00000000000
--- a/test/TEST-64-UDEV-STORAGE/nvme_basic.configure
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import os
-import shutil
-import subprocess
-import sys
-
-
-config = json.load(sys.stdin)
-
-qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}"
-result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE)
-if 'name "nvme"' not in result.stdout:
-    print("nvme device driver is not available, skipping test...", file=sys.stderr)
-    exit(77)
-
-def add_drive(i: int, serial: str) -> None:
-    global config
-    id = f"nvme{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "1M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += ["-device", f"nvme,drive={id},serial={serial},max_ioqpairs=8"]
-
-for i in range(5):
-    add_drive(i, serial=f"deadbeef{i}")
-for i in range(5, 10):
-    add_drive(i, serial=f"    deadbeef  {i}   ")
-for i in range(10, 15):
-    add_drive(i, serial=f"    dead/beef/{i}   ")
-for i in range(15, 20):
-    add_drive(i, serial=f"dead/../../beef/{i}")
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure b/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure
deleted file mode 100755
index ed8b39ac5ff..00000000000
--- a/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import os
-import shutil
-import subprocess
-import sys
-
-
-config = json.load(sys.stdin)
-
-qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}"
-result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE)
-if 'name "nvme"' not in result.stdout:
-    print("nvme device driver is not available, skipping test...", file=sys.stderr)
-    exit(77)
-
-for id in ("nvme0", "nvme1"):
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "1M",
-            "Options": "cache=unsafe",
-        }
-
-    ]
-
-config["QemuArgs"] += [
-    # Create an NVM Subsystem Device
-    "-device", "nvme-subsys,id=nvme-subsys-64,nqn=subsys64",
-    # Attach two NVM controllers to it
-    "-device", "nvme,subsys=nvme-subsys-64,serial=deadbeef",
-    "-device", "nvme,subsys=nvme-subsys-64,serial=deadbeef",
-    # And create two shared namespaces attached to both controllers
-    "-device", "nvme-ns,drive=nvme0,nsid=16,shared=on",
-    "-device", "nvme-ns,drive=nvme1,nsid=17,shared=on",
-]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/simultaneous_events.configure b/test/TEST-64-UDEV-STORAGE/simultaneous_events.configure
deleted file mode 100755
index 668f3e2aa06..00000000000
--- a/test/TEST-64-UDEV-STORAGE/simultaneous_events.configure
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-for i in range(10):
-    id = f"drivesimultaneousevents{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "128M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},serial=deadbeeftest{i}"]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure b/test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure
deleted file mode 100755
index 91e1fe14e55..00000000000
--- a/test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import sys
-
-
-config = json.load(sys.stdin)
-
-for i in range(4):
-    config["QemuArgs"] += ['-device', f"virtio-scsi-pci,id=scsi{i}"]
-
-for i in range(128):
-    id = f"drive{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "1M",
-            "Options": "cache=unsafe",
-        }
-    ]
-    config["QemuArgs"] += [
-        '-device',
-        f"scsi-hd,drive={id},bus=scsi{i // 32}.0,channel=0,"
-        f"scsi-id={i % 32},lun=0",
-    ]
-
-json.dump(config, sys.stdout)
diff --git a/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure b/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure
deleted file mode 100755
index 5ffade58005..00000000000
--- a/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-import json
-import os
-import shutil
-import subprocess
-import sys
-
-
-config = json.load(sys.stdin)
-
-qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}"
-result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE)
-if 'name "virtio-scsi-pci"' not in result.stdout:
-    print("virtio-scsi-pci device driver is not available, skipping test...", file=sys.stderr)
-    exit(77)
-
-num_disk = 16
-
-config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0,num_queues=4"]
-
-for i in range(0, num_disk):
-    id = f"drive{i}"
-    config["Drives"] += [
-        {
-            "Id": id,
-            "Size": "40M",
-            "Options": "cache=unsafe"
-        }
-    ]
-    config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},bus=scsi0.0,channel=0,scsi-id=0,lun={i}"]
-
-json.dump(config, sys.stdout)
diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py
index 746c0f98d91..a87b49bd8b9 100755
--- a/test/integration-test-wrapper.py
+++ b/test/integration-test-wrapper.py
@@ -6,6 +6,7 @@
 import argparse
 import base64
 import dataclasses
+import datetime
 import json
 import os
 import re
@@ -363,6 +364,7 @@ def main() -> None:
     parser.add_argument('--exit-code', required=True, type=int)
     parser.add_argument('--coredump-exclude-regex', required=True)
     parser.add_argument('--sanitizer-exclude-regex', required=True)
+    parser.add_argument('--rtc', action=argparse.BooleanOptionalAction)
     parser.add_argument('mkosi_args', nargs='*')
     args = parser.parse_args()
 
@@ -466,11 +468,19 @@ def main() -> None:
             """
         )
 
+    if args.rtc:
+        if sys.version_info >= (3, 12):
+            now = datetime.datetime.now(datetime.UTC)
+        else:
+            now = datetime.datetime.utcnow()
+
+        rtc = datetime.datetime.strftime(now, r'%Y-%m-%dT%H:%M:%S')
+    else:
+        rtc = None
+
     cmd = [
         args.mkosi,
         '--directory', os.fspath(args.meson_source_dir),
-        '--output-dir', os.fspath(args.meson_build_dir / 'mkosi.output'),
-        '--extra-search-path', os.fspath(args.meson_build_dir),
         '--machine', name,
         '--ephemeral=yes',
         *(['--forward-journal', journal_file] if journal_file else []),
@@ -485,6 +495,7 @@ def main() -> None:
         '--credential', f'systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}',
         '--runtime-network=none',
         '--runtime-scratch=no',
+        *([f'--qemu-args=-rtc base={rtc}'] if rtc else []),
         *args.mkosi_args,
         '--firmware', args.firmware,
         *(['--kvm', 'no'] if int(os.getenv('TEST_NO_KVM', '0')) else []),
diff --git a/test/meson.build b/test/meson.build
index f2fb5f79ce7..59e9cd36fd0 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -277,191 +277,198 @@ endif
 
 ############################################################
 
-integration_test_wrapper = find_program('integration-test-wrapper.py')
-integration_tests = []
-integration_test_template = {
-        'mkosi-args' : [],
-        'timeout' : 1800,
-        'storage' : 'volatile',
-        'priority' : 0,
-        'firmware' : 'linux',
-        'enabled' : true,
-        'configuration' : {
-                'memory-accounting' : 'no',
-                'command' : testdata_dir / 'units/%N.sh',
-                'wants' : 'multi-user.target user@4711.service',
-                'after' : 'user@4711.service',
-        },
-        'cmdline' : [],
-        'credentials' : [],
-        'qemu-args' : [],
-        'exit-code' : 123,
-        'vm' : false,
-        'coredump-exclude-regex' : '',
-        'sanitizer-exclude-regex' : '',
-}
-testdata_subdirs = [
-        'auxv',
-        'journal-data',
-        'knot-data',
-        'test-journals',
-        'units',
-        'test-execute',
-        'test-fstab-generator',
-        'test-path',
-        'test-path-util',
-        'test-umount',
-        'test-network',
-        'test-network-generator-conversion',
-]
-
-foreach dirname : [
-        'TEST-01-BASIC',
-        'TEST-02-UNITTESTS',
-        'TEST-03-JOBS',
-        'TEST-04-JOURNAL',
-        'TEST-05-RLIMITS',
-        'TEST-06-SELINUX',
-        'TEST-07-PID1',
-        'TEST-08-INITRD',
-        'TEST-09-REBOOT',
-        'TEST-13-NSPAWN',
-        'TEST-15-DROPIN',
-        'TEST-16-EXTEND-TIMEOUT',
-        'TEST-17-UDEV',
-        'TEST-18-FAILUREACTION',
-        'TEST-19-CGROUP',
-        'TEST-21-DFUZZER',
-        'TEST-22-TMPFILES',
-        'TEST-23-UNIT-FILE',
-        'TEST-24-CRYPTSETUP',
-        'TEST-25-IMPORT',
-        'TEST-26-SYSTEMCTL',
-        'TEST-29-PORTABLE',
-        'TEST-30-ONCLOCKCHANGE',
-        'TEST-31-DEVICE-ENUMERATION',
-        'TEST-32-OOMPOLICY',
-        'TEST-34-DYNAMICUSERMIGRATE',
-        'TEST-35-LOGIN',
-        'TEST-36-NUMAPOLICY',
-        'TEST-38-FREEZER',
-        'TEST-43-PRIVATEUSER-UNPRIV',
-        'TEST-44-LOG-NAMESPACE',
-        'TEST-45-TIMEDATE',
-        'TEST-46-HOMED',
-        'TEST-50-DISSECT',
-        'TEST-52-HONORFIRSTSHUTDOWN',
-        'TEST-53-ISSUE-16347',
-        'TEST-54-CREDS',
-        'TEST-55-OOMD',
-        'TEST-58-REPART',
-        'TEST-59-RELOADING-RESTART',
-        'TEST-60-MOUNT-RATELIMIT',
-        'TEST-62-RESTRICT-IFACES',
-        'TEST-63-PATH',
-        'TEST-64-UDEV-STORAGE',
-        'TEST-65-ANALYZE',
-        'TEST-66-DEVICE-ISOLATION',
-        'TEST-67-INTEGRITY',
-        'TEST-68-PROPAGATE-EXIT-STATUS',
-        'TEST-69-SHUTDOWN',
-        'TEST-70-TPM2',
-        'TEST-71-HOSTNAME',
-        'TEST-72-SYSUPDATE',
-        'TEST-73-LOCALE',
-        'TEST-74-AUX-UTILS',
-        'TEST-75-RESOLVED',
-        'TEST-76-SYSCTL',
-        'TEST-78-SIGQUEUE',
-        'TEST-79-MEMPRESS',
-        'TEST-80-NOTIFYACCESS',
-        'TEST-81-GENERATORS',
-        'TEST-82-SOFTREBOOT',
-        'TEST-83-BTRFS',
-        'TEST-84-STORAGETM',
-        'TEST-85-NETWORK',
-        'TEST-86-MULTI-PROFILE-UKI',
-        'TEST-87-AUX-UTILS-VM',
-]
-        subdir(dirname)
-endforeach
-
-foreach integration_test : integration_tests
-        integration_test_args = [
-                '--meson-source-dir', meson.project_source_root(),
-                '--meson-build-dir', meson.project_build_root(),
-                '--name', integration_test['name'],
-                '--storage', integration_test['storage'],
-                '--firmware', integration_test['firmware'],
-                '--exit-code', integration_test['exit-code'].to_string(),
-                '--coredump-exclude-regex', integration_test['coredump-exclude-regex'],
-                '--sanitizer-exclude-regex', integration_test['sanitizer-exclude-regex'],
+if want_tests != 'false'
+        integration_test_wrapper = find_program('integration-test-wrapper.py')
+        integration_tests = []
+        integration_test_template = {
+                'mkosi-args' : [],
+                'timeout' : 1800,
+                'storage' : 'volatile',
+                'priority' : 0,
+                'firmware' : 'linux',
+                'enabled' : true,
+                'configuration' : {
+                        'memory-accounting' : 'no',
+                        'command' : testdata_dir / 'units/%N.sh',
+                        'wants' : 'multi-user.target user@4711.service',
+                        'after' : 'user@4711.service',
+                },
+                'cmdline' : [],
+                'credentials' : [],
+                'qemu-args' : [],
+                'exit-code' : 123,
+                'vm' : false,
+                'coredump-exclude-regex' : '',
+                'sanitizer-exclude-regex' : '',
+                'rtc' : false,
+        }
+        testdata_subdirs = [
+                'auxv',
+                'journal-data',
+                'knot-data',
+                'test-journals',
+                'units',
+                'test-execute',
+                'test-fstab-generator',
+                'test-path',
+                'test-path-util',
+                'test-umount',
+                'test-network',
+                'test-network-generator-conversion',
         ]
 
-        if 'unit' in integration_test
-                integration_test_unit = integration_test['unit']
-        else
-                integration_test_unit = configure_file(
-                        input : 'test.service.in',
-                        output : '@0@.service'.format(integration_test['name']),
-                        configuration : integration_test['configuration'],
-                )
-        endif
-
-        integration_test_args += ['--unit', fs.name(integration_test_unit)]
-        if install_tests
-                install_data(integration_test_unit, install_dir : testdata_dir / 'units')
-        endif
-
-        if integration_test['vm']
-                integration_test_args += ['--vm']
-        endif
-
-        if not mkosi.found()
-                continue
-        endif
-
-        integration_test_args += ['--mkosi', mkosi.full_path(), '--']
-
-        if integration_test['cmdline'].length() > 0
-                integration_test_args += [
-                        '--kernel-command-line-extra=@0@'.format(' '.join(integration_test['cmdline']))
-                ]
-        endif
-
-        foreach credential : integration_test['credentials']
-                integration_test_args += ['--credential', credential]
+        foreach dirname : [
+                'TEST-01-BASIC',
+                'TEST-02-UNITTESTS',
+                'TEST-03-JOBS',
+                'TEST-04-JOURNAL',
+                'TEST-05-RLIMITS',
+                'TEST-06-SELINUX',
+                'TEST-07-PID1',
+                'TEST-08-INITRD',
+                'TEST-09-REBOOT',
+                'TEST-13-NSPAWN',
+                'TEST-15-DROPIN',
+                'TEST-16-EXTEND-TIMEOUT',
+                'TEST-17-UDEV',
+                'TEST-18-FAILUREACTION',
+                'TEST-19-CGROUP',
+                'TEST-21-DFUZZER',
+                'TEST-22-TMPFILES',
+                'TEST-23-UNIT-FILE',
+                'TEST-24-CRYPTSETUP',
+                'TEST-25-IMPORT',
+                'TEST-26-SYSTEMCTL',
+                'TEST-29-PORTABLE',
+                'TEST-30-ONCLOCKCHANGE',
+                'TEST-31-DEVICE-ENUMERATION',
+                'TEST-32-OOMPOLICY',
+                'TEST-34-DYNAMICUSERMIGRATE',
+                'TEST-35-LOGIN',
+                'TEST-36-NUMAPOLICY',
+                'TEST-38-FREEZER',
+                'TEST-43-PRIVATEUSER-UNPRIV',
+                'TEST-44-LOG-NAMESPACE',
+                'TEST-45-TIMEDATE',
+                'TEST-46-HOMED',
+                'TEST-50-DISSECT',
+                'TEST-52-HONORFIRSTSHUTDOWN',
+                'TEST-53-ISSUE-16347',
+                'TEST-54-CREDS',
+                'TEST-55-OOMD',
+                'TEST-58-REPART',
+                'TEST-59-RELOADING-RESTART',
+                'TEST-60-MOUNT-RATELIMIT',
+                'TEST-62-RESTRICT-IFACES',
+                'TEST-63-PATH',
+                'TEST-64-UDEV-STORAGE',
+                'TEST-65-ANALYZE',
+                'TEST-66-DEVICE-ISOLATION',
+                'TEST-67-INTEGRITY',
+                'TEST-68-PROPAGATE-EXIT-STATUS',
+                'TEST-69-SHUTDOWN',
+                'TEST-70-TPM2',
+                'TEST-71-HOSTNAME',
+                'TEST-72-SYSUPDATE',
+                'TEST-73-LOCALE',
+                'TEST-74-AUX-UTILS',
+                'TEST-75-RESOLVED',
+                'TEST-76-SYSCTL',
+                'TEST-78-SIGQUEUE',
+                'TEST-79-MEMPRESS',
+                'TEST-80-NOTIFYACCESS',
+                'TEST-81-GENERATORS',
+                'TEST-82-SOFTREBOOT',
+                'TEST-83-BTRFS',
+                'TEST-84-STORAGETM',
+                'TEST-85-NETWORK',
+                'TEST-86-MULTI-PROFILE-UKI',
+                'TEST-87-AUX-UTILS-VM',
+        ]
+                subdir(dirname)
         endforeach
 
-        if integration_test['qemu-args'].length() > 0
-                integration_test_args += ['--qemu-args=@0@'.format(' '.join(integration_test['qemu-args']))]
-        endif
+        foreach integration_test : integration_tests
+                integration_test_args = [
+                        '--meson-source-dir', meson.project_source_root(),
+                        '--meson-build-dir', meson.project_build_root(),
+                        '--name', integration_test['name'],
+                        '--storage', integration_test['storage'],
+                        '--firmware', integration_test['firmware'],
+                        '--exit-code', integration_test['exit-code'].to_string(),
+                        '--coredump-exclude-regex', integration_test['coredump-exclude-regex'],
+                        '--sanitizer-exclude-regex', integration_test['sanitizer-exclude-regex'],
+                ]
 
-        integration_test_args += integration_test['mkosi-args']
+                if 'unit' in integration_test
+                        integration_test_unit = integration_test['unit']
+                else
+                        integration_test_unit = configure_file(
+                                input : 'test.service.in',
+                                output : '@0@.service'.format(integration_test['name']),
+                                configuration : integration_test['configuration'],
+                        )
+                endif
 
-        integration_test_env = {}
+                integration_test_args += ['--unit', fs.name(integration_test_unit)]
+                if install_tests
+                        install_data(integration_test_unit, install_dir : testdata_dir / 'units')
+                endif
 
-        if want_integration_tests
-                integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
-        endif
+                if integration_test['vm']
+                        integration_test_args += ['--vm']
+                endif
 
-        if not integration_test['enabled']
-                continue
-        endif
+                if integration_test['rtc']
+                        integration_test_args += ['--rtc']
+                endif
 
-        # We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
-        # "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
-        # integration tests with mkosi.
-        test(
-                integration_test['name'],
-                integration_test_wrapper,
-                env : integration_test_env,
-                args : integration_test_args,
-                timeout : integration_test['timeout'],
-                priority : integration_test['priority'],
-                suite : 'integration-tests',
-        )
-endforeach
+                if not mkosi.found()
+                        continue
+                endif
+
+                integration_test_args += ['--mkosi', mkosi.full_path(), '--']
+
+                if integration_test['cmdline'].length() > 0
+                        integration_test_args += [
+                                '--kernel-command-line-extra=@0@'.format(' '.join(integration_test['cmdline']))
+                        ]
+                endif
+
+                foreach credential : integration_test['credentials']
+                        integration_test_args += ['--credential', credential]
+                endforeach
+
+                if integration_test['qemu-args'].length() > 0
+                        integration_test_args += ['--qemu-args=@0@'.format(' '.join(integration_test['qemu-args']))]
+                endif
+
+                integration_test_args += integration_test['mkosi-args']
+
+                integration_test_env = {}
+
+                if want_integration_tests
+                        integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
+                endif
+
+                if not integration_test['enabled']
+                        continue
+                endif
+
+                # We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
+                # "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
+                # integration tests with mkosi.
+                test(
+                        integration_test['name'],
+                        integration_test_wrapper,
+                        env : integration_test_env,
+                        args : integration_test_args,
+                        timeout : integration_test['timeout'],
+                        priority : integration_test['priority'],
+                        suite : 'integration-tests',
+                )
+        endforeach
+endif
 
 if install_tests
         foreach subdir : testdata_subdirs