--- Begin Message ---
The blockdev chain is:
-throttle-group-node (drive-(ide|scsi|virtio)x)
    - format-node (fmt-drive-x)
         - file-node (file-drive -x)

fixme:
 - rbd blockdev don't allow extra options (keyring file for example),
   do we need to patch qemu ? or write client option in a file ?
Signed-off-by: Alexandre Derumier <alexandre.derum...@groupe-cyllene.com>
---
 PVE/QemuServer.pm                             | 172 +-------
 PVE/QemuServer/Drive.pm                       | 400 ++++++++++++++++--
 test/cfg2cmd/bootorder-empty.conf.cmd         |  12 +-
 test/cfg2cmd/bootorder-legacy.conf.cmd        |  12 +-
 test/cfg2cmd/bootorder.conf.cmd               |  12 +-
 ...putype-icelake-client-deprecation.conf.cmd |   6 +-
 test/cfg2cmd/ide.conf.cmd                     |  23 +-
 test/cfg2cmd/pinned-version-pxe-pve.conf.cmd  |   6 +-
 test/cfg2cmd/pinned-version-pxe.conf.cmd      |   6 +-
 test/cfg2cmd/pinned-version.conf.cmd          |   6 +-
 test/cfg2cmd/q35-ide.conf.cmd                 |  23 +-
 .../q35-linux-hostpci-template.conf.cmd       |   3 +-
 test/cfg2cmd/seabios_serial.conf.cmd          |   6 +-
 ...imple-balloon-free-page-reporting.conf.cmd |   6 +-
 test/cfg2cmd/simple-btrfs.conf.cmd            |   6 +-
 test/cfg2cmd/simple-disk-passthrough.conf.cmd |  11 +-
 test/cfg2cmd/simple-rbd.conf.cmd              |   9 +-
 test/cfg2cmd/simple-virtio-blk.conf.cmd       |   6 +-
 test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd   |   6 +-
 test/cfg2cmd/simple1-template.conf.cmd        |  11 +-
 test/cfg2cmd/simple1.conf.cmd                 |   6 +-
 21 files changed, 472 insertions(+), 276 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index ccdceedc..fed0ef2b 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -55,7 +55,7 @@ use PVE::QemuServer::Helpers qw(config_aware_timeout 
min_version kvm_user_versio
 use PVE::QemuServer::Cloudinit;
 use PVE::QemuServer::CGroup;
 use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options 
get_cpu_bitness is_native_arch get_amd_sev_object get_amd_sev_type);
-use PVE::QemuServer::Drive qw(is_valid_drivename checked_volume_format 
drive_is_cloudinit drive_is_cdrom drive_is_read_only parse_drive print_drive);
+use PVE::QemuServer::Drive qw(is_valid_drivename checked_volume_format 
drive_is_cloudinit drive_is_cdrom drive_is_read_only parse_drive print_drive 
print_drive_throttle_group generate_drive_blockdev);
 use PVE::QemuServer::Machine;
 use PVE::QemuServer::Memory qw(get_current_memory);
 use PVE::QemuServer::MetaInfo;
@@ -1367,7 +1367,10 @@ sub print_drivedevice_full {
        } else {
            $device .= ",bus=ahci$controller.$unit";
        }
