Compare commits
4 commits
503ae6d680
...
be6264ebbf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be6264ebbf | ||
|
|
7fe84f2902 | ||
|
|
88d7de0720 | ||
|
|
1d1e4aa3a7 |
4 changed files with 129 additions and 1 deletions
|
|
@ -5822,6 +5822,28 @@ sub vm_start_nolock {
|
||||||
warn $@ if $@;
|
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
|
#start nbd server for storage migration
|
||||||
if (my $nbd = $migrate_opts->{nbd}) {
|
if (my $nbd = $migrate_opts->{nbd}) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,21 @@ sub get_block_info {
|
||||||
return $block_info;
|
return $block_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_block_stats {
|
||||||
|
my ($vmid) = @_;
|
||||||
|
|
||||||
|
my $block_stats = {};
|
||||||
|
|
||||||
|
my $qmp_block_stats = mon_cmd($vmid, "query-blockstats");
|
||||||
|
for my $info ($qmp_block_stats->@*) {
|
||||||
|
my $qdev_id = $info->{qdev} or next;
|
||||||
|
my $drive_id = qdev_id_to_drive_id($qdev_id);
|
||||||
|
$block_stats->{$drive_id} = $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $block_stats;
|
||||||
|
}
|
||||||
|
|
||||||
my sub get_node_name {
|
my sub get_node_name {
|
||||||
my ($type, $drive_id, $volid, $options) = @_;
|
my ($type, $drive_id, $volid, $options) = @_;
|
||||||
|
|
||||||
|
|
@ -700,6 +715,24 @@ sub resize {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub underlay_resize {
|
||||||
|
my ($storecfg, $vmid, $drive_id, $volid) = @_;
|
||||||
|
|
||||||
|
my $running = PVE::QemuServer::Helpers::vm_running_locally($vmid);
|
||||||
|
|
||||||
|
# get backing_snap
|
||||||
|
my $snapshots = PVE::Storage::volume_snapshot_info($storecfg, $volid);
|
||||||
|
my $backing_snap = $snapshots->{current}->{parent};
|
||||||
|
my $size = PVE::Storage::volume_underlay_resize($storecfg, $volid, $backing_snap);
|
||||||
|
|
||||||
|
return if !$running;
|
||||||
|
my $block_info = get_block_info($vmid);
|
||||||
|
my $inserted = $block_info->{$drive_id}->{inserted}
|
||||||
|
or die "no block node inserted for drive '$drive_id'\n";
|
||||||
|
|
||||||
|
set_write_threshold($storecfg, $vmid, $drive_id, $volid);
|
||||||
|
}
|
||||||
|
|
||||||
my sub blockdev_change_medium {
|
my sub blockdev_change_medium {
|
||||||
my ($storecfg, $vmid, $qdev_id, $drive) = @_;
|
my ($storecfg, $vmid, $qdev_id, $drive) = @_;
|
||||||
|
|
||||||
|
|
@ -820,6 +853,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_underlay_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 {
|
sub blockdev_external_snapshot {
|
||||||
my ($storecfg, $vmid, $machine_version, $deviceid, $drive, $snap, $parent_snap) = @_;
|
my ($storecfg, $vmid, $machine_version, $deviceid, $drive, $snap, $parent_snap) = @_;
|
||||||
|
|
||||||
|
|
@ -868,6 +944,10 @@ sub blockdev_external_snapshot {
|
||||||
node => $snap_fmt_blockdev->{'node-name'},
|
node => $snap_fmt_blockdev->{'node-name'},
|
||||||
overlay => $new_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 {
|
sub blockdev_delete {
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,13 @@ my %drivedesc_base = (
|
||||||
optional => 1,
|
optional => 1,
|
||||||
default => 0,
|
default => 0,
|
||||||
},
|
},
|
||||||
|
thin => {
|
||||||
|
type => 'boolean',
|
||||||
|
description =>
|
||||||
|
'Controls whether a drive should be thin provisioned',
|
||||||
|
optional => 1,
|
||||||
|
default => 0,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
my %iothread_fmt = (
|
my %iothread_fmt = (
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
#define DEFAULT_KILL_TIMEOUT 60
|
#define DEFAULT_KILL_TIMEOUT 60
|
||||||
|
|
||||||
static int verbose = 0;
|
static int verbose = 1;
|
||||||
static int kill_timeout = DEFAULT_KILL_TIMEOUT;
|
static int kill_timeout = DEFAULT_KILL_TIMEOUT;
|
||||||
static int epoll_fd = 0;
|
static int epoll_fd = 0;
|
||||||
static const char *progname;
|
static const char *progname;
|
||||||
|
|
@ -209,6 +209,25 @@ void handle_qmp_event(struct Client *client, struct json_object *obj) {
|
||||||
|
|
||||||
// check if a backup is running and kill QEMU process if not
|
// check if a backup is running and kill QEMU process if not
|
||||||
terminate_check(client);
|
terminate_check(client);
|
||||||
|
} else if (!strcmp(json_object_get_string(event), "BLOCK_WRITE_THRESHOLD")) {
|
||||||
|
struct json_object *data;
|
||||||
|
struct json_object *nodename;
|
||||||
|
if (json_object_object_get_ex(obj, "data", &data) &&
|
||||||
|
json_object_object_get_ex(data, "node-name", &nodename)) {
|
||||||
|
|
||||||
|
// needs concurrency control
|
||||||
|
char extend_queue_path[] = "/etc/pve/extend-queue";
|
||||||
|
FILE *p_extend_queue = fopen(extend_queue_path, "a");
|
||||||
|
if (p_extend_queue == NULL) {
|
||||||
|
VERBOSE_PRINT(
|
||||||
|
"%s: Couldn't open extend queue file %s", client->qemu.vmid, extend_queue_path
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const char *nodename_string = json_object_get_string(nodename);
|
||||||
|
fprintf(p_extend_queue, "%s: %s\n", client->qemu.vmid, nodename_string);
|
||||||
|
}
|
||||||
|
fclose(p_extend_queue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue