diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index 45daa06c..de1c39a5 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -5729,6 +5729,28 @@ sub vm_start_nolock { warn $@ if $@; } + # set write threshold for LVM thin provisioning disks + PVE::QemuConfig->foreach_volume( + $conf, + sub { + my ($ds, $drive) = @_; + return if PVE::QemuServer::drive_is_cdrom($drive, 1); + my $volid = $drive->{file}; + if ( $volid ne 'none') { + my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); + my $snapshots = PVE::Storage::volume_snapshot_info($storecfg, $volid); + my $parentid = $snapshots->{'current'}->{parent}; + # for now only set write_threshold for volumes that have snapshots + # FIX: Change to only thin drives + if ($parentid) { + PVE::QemuServer::Blockdev::set_write_threshold( + $storecfg, $vmid, $drive_id, $volid + ); + } + } + }, + ); + #start nbd server for storage migration if (my $nbd = $migrate_opts->{nbd}) { diff --git a/src/PVE/QemuServer/Blockdev.pm b/src/PVE/QemuServer/Blockdev.pm index 8fa5eb51..9f8b635c 100644 --- a/src/PVE/QemuServer/Blockdev.pm +++ b/src/PVE/QemuServer/Blockdev.pm @@ -830,6 +830,49 @@ sub set_io_throttle { } } +sub block_set_write_threshold { + my ($vmid, $nodename, $threshold) = @_; + + print "set threshold $nodename $threshold\n"; + + PVE::QemuServer::mon_cmd( + $vmid, + "block-set-write-threshold", + 'node-name' => $nodename, + 'write-threshold' => int($threshold), + ); +} + +sub compute_write_threshold { + my ($storecfg, $scfg, $volid) = @_; + + my $lv_size = PVE::Storage::volume_size_info($storecfg, $volid, 5); + + my $write_threshold = $lv_size - $scfg->{chunksize} * (1 - $scfg->{'chunk-percentage'}); + + return $write_threshold; +} + +sub set_write_threshold { + my ($storecfg, $vmid, $drive_id, $volid, $options) = @_; + + my ($storeid) = PVE::Storage::parse_volume_id($volid); + my $scfg = PVE::Storage::storage_config($storecfg, $storeid); + my $support_qemu_snapshots = PVE::Storage::volume_qemu_snapshot_method($storecfg, $volid); + + # set write threshold is only supported for lvm storage using + # qcow2+external snapshots + return if $scfg->{type} ne 'lvm' || $support_qemu_snapshots ne 'mixed'; + # return if drive is not set as thin + # return if !$drive->{thin}; + + my $nodename = get_node_name('file', $drive_id, $volid, $options); + my $write_threshold = compute_write_threshold($storecfg, $scfg, $volid); + + print "setting threshold for $volid from $storeid\n"; + block_set_write_threshold($vmid, $nodename, $write_threshold); +} + sub blockdev_external_snapshot { my ($storecfg, $vmid, $machine_version, $deviceid, $drive, $snap, $parent_snap) = @_; @@ -878,6 +921,10 @@ sub blockdev_external_snapshot { node => $snap_fmt_blockdev->{'node-name'}, overlay => $new_fmt_blockdev->{'node-name'}, ); + + # FIX: only if thin + my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); + set_write_threshold($storecfg, $vmid, $drive_id, $volid); } sub blockdev_delete { diff --git a/src/PVE/QemuServer/Drive.pm b/src/PVE/QemuServer/Drive.pm index 79dd22e6..44f477a9 100644 --- a/src/PVE/QemuServer/Drive.pm +++ b/src/PVE/QemuServer/Drive.pm @@ -253,6 +253,13 @@ my %drivedesc_base = ( optional => 1, default => 0, }, + thin => { + type => 'boolean', + description => + 'Controls whether a drive should be thin provisioned', + optional => 1, + default => 0, + }, ); my %iothread_fmt = (