-       $device .= ",drive=drive-$drive_id,id=$drive_id";
+       $device .= ",id=$drive_id";
+       #with blockdev, empty cdrom device don't have any blockdev attached, so 
drive param can't be declared
+       #with drive=none (and throttle-filter can't be defined without media 
too)
+       $device .= ",drive=drive-$drive_id" if $device_type ne 'cd' || 
$drive->{file} ne 'none';
 
        if ($device_type eq 'hd') {
            if (my $model = $drive->{model}) {
@@ -1393,6 +1396,13 @@ sub print_drivedevice_full {
        $device .= ",serial=$serial";
     }
 
+    my $writecache = $drive->{cache} && $drive->{cache} =~ 
/^(?:none|writeback|unsafe)$/  ? "on" : "off";
+    $device .= ",write-cache=$writecache" if $drive->{media} && 
$drive->{media} ne 'cdrom';
+
+    my @qemu_drive_options = qw(heads secs cyls trans rerror werror);
+    foreach my $o (@qemu_drive_options) {
+       $device .= ",$o=$drive->{$o}" if defined($drive->{$o});
+    }
 
     return $device;
 }
@@ -1411,154 +1421,6 @@ sub get_initiator_name {
     return $initiator;
 }
 
-my sub storage_allows_io_uring_default {
-    my ($scfg, $cache_direct) = @_;
-
-    # io_uring with cache mode writeback or writethrough on krbd will hang...
-    return if $scfg && $scfg->{type} eq 'rbd' && $scfg->{krbd} && 
!$cache_direct;
-
-    # io_uring with cache mode writeback or writethrough on LVM will hang, 
without cache only
-    # sometimes, just plain disable...
-    return if $scfg && $scfg->{type} eq 'lvm';
-
-    # io_uring causes problems when used with CIFS since kernel 5.15
-    # Some discussion: https://www.spinics.net/lists/linux-cifs/msg26734.html
-    return if $scfg && $scfg->{type} eq 'cifs';
-
-    return 1;
-}
-
-my sub drive_uses_cache_direct {
-    my ($drive, $scfg) = @_;
-
-    my $cache_direct = 0;
-
-    if (my $cache = $drive->{cache}) {
-       $cache_direct = $cache =~ /^(?:off|none|directsync)$/;
-    } elsif (!drive_is_cdrom($drive) && !($scfg && $scfg->{type} eq 'btrfs' && 
!$scfg->{nocow})) {
-       $cache_direct = 1;
-    }
-
-    return $cache_direct;
-}
-
-sub print_drive_commandline_full {
-    my ($storecfg, $vmid, $drive, $live_restore_name, $io_uring) = @_;
-
-    my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive);
-
-    my ($storeid) = PVE::Storage::parse_volume_id($drive->{file}, 1);
-    my $scfg = $storeid ? PVE::Storage::storage_config($storecfg, $storeid) : 
undef;
-    my $vtype = $storeid ? (PVE::Storage::parse_volname($storecfg, 
$drive->{file}))[0] : undef;
-
-    my ($path, $format) = PVE::QemuServer::Drive::get_path_and_format(
-       $storecfg, $vmid, $drive, $live_restore_name);
-
-    my $is_rbd = $path =~ m/^rbd:/;
-
-    my $opts = '';
-    my @qemu_drive_options = qw(heads secs cyls trans media cache rerror 
werror aio discard);
-    foreach my $o (@qemu_drive_options) {
-       $opts .= ",$o=$drive->{$o}" if defined($drive->{$o});
-    }
-
-    # snapshot only accepts on|off
-    if (defined($drive->{snapshot})) {
-       my $v = $drive->{snapshot} ? 'on' : 'off';
-       $opts .= ",snapshot=$v";
-    }
-
-    if (defined($drive->{ro})) { # ro maps to QEMUs `readonly`, which accepts 
`on` or `off` only
-       $opts .= ",readonly=" . ($drive->{ro} ? 'on' : 'off');
-    }
-
-    foreach my $type (['', '-total'], [_rd => '-read'], [_wr => '-write']) {
-       my ($dir, $qmpname) = @$type;
-       if (my $v = $drive->{"mbps$dir"}) {
-           $opts .= ",throttling.bps$qmpname=".int($v*1024*1024);
-       }
-       if (my $v = $drive->{"mbps${dir}_max"}) {
-           $opts .= ",throttling.bps$qmpname-max=".int($v*1024*1024);
-       }
-       if (my $v = $drive->{"bps${dir}_max_length"}) {
-           $opts .= ",throttling.bps$qmpname-max-length=$v";
-       }
-       if (my $v = $drive->{"iops${dir}"}) {
-           $opts .= ",throttling.iops$qmpname=$v";
-       }
-       if (my $v = $drive->{"iops${dir}_max"}) {
-           $opts .= ",throttling.iops$qmpname-max=$v";
-       }
-       if (my $v = $drive->{"iops${dir}_max_length"}) {
-           $opts .= ",throttling.iops$qmpname-max-length=$v";
-       }
-    }
-
-    if ($live_restore_name) {
-       $format = "rbd" if $is_rbd;
-       die "$drive_id: Proxmox Backup Server backed drive cannot auto-detect 
the format\n"
-           if !$format;
-       $opts .= ",format=alloc-track,file.driver=$format";
-    } elsif ($format) {
-       $opts .= ",format=$format";
-    }
-
-    my $cache_direct = drive_uses_cache_direct($drive, $scfg);
-
-    $opts .= ",cache=none" if !$drive->{cache} && $cache_direct;
-
-    if (!$drive->{aio}) {
-       if ($io_uring && storage_allows_io_uring_default($scfg, $cache_direct)) 
{
-           # io_uring supports all cache modes
-           $opts .= ",aio=io_uring";
-       } else {
-           # aio native works only with O_DIRECT
-           if($cache_direct) {
-               $opts .= ",aio=native";
-           } else {
-               $opts .= ",aio=threads";
-           }
-       }
-    }
-
-    die "$drive_id: explicit media parameter is required for iso images\n"
-       if !defined($drive->{media}) && defined($vtype) && $vtype eq 'iso';
-
-    if (!drive_is_cdrom($drive)) {
-       my $detectzeroes;
-       if (defined($drive->{detect_zeroes}) && !$drive->{detect_zeroes}) {
-           $detectzeroes = 'off';
-       } elsif ($drive->{discard}) {
-           $detectzeroes = $drive->{discard} eq 'on' ? 'unmap' : 'on';
-       } else {
-           # This used to be our default with discard not being specified:
-           $detectzeroes = 'on';
-       }
-
-       # note: 'detect-zeroes' works per blockdev and we want it to persist
-       # after the alloc-track is removed, so put it on 'file' directly
-       my $dz_param = $live_restore_name ? "file.detect-zeroes" : 
"detect-zeroes";
-       $opts .= ",$dz_param=$detectzeroes" if $detectzeroes;
-    }
-
-    if ($live_restore_name) {
-       $opts .= ",backing=$live_restore_name";
-       $opts .= ",auto-remove=on";
-    }
-
-    # my $file_param = $live_restore_name ? "file.file.filename" : "file";
-    my $file_param = "file";
-    if ($live_restore_name) {
-       # non-rbd drivers require the underlying file to be a separate block
-       # node, so add a second .file indirection
-       $file_param .= ".file" if !$is_rbd;
-       $file_param .= ".filename";
-    }
-    my $pathinfo = $path ? "$file_param=$path," : '';
-
-    return 
"${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
-}
-
 sub print_pbs_blockdev {
     my ($pbs_conf, $pbs_name) = @_;
     my $blockdev = "driver=pbs,node-name=$pbs_name,read-only=on";
@@ -3960,13 +3822,13 @@ sub config_to_command {
            push @$devices, '-blockdev', $live_restore->{blockdev};
        }
 
-       my $drive_cmd = print_drive_commandline_full(
-           $storecfg, $vmid, $drive, $live_blockdev_name, min_version($kvmver, 
6, 0));
+       my $throttle_group = print_drive_throttle_group($drive);
+       push @$devices, '-object', $throttle_group if $throttle_group;
 
        # extra protection for templates, but SATA and IDE don't support it..
-       $drive_cmd .= ',readonly=on' if drive_is_read_only($conf, $drive);
-
-       push @$devices, '-drive',$drive_cmd;
+       $drive->{ro} = 1 if drive_is_read_only($conf, $drive);
+       my $blockdev = generate_drive_blockdev($storecfg, $drive, 
$live_blockdev_name);
+       push @$devices, '-blockdev', 
JSON->new->canonical->allow_nonref->encode($blockdev) if $blockdev;
        push @$devices, '-device', print_drivedevice_full(
            $storecfg, $conf, $vmid, $drive, $bridges, $arch, $machine_type);
     });
diff --git a/PVE/QemuServer/Drive.pm b/PVE/QemuServer/Drive.pm
index 81e1aa04..1a9242e1 100644
--- a/PVE/QemuServer/Drive.pm
+++ b/PVE/QemuServer/Drive.pm
@@ -24,6 +24,8 @@ drive_is_read_only
 get_scsi_devicetype
 parse_drive
 print_drive
+print_drive_throttle_group
+generate_drive_blockdev
 );
 
 our $QEMU_FORMAT_RE = qr/raw|qcow|qcow2|qed|vmdk|cloop/;
