qemu 2.4 feature Signed-off-by: Alexandre Derumier <aderum...@odiso.com> --- PVE/QemuServer.pm | 101 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 18 deletions(-)
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index f035b67..36bed4a 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -2607,6 +2607,27 @@ sub foreach_dimm { } } +sub foreach_reverse_dimm { + my ($conf, $vmid, $memory, $sockets, $func) = @_; + + my $dimm_id = 253; + my $current_size = 4177920; + my $dimm_size = 65536; + return if $current_size == $memory; + + for (my $j = 0; $j < 8; $j++) { + for (my $i = 0; $i < 32; $i++) { + my $name = "dimm${dimm_id}"; + $dimm_id--; + my $numanode = $i % $sockets; + $current_size -= $dimm_size; + &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory); + return $current_size if $current_size <= $memory; + } + $dimm_size /= 2; + } +} + sub foreach_drive { my ($conf, $vmid, $func) = @_; @@ -3693,33 +3714,77 @@ sub qemu_memory_hotplug { my $dimm_memory = $memory - $static_memory; die "memory can't be lower than $static_memory MB" if $value < $static_memory; - die "memory unplug is not yet available" if $value < $memory; die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM; my $sockets = 1; $sockets = $conf->{sockets} if $conf->{sockets}; - foreach_dimm($conf, $vmid, $value, $sockets, sub { - my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_; + if($value > $memory) { - return if $current_size <= $conf->{memory}; + foreach_dimm($conf, $vmid, $value, $sockets, sub { + my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_; - eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) }; - if (my $err = $@) { - eval { qemu_objectdel($vmid, "mem-$name"); }; - die $err; - } + return if $current_size <= $conf->{memory}; - eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) }; - if (my $err = $@) { - eval { qemu_objectdel($vmid, "mem-$name"); }; - die $err; - } - #update conf after each succesful module hotplug - $conf->{memory} = $current_size; - update_config_nolock($vmid, $conf, 1); - }); + eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) }; + if (my $err = $@) { + eval { qemu_objectdel($vmid, "mem-$name"); }; + die $err; + } + + eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) }; + if (my $err = $@) { + eval { qemu_objectdel($vmid, "mem-$name"); }; + die $err; + } + #update conf after each succesful module hotplug + $conf->{memory} = $current_size; + update_config_nolock($vmid, $conf, 1); + }); + + } else { + + foreach_reverse_dimm($conf, $vmid, $value, $sockets, sub { + my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_; + + return if $current_size >= $conf->{memory}; + print "try to unplug memory dimm $name\n"; + + my $retry = 0; + while (1) { + eval { qemu_devicedel($vmid, $name) }; + sleep 3; + my $dimm_list = qemu_dimm_list($vmid); + last if !$dimm_list->{$name}; + raise_param_exc({ $name => "error unplug memory module" }) if $retry > 5; + $retry++; + } + + #update conf after each succesful module unplug + $conf->{memory} = $current_size; + + eval { qemu_objectdel($vmid, "mem-$name"); }; + update_config_nolock($vmid, $conf, 1); + }); + } +} + +sub qemu_dimm_list { + my ($vmid) = @_; + + my $dimmarray = vm_mon_cmd_nocheck($vmid, "query-memory-devices"); + my $dimms = {}; + + foreach my $dimm (@$dimmarray) { + + $dimms->{$dimm->{data}->{id}}->{id} = $dimm->{data}->{id}; + $dimms->{$dimm->{data}->{id}}->{node} = $dimm->{data}->{node}; + $dimms->{$dimm->{data}->{id}}->{addr} = $dimm->{data}->{addr}; + $dimms->{$dimm->{data}->{id}}->{size} = $dimm->{data}->{size}; + $dimms->{$dimm->{data}->{id}}->{slot} = $dimm->{data}->{slot}; + } + return $dimms; } sub qemu_block_set_io_throttle { -- 2.1.4 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel