- 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;