@@ -87,7 +89,7 @@ sub get_cdrom_path {
 }
 
 sub get_iso_path {
-    my ($storecfg, $vmid, $cdrom) = @_;
+    my ($storecfg, $cdrom) = @_;
 
     if ($cdrom eq 'cdrom') {
        return get_cdrom_path();
@@ -100,49 +102,6 @@ sub get_iso_path {
     }
 }
 
-# Returns the path that can be used on the QEMU commandline and in QMP 
commands as well as the
-# checked format of the drive.
-sub get_path_and_format {
-    my ($storecfg, $vmid, $drive, $live_restore_name) = @_;
-
-    my $path;
-    my $volid = $drive->{file};
-    my $drive_id = get_drive_id($drive);
-
-    my ($storeid) = PVE::Storage::parse_volume_id($volid, 1);
-
-    if (drive_is_cdrom($drive)) {
-       $path = get_iso_path($storecfg, $vmid, $volid);
-       die "$drive_id: cannot back cdrom drive with a live restore image\n" if 
$live_restore_name;
-    } else {
-       if ($storeid) {
-           $path = PVE::Storage::path($storecfg, $volid);
-       } else {
-           $path = $volid;
-       }
-    }
-
-    # For PVE-managed volumes, use the format from the storage layer and 
prevent overrides via the
-    # drive's 'format' option. For unmanaged volumes, fallback to 'raw' to 
avoid auto-detection by
-    # QEMU. For the special case 'none' (get_iso_path() returns an empty 
$path), there should be no
-    # format or QEMU won't start.
-    my $format;
-    if (drive_is_cdrom($drive) && !$path) {
-       # no format
-    } elsif ($storeid) {
-       $format = checked_volume_format($storecfg, $volid);
-
-       if ($drive->{format} && $drive->{format} ne $format) {
-           die "drive '$drive_id' - volume '$volid' - 
'format=$drive->{format}' option different"
-               ." from storage format '$format'\n";
-       }
-    } else {
-       $format = $drive->{format} // 'raw';
-    }
-
-    return ($path, $format);
-}
-
 my $MAX_IDE_DISKS = 4;
 my $MAX_SCSI_DISKS = 31;
 my $MAX_VIRTIO_DISKS = 16;
@@ -998,4 +957,357 @@ sub get_scsi_device_type {
 
     return $devicetype;
 }
+
+my sub storage_allows_io_uring_default {
+    my ($scfg, $cache_direct) = @_;
+
+    # io_uring with cache mode writeback or writethrough on krbd will hang...
+    return if $scfg && $scfg->{type} eq 'rbd' && $scfg->{krbd} && 
!$cache_direct;
+
+    # io_uring with cache mode writeback or writethrough on LVM will hang, 
without cache only
+    # sometimes, just plain disable...
+    return if $scfg && $scfg->{type} eq 'lvm';
+
+    # io_uring causes problems when used with CIFS since kernel 5.15
+    # Some discussion: https://www.spinics.net/lists/linux-cifs/msg26734.html
+    return if $scfg && $scfg->{type} eq 'cifs';
+
+    return 1;
+}
+
+my sub drive_uses_cache_direct {
+    my ($drive, $scfg) = @_;
+
+    my $cache_direct = 0;
+
+    if (my $cache = $drive->{cache}) {
+       $cache_direct = $cache =~ /^(?:off|none|directsync)$/;
+    } elsif (!drive_is_cdrom($drive) && !($scfg && $scfg->{type} eq 'btrfs' && 
!$scfg->{nocow})) {
+       $cache_direct = 1;
+    }
+
+    return $cache_direct;
+}
+
+sub generate_blockdev_drive_aio {
+    my ($drive, $scfg) = @_;
+
+    my $cache_direct = drive_uses_cache_direct($drive, $scfg);
+    $drive->{aio} = 'threads' if drive_is_cdrom($drive);
+    my $aio = $drive->{aio};
+    if (!$aio) {
+       if (storage_allows_io_uring_default($scfg, $cache_direct)) {
+           # io_uring supports all cache modes
+           $aio = "io_uring";
+       } else {
+           # aio native works only with O_DIRECT
+           if($cache_direct) {
+               $aio = "native";
+           } else {
+               $aio = "threads";
+           }
+       }
+    }
+    return $aio;
+}
+
+sub generate_blockdev_drive_cache {
+    my ($drive, $scfg) = @_;
+
+    my $cache_direct = drive_uses_cache_direct($drive, $scfg);
+    my $cache = {};
+    $cache->{direct} = $cache_direct ? JSON::true : JSON::false;
+    $cache->{'no-flush'} = $drive->{cache} && $drive->{cache} eq 'unsafe' ? 
JSON::true : JSON::false;
+    return $cache;
+}
+
+sub generate_throttle_group {
+    my ($drive) = @_;
+
+    my $drive_id = get_drive_id($drive);
+
+    my $throttle_group = { id => "throttle-drive-$drive_id" };
+    my $limits = {};
+
+    foreach my $type (['', '-total'], [_rd => '-read'], [_wr => '-write']) {
+       my ($dir, $qmpname) = @$type;
+
+       if (my $v = $drive->{"mbps$dir"}) {
+           $limits->{"bps$qmpname"} = int($v*1024*1024);
+       }
+       if (my $v = $drive->{"mbps${dir}_max"}) {
+           $limits->{"bps$qmpname-max"} = int($v*1024*1024);
+       }
+       if (my $v = $drive->{"bps${dir}_max_length"}) {
+           $limits->{"bps$qmpname-max-length"} = int($v)
+       }
+       if (my $v = $drive->{"iops${dir}"}) {
+           $limits->{"iops$qmpname"} = int($v);
+       }
+       if (my $v = $drive->{"iops${dir}_max"}) {
+           $limits->{"iops$qmpname-max"} = int($v);
+       }
+       if (my $v = $drive->{"iops${dir}_max_length"}) {
+           $limits->{"iops$qmpname-max-length"} = int($v);
+       }
+   }
+
+   $throttle_group->{limits} = $limits;
+
+   return $throttle_group;
+}
+
+sub print_drive_throttle_group {
+    my ($drive) = @_;
+
+    return if drive_is_cdrom($drive) && $drive->{file} eq 'none';
+
+    my $group = generate_throttle_group($drive);
+    $group->{'qom-type'} = "throttle-group";
+    return JSON->new->canonical->allow_nonref->encode($group)
+}
+
+sub generate_file_blockdev {
+    my ($storecfg, $drive, $snap, $nodename) = @_;
+
+    my $volid = $drive->{file};
+    my $blockdev = {};
+
+    my $scfg = undef;
+    my $path = $volid;
+    my $storeid = undef;
+
+    if($path !~ m/^nbd:(\S+)$/) {
+
+       ($storeid) = PVE::Storage::parse_volume_id($volid, 1);
+       my $vtype = $storeid ? (PVE::Storage::parse_volname($storecfg, 
$drive->{file}))[0] : undef;
+       die "$driveid: explicit media parameter is required for iso images\n"
+           if !defined($drive->{media}) && defined($vtype) && $vtype eq 'iso';
+
+       if (drive_is_cdrom($drive)) {
+           $path = get_iso_path($storecfg, $volid);
+       } elsif ($storeid) {
+           $path = PVE::Storage::path($storecfg, $volid, $snap);
+           $scfg = PVE::Storage::storage_config($storecfg, $storeid);
+       }
+    }
+
+    if ($path =~ m/^rbd:(\S+)$/) {
+
+        my $rbd_options = $1;
+        $blockdev->{driver} = 'rbd';
+
+       #map options to key=value pair (if not key is provided, this is the 
image)
+       #options are seprated with : but we need to exclude \: used for ipv6 
address
+       my $options = {
+           map {
+               s/\\:/:/g; /^(.*?)=(.*)/ ? ($1=>$2) : (image=>$_)
+           } $rbd_options =~ /(?:\\:|\[[^\]]*\]|[^:\\])+/g
+       };
+
+
+       $blockdev->{'auth-client-required'} = [$options->{'auth_supported'}] if 
$options->{'auth_supported'};
+       $blockdev->{'conf'} = $options->{'conf'} if $options->{'conf'};
+       $blockdev->{'user'} = $options->{'id'} if $options->{'id'};
+
+       if($options->{'mon_host'}) {
+           my $server = [];
+           my @mons = split(';', $options->{'mon_host'});
+           for my $mon (@mons) {
+               $mon =~ s/[\[\]]//g;
+               my ($host, $port) = PVE::Tools::parse_host_and_port($mon);
+               $port = '3300' if !$port;
+               push @$server, { host => $host, port => $port };
+           }
+           $blockdev->{server} = $server;
+       }
+
+       if($options->{'image'} =~ m|^(\S+)/(\S+)$|) {
+           $blockdev->{pool} = $1;
+           $blockdev->{image} = $2;
+           if($blockdev->{image} =~ m|^(\S+)/(\S+)$|) {
+               $blockdev->{namespace} = $1;
+               $blockdev->{image} = $2;
+           }
+        }
+
+        if($options->{keyring} && $blockdev->{server}) {
+            #qemu devs are removed passing arbitrary values to blockdev 
object, and don't have added
+            #keyring to the list of allowed keys. It need to be defined in the 
store ceph.conf.
+            
#https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg02676.html
+            #another way could be to simply patch qemu to allow the key
+            my $ceph_conf = "/etc/pve/priv/ceph/${storeid}.conf";
+            $blockdev->{conf} = $ceph_conf;
+            if (!-e $ceph_conf) {
+                my $content = "[global]\nkeyring = $options->{keyring}\n";
+               PVE::Tools::file_set_contents($ceph_conf, $content, 0400);
+           }
+       }
+    } elsif ($path =~ m/^nbd:(\S+):(\d+):exportname=(\S+)$/) {
+       my $server = { type => 'inet', host => $1, port => $2 };
+       $blockdev = { driver => 'nbd', server => $server, export => $3 };
+    } elsif ($path =~ m/^nbd:unix:(\S+):exportname=(\S+)$/) {
+       my $server = { type => 'unix', path => $1 };
+       $blockdev = { driver => 'nbd', server => $server, export => $2 };
+    } elsif ($path =~ 
m|^gluster(\+(tcp\|unix\|rdma))?://(.*)/(.*)/(images/(\S+)/(\S+))$|) {
+       my $protocol = $2 ? $2 : 'inet';
+       $protocol = 'inet' if $protocol eq 'tcp';
+       my $server = [{ type => $protocol, host => $3, port => '24007' }];
+       $blockdev = { driver => 'gluster', server => $server, volume => $4, 
path => $5 };
+    } elsif ($path =~ m/^iscsi:\/\/(\S+)\/(\S+)\/(\d+)$/) {
+       $blockdev = { driver => 'iscsi', portal => $1, target => $2, lun => $3, 
transport => "tcp" };
+    } elsif ($path =~ m/^\/dev/) {
+       my $driver = drive_is_cdrom($drive) ? 'host_cdrom' : 'host_device';
+       $blockdev = { driver => $driver, filename => $path };
+    } elsif ($path =~ m/^\//) {
+       $blockdev = { driver => 'file', filename => $path};
+    } else {
+       die "unsupported path: $path\n";
+    }
+
+    $blockdev->{cache} = generate_blockdev_drive_cache($drive, $scfg);
+    #non-host qemu block driver (rbd, gluster,iscsi,..) don't have aio 
attribute
+    $blockdev->{aio} = generate_blockdev_drive_aio($drive, $scfg) if 
$blockdev->{filename};
+
+    ##discard && detect-zeroes
+    my $discard = 'ignore';
+    if($drive->{discard}) {
+       $discard = $drive->{discard};
+       $discard = 'unmap' if $discard eq 'on';
+    }
+    $blockdev->{discard} = $discard if !drive_is_cdrom($drive);
+
+    my $detect_zeroes;
+    if (defined($drive->{detect_zeroes}) && !$drive->{detect_zeroes}) {
+       $detect_zeroes = 'off';
+    } elsif ($drive->{discard}) {
+       $detect_zeroes = $drive->{discard} eq 'on' ? 'unmap' : 'on';
+    } else {
+       # This used to be our default with discard not being specified:
+       $detect_zeroes = 'on';
+    }
+    $blockdev->{'detect-zeroes'} = $detect_zeroes if !drive_is_cdrom($drive);
+
+    $nodename = encode_nodename('file', $volid, $snap) if !$nodename;
+    $blockdev->{'node-name'} = $nodename;
+
+    return $blockdev;
+}
+
+sub generate_format_blockdev {
+    my ($storecfg, $drive, $file, $snap, $nodename) = @_;
+
+    my $volid = $drive->{file};
+    #nbd don't support format blockdev, return the fileblockdev
+    return $file if $volid =~ /^nbd:/;
+
+    my $scfg = undef;
+    $nodename = encode_nodename('fmt', $volid, $snap) if !$nodename;
+
+    my $drive_id = get_drive_id($drive);
+
+    if ($drive->{zeroinit}) {
+       #fixme how to handle zeroinit ? insert special blockdev filter ?
+    }
+
+    my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
+
+    # For PVE-managed volumes, use the format from the storage layer and 
prevent overrides via the
+    # drive's 'format' option. For unmanaged volumes, fallback to 'raw' to 
avoid auto-detection by
+    # QEMU.
+    my $format = undef;
+    if($storeid) {
+       $scfg = PVE::Storage::storage_config($storecfg, $storeid);
+       $format = checked_volume_format($storecfg, $volid);
+       if ($drive->{format} && $drive->{format} ne $format) {
+           die "drive '$drive->{interface}$drive->{index}' - volume '$volid'"
+               ." - 'format=$drive->{format}' option different from storage 
format '$format'\n";
+       }
+    } else {
+       $format = $drive->{format} // 'raw';
+    }
+
+    my $readonly = defined($drive->{ro}) ? JSON::true : JSON::false;
+
+    #libvirt define cache option on both format && file
+    my $cache = generate_blockdev_drive_cache($drive, $scfg);
+
+    my $blockdev = { 'node-name' => $nodename, driver => $format, file => 
$file, cache => $cache, 'read-only' => $readonly };
+
+    return $blockdev;
+}
+
+sub generate_drive_blockdev {
+    my ($storecfg, $drive, $live_restore_name) = @_;
+
+    my $volid = $drive->{file};
+    my $drive_id = get_drive_id($drive);
+
+    if (drive_is_cdrom($drive)) {
+        die "$drive_id: cannot back cdrom drive with a live restore image\n" 
if $live_restore_name;
+
+       my $path = get_iso_path($storecfg, $volid);
+       #throttle-filter can't be defined without attached disk
+       return if !$path;
+       $drive->{ro} = 1;
+    }
+
+    my $blockdev_file = generate_file_blockdev($storecfg, $drive);
+    my $blockdev_format = generate_format_blockdev($storecfg, $drive, 
$blockdev_file);
+
+    my $blockdev_live_restore = undef;
+    if ($live_restore_name) {
+        die "$drive_id: Proxmox Backup Server backed drive cannot auto-detect 
the format\n"
+            if !$drive->{format};
+
+        $blockdev_live_restore = { 'node-name' => 
"liverestore-drive-$drive_id",
+                                   backing => $live_restore_name,
+                                   'auto-remove' => 'on', format => 
"alloc-track",
+                                   file => $blockdev_format };
+    }
+
+    #this is the topfilter entry point, use $drive-drive_id as nodename
+    my $blockdev_throttle = { driver => "throttle", 'node-name' => 
"drive-$drive_id", 'throttle-group' => "throttle-drive-$drive_id" };
+    #put liverestore filter between throttle && format filter
+    $blockdev_throttle->{file} = $live_restore_name ? $blockdev_live_restore : 
$blockdev_format;
+    return $blockdev_throttle,
+}
+
+sub encode_base62 {
+    my ($input) = @_;
+    my @chars = ('0'..'9', 'A'..'Z', 'a'..'z');
+    my $base = 62;
+    my $value = 0;
+
+    foreach my $byte (unpack('C*', $input)) {
+        $value = $value * 256 + $byte;
+    }
+
+    my $result = '';
+    while ($value > 0) {
+        $result = $chars[$value % $base] . $result;
+        $value = int($value / $base);
+    }
+
+    return $result || '0';
+}
+
+sub encode_nodename {
+    my ($type, $volid, $snap) = @_;
+
+    my $nodename = "$volid";
+    $nodename .= "-$snap" if $snap;
+    $nodename = encode_base62(Digest::SHA::sha1($nodename));
+    my $prefix = "";
+    if ($type eq 'fmt') {
+       $prefix = 'f';
+    } elsif ($type eq 'file') {
+       $prefix = 'e';
+    } else {
+       die "wrong node type";
+    }
+    #node-name start with an alpha character
+    return "$prefix-$nodename";
+}
+
 1;
diff --git a/test/cfg2cmd/bootorder-empty.conf.cmd 
b/test/cfg2cmd/bootorder-empty.conf.cmd
index 07d46ee9..63e73be1 100644
--- a/test/cfg2cmd/bootorder-empty.conf.cmd
+++ b/test/cfg2cmd/bootorder-empty.conf.cmd
@@ -27,14 +27,16 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2' \
   -device 'lsi,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-scsi4,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi4","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-scsi4","throttle-group":"throttle-drive-scsi4"}'
   -device 'scsi-hd,bus=scsihw0.0,scsi-id=4,drive=drive-scsi4,id=scsi4' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-virtio0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio0","throttle-group":"throttle-drive-virtio0"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,iothread=iothread-virtio0'
 \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio1,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-virtio1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio1","throttle-group":"throttle-drive-virtio1"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio1,id=virtio1,bus=pci.0,addr=0xb,iothread=iothread-virtio1'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256'
 \
diff --git a/test/cfg2cmd/bootorder-legacy.conf.cmd 
b/test/cfg2cmd/bootorder-legacy.conf.cmd
index d12dcd94..7debfe13 100644
--- a/test/cfg2cmd/bootorder-legacy.conf.cmd
+++ b/test/cfg2cmd/bootorder-legacy.conf.cmd
@@ -27,14 +27,16 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'lsi,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-scsi4,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi4","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-scsi4","throttle-group":"throttle-drive-scsi4"}'
 \
   -device 'scsi-hd,bus=scsihw0.0,scsi-id=4,drive=drive-scsi4,id=scsi4' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-virtio0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio0","throttle-group":"throttle-drive-virtio0"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,iothread=iothread-virtio0'
 \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio1,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-virtio1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio1","throttle-group":"throttle-drive-virtio1"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio1,id=virtio1,bus=pci.0,addr=0xb,iothread=iothread-virtio1,bootindex=302'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=100'
 \
diff --git a/test/cfg2cmd/bootorder.conf.cmd b/test/cfg2cmd/bootorder.conf.cmd
index 2f2aa555..79d6da95 100644
--- a/test/cfg2cmd/bootorder.conf.cmd
+++ b/test/cfg2cmd/bootorder.conf.cmd
@@ -27,14 +27,16 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=103' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=103' \
   -device 'lsi,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-scsi4,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi4","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-scsi4","throttle-group":"throttle-drive-scsi4"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,scsi-id=4,drive=drive-scsi4,id=scsi4,bootindex=102' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-virtio0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio0","throttle-group":"throttle-drive-virtio0"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,iothread=iothread-virtio0'
 \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio1,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-virtio1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio1","throttle-group":"throttle-drive-virtio1"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio1,id=virtio1,bus=pci.0,addr=0xb,iothread=iothread-virtio1,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=101'
 \
diff --git a/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd 
b/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd
index 4fe10b66..e5edcb4c 100644
--- a/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd
+++ b/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd
@@ -25,9 +25,9 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/base-8006-disk-0.qcow2,if=none,id=drive-scsi0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-0.qcow2","node-name":"e-Nc8rhHZ7kcE2uuU2M8keyicwm0w"},"node-name":"f-Nc8rhHZ7kcE2uuU2M8keyicwm0w","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -machine 'type=pc+pve1'
diff --git a/test/cfg2cmd/ide.conf.cmd b/test/cfg2cmd/ide.conf.cmd
index 273b8e7d..eca6bacd 100644
--- a/test/cfg2cmd/ide.conf.cmd
+++ b/test/cfg2cmd/ide.conf.cmd
@@ -25,16 +25,21 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/zero.iso,if=none,id=drive-ide0,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.0,unit=0,drive=drive-ide0,id=ide0,bootindex=200' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/one.iso,if=none,id=drive-ide1,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.0,unit=1,drive=drive-ide1,id=ide1,bootindex=201' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/two.iso,if=none,id=drive-ide2,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=202' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/three.iso,if=none,id=drive-ide3,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.1,unit=1,drive=drive-ide3,id=ide3,bootindex=203' \
+  -object 
'{"id":"throttle-drive-ide0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/zero.iso","node-name":"e-OO9IkxxtCYSqog6okQom0we4S48"},"node-name":"f-OO9IkxxtCYSqog6okQom0we4S48","read-only":true},"node-name":"drive-ide0","throttle-group":"throttle-drive-ide0"}'
 \
+  -device 'ide-cd,bus=ide.0,unit=0,id=ide0,drive=drive-ide0,bootindex=200' \
+  -object 
'{"id":"throttle-drive-ide1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/one.iso","node-name":"e-OiteZ9aAusKmw6oIO8qucwmmmUU"},"node-name":"f-OiteZ9aAusKmw6oIO8qucwmmmUU","read-only":true},"node-name":"drive-ide1","throttle-group":"throttle-drive-ide1"}'
 \
+  -device 'ide-cd,bus=ide.0,unit=1,id=ide1,drive=drive-ide1,bootindex=201' \
+  -object 
'{"id":"throttle-drive-ide2","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/two.iso","node-name":"e-1Aib1Kemp2sgocAWokMGOyIQyQY"},"node-name":"f-1Aib1Kemp2sgocAWokMGOyIQyQY","read-only":true},"node-name":"drive-ide2","throttle-group":"throttle-drive-ide2"}'
 \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,drive=drive-ide2,bootindex=202' \
+  -object 
'{"id":"throttle-drive-ide3","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/three.iso","node-name":"e-UKCOEDGubQ8AywsAyqqGIywCIWQ"},"node-name":"f-UKCOEDGubQ8AywsAyqqGIywCIWQ","read-only":true},"node-name":"drive-ide3","throttle-group":"throttle-drive-ide3"}'
 \
+  -device 'ide-cd,bus=ide.1,unit=1,id=ide3,drive=drive-ide3,bootindex=203' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/100/vm-100-disk-2.qcow2,if=none,id=drive-scsi0,format=qcow2,cache=none,aio=io_uring,detect-zeroes=on'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/100/vm-100-disk-2.qcow2","node-name":"e-6zrMeiDDrkeISyGMGwACygKAISG"},"node-name":"f-6zrMeiDDrkeISyGMGwACygKAISG","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/pinned-version-pxe-pve.conf.cmd 
b/test/cfg2cmd/pinned-version-pxe-pve.conf.cmd
index 7301e3fa..01eed505 100644
--- a/test/cfg2cmd/pinned-version-pxe-pve.conf.cmd
+++ b/test/cfg2cmd/pinned-version-pxe-pve.conf.cmd
@@ -23,10 +23,10 @@
   -device 
'virtio-rng-pci,rng=rng0,max-bytes=1024,period=1000,bus=pci.1,addr=0x1d' \
   -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.raw,if=none,id=drive-scsi0,discard=on,format=raw,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.raw","node-name":"e-QrVmtMFNQG4wiK6key0AGkSGiE2"},"node-name":"f-QrVmtMFNQG4wiK6key0AGkSGiE2","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A1,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300,romfile=pxe-virtio.rom'
 \
diff --git a/test/cfg2cmd/pinned-version-pxe.conf.cmd 
b/test/cfg2cmd/pinned-version-pxe.conf.cmd
index 89be8c69..6d6c4c63 100644
--- a/test/cfg2cmd/pinned-version-pxe.conf.cmd
+++ b/test/cfg2cmd/pinned-version-pxe.conf.cmd
@@ -21,10 +21,10 @@
   -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \
   -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.raw,if=none,id=drive-scsi0,discard=on,format=raw,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.raw","node-name":"e-QrVmtMFNQG4wiK6key0AGkSGiE2"},"node-name":"f-QrVmtMFNQG4wiK6key0AGkSGiE2","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A1,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300,romfile=pxe-virtio.rom'
 \
diff --git a/test/cfg2cmd/pinned-version.conf.cmd 
b/test/cfg2cmd/pinned-version.conf.cmd
index da161ad9..17f39bb1 100644
--- a/test/cfg2cmd/pinned-version.conf.cmd
+++ b/test/cfg2cmd/pinned-version.conf.cmd
@@ -21,10 +21,10 @@
   -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \
   -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.raw,if=none,id=drive-scsi0,discard=on,format=raw,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.raw","node-name":"e-QrVmtMFNQG4wiK6key0AGkSGiE2"},"node-name":"f-QrVmtMFNQG4wiK6key0AGkSGiE2","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A1,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300'
 \
diff --git a/test/cfg2cmd/q35-ide.conf.cmd b/test/cfg2cmd/q35-ide.conf.cmd
index 4e910ff7..8c890314 100644
--- a/test/cfg2cmd/q35-ide.conf.cmd
+++ b/test/cfg2cmd/q35-ide.conf.cmd
@@ -24,16 +24,21 @@
   -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/zero.iso,if=none,id=drive-ide0,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.0,unit=0,drive=drive-ide0,id=ide0,bootindex=200' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/one.iso,if=none,id=drive-ide1,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.2,unit=0,drive=drive-ide1,id=ide1,bootindex=201' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/two.iso,if=none,id=drive-ide2,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=202' \
-  -drive 
'file=/mnt/pve/cifs-store/template/iso/three.iso,if=none,id=drive-ide3,media=cdrom,format=raw,aio=threads'
 \
-  -device 'ide-cd,bus=ide.3,unit=0,drive=drive-ide3,id=ide3,bootindex=203' \
+  -object 
'{"id":"throttle-drive-ide0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/zero.iso","node-name":"e-OO9IkxxtCYSqog6okQom0we4S48"},"node-name":"f-OO9IkxxtCYSqog6okQom0we4S48","read-only":true},"node-name":"drive-ide0","throttle-group":"throttle-drive-ide0"}'
 \
+  -device 'ide-cd,bus=ide.0,unit=0,id=ide0,drive=drive-ide0,bootindex=200' \
+  -object 
'{"id":"throttle-drive-ide1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/one.iso","node-name":"e-OiteZ9aAusKmw6oIO8qucwmmmUU"},"node-name":"f-OiteZ9aAusKmw6oIO8qucwmmmUU","read-only":true},"node-name":"drive-ide1","throttle-group":"throttle-drive-ide1"}'
 \
+  -device 'ide-cd,bus=ide.2,unit=0,id=ide1,drive=drive-ide1,bootindex=201' \
+  -object 
'{"id":"throttle-drive-ide2","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/two.iso","node-name":"e-1Aib1Kemp2sgocAWokMGOyIQyQY"},"node-name":"f-1Aib1Kemp2sgocAWokMGOyIQyQY","read-only":true},"node-name":"drive-ide2","throttle-group":"throttle-drive-ide2"}'
 \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,drive=drive-ide2,bootindex=202' \
+  -object 
'{"id":"throttle-drive-ide3","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"file","filename":"/mnt/pve/cifs-store/template/iso/three.iso","node-name":"e-UKCOEDGubQ8AywsAyqqGIywCIWQ"},"node-name":"f-UKCOEDGubQ8AywsAyqqGIywCIWQ","read-only":true},"node-name":"drive-ide3","throttle-group":"throttle-drive-ide3"}'
 \
+  -device 'ide-cd,bus=ide.3,unit=0,id=ide3,drive=drive-ide3,bootindex=203' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/100/vm-100-disk-2.qcow2,if=none,id=drive-scsi0,format=qcow2,cache=none,aio=io_uring,detect-zeroes=on'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/100/vm-100-disk-2.qcow2","node-name":"e-6zrMeiDDrkeISyGMGwACygKAISG"},"node-name":"f-6zrMeiDDrkeISyGMGwACygKAISG","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/q35-linux-hostpci-template.conf.cmd 
b/test/cfg2cmd/q35-linux-hostpci-template.conf.cmd
index 1bf1feb6..fcee635f 100644
--- a/test/cfg2cmd/q35-linux-hostpci-template.conf.cmd
+++ b/test/cfg2cmd/q35-linux-hostpci-template.conf.cmd
@@ -26,7 +26,8 @@
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/100/base-100-disk-2.raw,if=none,id=drive-scsi0,format=raw,cache=none,aio=io_uring,detect-zeroes=on,readonly=on'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/100/base-100-disk-2.raw","node-name":"e-3nPTM162JEOAymkwqg2Ww2QUioK"},"node-name":"f-3nPTM162JEOAymkwqg2Ww2QUioK","read-only":true},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0' \
   -machine 'accel=tcg,type=pc+pve1' \
   -snapshot
diff --git a/test/cfg2cmd/seabios_serial.conf.cmd 
b/test/cfg2cmd/seabios_serial.conf.cmd
index 114c6752..0da46c84 100644
--- a/test/cfg2cmd/seabios_serial.conf.cmd
+++ b/test/cfg2cmd/seabios_serial.conf.cmd
@@ -25,10 +25,10 @@
   -device 'isa-serial,chardev=serial0' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-scsi0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple-balloon-free-page-reporting.conf.cmd 
b/test/cfg2cmd/simple-balloon-free-page-reporting.conf.cmd
index 0c61d334..fd2e48e9 100644
--- a/test/cfg2cmd/simple-balloon-free-page-reporting.conf.cmd
+++ b/test/cfg2cmd/simple-balloon-free-page-reporting.conf.cmd
@@ -23,10 +23,10 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-scsi0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple-btrfs.conf.cmd 
b/test/cfg2cmd/simple-btrfs.conf.cmd
index 2d92b0f6..b3660047 100644
--- a/test/cfg2cmd/simple-btrfs.conf.cmd
+++ b/test/cfg2cmd/simple-btrfs.conf.cmd
@@ -25,10 +25,10 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/butter/bread/images/8006/vm-8006-disk-0/disk.raw,if=none,id=drive-scsi0,discard=on,format=raw,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/butter/bread/images/8006/vm-8006-disk-0/disk.raw","node-name":"e-Dc613MAbXUuSMOUYkqCWymoyGAM"},"node-name":"f-Dc613MAbXUuSMOUYkqCWymoyGAM","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple-disk-passthrough.conf.cmd 
b/test/cfg2cmd/simple-disk-passthrough.conf.cmd
index ca613a8f..0363b701 100644
--- a/test/cfg2cmd/simple-disk-passthrough.conf.cmd
+++ b/test/cfg2cmd/simple-disk-passthrough.conf.cmd
@@ -25,12 +25,15 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 
'file=/dev/cdrom,if=none,id=drive-ide2,media=cdrom,format=raw,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -object 
'{"id":"throttle-drive-ide2","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"driver":"host_cdrom","filename":"/dev/cdrom","node-name":"e-59mSJaWzNY8Eg6eyOAiKqyoU6Q4"},"node-name":"f-59mSJaWzNY8Eg6eyOAiKqyoU6Q4","read-only":true},"node-name":"drive-ide2","throttle-group":"throttle-drive-ide2"}'
 \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,drive=drive-ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/dev/sda,if=none,id=drive-scsi0,format=raw,cache=none,aio=io_uring,detect-zeroes=on'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"host_device","filename":"/dev/sda","node-name":"e-4BHkNLIiz2quuiY0o0yQ2WO8SUG"},"node-name":"f-4BHkNLIiz2quuiY0o0yQ2WO8SUG","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
-  -drive 
'file=/mnt/file.raw,if=none,id=drive-scsi1,format=raw,cache=none,aio=io_uring,detect-zeroes=on'
 \
+  -object 
'{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/mnt/file.raw","node-name":"e-4Z0R2kiQGecKCcma0k2qO0CCQ0O"},"node-name":"f-4Z0R2kiQGecKCcma0k2qO0CCQ0O","read-only":false},"node-name":"drive-scsi1","throttle-group":"throttle-drive-scsi1"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=1,drive=drive-scsi1,id=scsi1' \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple-rbd.conf.cmd b/test/cfg2cmd/simple-rbd.conf.cmd
index 644ff18c..56604d19 100644
--- a/test/cfg2cmd/simple-rbd.conf.cmd
+++ b/test/cfg2cmd/simple-rbd.conf.cmd
@@ -25,12 +25,13 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=rbd:cpool/vm-8006-disk-0:mon_host=127.0.0.42;127.0.0.21;[\:\:1]:auth_supported=none,if=none,id=drive-scsi0,discard=on,format=raw,cache=none,aio=io_uring,detect-zeroes=unmap'
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"auth-client-required":["none"],"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"rbd","image":"vm-8006-disk-0","node-name":"e-WH7PdKLViYcsYSWkcQoqQ0U40uI","pool":"cpool","server":[{"host":"127.0.0.42","port":"3300"},{"host":"127.0.0.21","port":"3300"},{"host":"::1","port":"3300"}]},"node-name":"f-WH7PdKLViYcsYSWkcQoqQ0U40uI","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
-  -drive 
'file=/dev/rbd-pve/fc4181a6-56eb-4f68-b452-8ba1f381ca2a/cpool/vm-8006-disk-0,if=none,id=drive-scsi1,discard=on,format=raw,cache=none,aio=io_uring,detect-zeroes=unmap'
+  -object 
'{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/rbd-pve/fc4181a6-56eb-4f68-b452-8ba1f381ca2a/cpool/vm-8006-disk-0","node-name":"e-426qW8R920KGyGqY480ymoSywiU"},"node-name":"f-426qW8R920KGyGqY480ymoSywiU","read-only":false},"node-name":"drive-scsi1","throttle-group":"throttle-drive-scsi1"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=1,drive=drive-scsi1,id=scsi1'
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple-virtio-blk.conf.cmd 
b/test/cfg2cmd/simple-virtio-blk.conf.cmd
index 1680f541..10a4d296 100644
--- a/test/cfg2cmd/simple-virtio-blk.conf.cmd
+++ b/test/cfg2cmd/simple-virtio-blk.conf.cmd
@@ -26,9 +26,9 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-virtio0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
+  -object 
'{"id":"throttle-drive-virtio0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-virtio0","throttle-group":"throttle-drive-virtio0"}'
 \
   -device 
'virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,iothread=iothread-virtio0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd 
b/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd
index 196d74d4..5cb54fc0 100644
--- a/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd
+++ b/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd
@@ -25,10 +25,10 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=iscsi://127.0.0.1/iqn.2019-10.org.test:foobar/0,if=none,id=drive-scsi0,discard=on,format=raw,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"raw","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"iscsi","lun":"0","node-name":"e-R6iR6TPY7y2M8YsIOasguK8KEEo","portal":"127.0.0.1","target":"iqn.2019-10.org.test:foobar","transport":"tcp"},"node-name":"f-R6iR6TPY7y2M8YsIOasguK8KEEo","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
diff --git a/test/cfg2cmd/simple1-template.conf.cmd 
b/test/cfg2cmd/simple1-template.conf.cmd
index 1de512e8..bd2e7f2c 100644
--- a/test/cfg2cmd/simple1-template.conf.cmd
+++ b/test/cfg2cmd/simple1-template.conf.cmd
@@ -23,13 +23,14 @@
   -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/base-8006-disk-1.qcow2,if=none,id=drive-scsi0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap,readonly=on'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-1.qcow2","node-name":"e-ZRitpbHqRyeSoKUmIwwMc4Uq0oQ"},"node-name":"f-ZRitpbHqRyeSoKUmIwwMc4Uq0oQ","read-only":true},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0' \
   -device 'ahci,id=ahci0,multifunction=on,bus=pci.0,addr=0x7' \
-  -drive 
'file=/var/lib/vz/images/8006/base-8006-disk-0.qcow2,if=none,id=drive-sata0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
-  -device 'ide-hd,bus=ahci0.0,drive=drive-sata0,id=sata0' \
+  -object 
'{"id":"throttle-drive-sata0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-0.qcow2","node-name":"e-Nc8rhHZ7kcE2uuU2M8keyicwm0w"},"node-name":"f-Nc8rhHZ7kcE2uuU2M8keyicwm0w","read-only":false},"node-name":"drive-sata0","throttle-group":"throttle-drive-sata0"}'
 \
+  -device 'ide-hd,bus=ahci0.0,id=sata0,drive=drive-sata0' \
   -machine 'accel=tcg,smm=off,type=pc+pve1' \
   -snapshot
diff --git a/test/cfg2cmd/simple1.conf.cmd b/test/cfg2cmd/simple1.conf.cmd
index c7fa1e0a..603a28c8 100644
--- a/test/cfg2cmd/simple1.conf.cmd
+++ b/test/cfg2cmd/simple1.conf.cmd
@@ -25,10 +25,10 @@
   -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
   -device 
'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
   -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
-  -drive 'if=none,id=drive-ide2,media=cdrom,aio=io_uring' \
-  -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200' \
+  -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
   -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \
-  -drive 
'file=/var/lib/vz/images/8006/vm-8006-disk-0.qcow2,if=none,id=drive-scsi0,discard=on,format=qcow2,cache=none,aio=io_uring,detect-zeroes=unmap'
 \
+  -object 
'{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+  -blockdev 
'{"driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"e-IQHs2Stp3mYmKYSGmUACmUu8i6u"},"node-name":"f-IQHs2Stp3mYmKYSGmUACmUu8i6u","read-only":false},"node-name":"drive-scsi0","throttle-group":"throttle-drive-scsi0"}'
 \
   -device 
'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,bootindex=100'
 \
   -netdev 
'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on'
 \
   -device 
'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300'
 \
-- 
2.39.5



--- End Message ---
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to