]>
git.proxmox.com Git - qemu-server.git/blob - PVE/QemuServer/Memory.pm
1 package PVE
::QemuServer
::Memory
;
11 my ($conf, $vmid, $memory, $sockets, $func) = @_;
14 my $current_size = 1024;
16 return if $current_size == $memory;
18 for (my $j = 0; $j < 8; $j++) {
19 for (my $i = 0; $i < 32; $i++) {
20 my $name = "dimm${dimm_id}";
22 my $numanode = $i % $sockets;
23 $current_size += $dimm_size;
24 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
25 return $current_size if $current_size >= $memory;
31 sub foreach_reverse_dimm
{
32 my ($conf, $vmid, $memory, $sockets, $func) = @_;
35 my $current_size = 4177920;
36 my $dimm_size = 65536;
37 return if $current_size == $memory;
39 for (my $j = 0; $j < 8; $j++) {
40 for (my $i = 0; $i < 32; $i++) {
41 my $name = "dimm${dimm_id}";
43 my $numanode = $i % $sockets;
44 $current_size -= $dimm_size;
45 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
46 return $current_size if $current_size <= $memory;
52 sub qemu_memory_hotplug
{
53 my ($vmid, $conf, $defaults, $opt, $value) = @_;
55 return $value if !check_running
($vmid);
57 my $memory = $conf->{memory
} || $defaults->{memory
};
58 $value = $defaults->{memory
} if !$value;
59 return $value if $value == $memory;
61 my $static_memory = $STATICMEM;
62 my $dimm_memory = $memory - $static_memory;
64 die "memory can't be lower than $static_memory MB" if $value < $static_memory;
65 die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM;
69 $sockets = $conf->{sockets
} if $conf->{sockets
};
71 if($value > $memory) {
73 foreach_dimm
($conf, $vmid, $value, $sockets, sub {
74 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
76 return if $current_size <= $conf->{memory
};
78 eval { PVE
::QemuServer
::vm_mon_cmd
($vmid, "object-add", 'qom-type' => "memory-backend-ram", id
=> "mem-$name", props
=> { size
=> int($dimm_size*1024*1024) } ) };
80 eval { PVE
::QemuServer
::qemu_objectdel
($vmid, "mem-$name"); };
84 eval { PVE
::QemuServer
::vm_mon_cmd
($vmid, "device_add", driver
=> "pc-dimm", id
=> "$name", memdev
=> "mem-$name", node
=> $numanode) };
86 eval { PVE
::QemuServer
::qemu_objectdel
($vmid, "mem-$name"); };
89 #update conf after each succesful module hotplug
90 $conf->{memory
} = $current_size;
91 PVE
::QemuConfig-
>write_config($vmid, $conf);
96 foreach_reverse_dimm
($conf, $vmid, $value, $sockets, sub {
97 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
99 return if $current_size >= $conf->{memory
};
100 print "try to unplug memory dimm $name\n";
104 eval { PVE
::QemuServer
::qemu_devicedel
($vmid, $name) };
106 my $dimm_list = qemu_dimm_list
($vmid);
107 last if !$dimm_list->{$name};
108 raise_param_exc
({ $name => "error unplug memory module" }) if $retry > 5;
112 #update conf after each succesful module unplug
113 $conf->{memory
} = $current_size;
115 eval { PVE
::QemuServer
::qemu_objectdel
($vmid, "mem-$name"); };
116 PVE
::QemuConfig-
>write_config($vmid, $conf);
124 my $dimmarray = PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "query-memory-devices");
127 foreach my $dimm (@$dimmarray) {
129 $dimms->{$dimm->{data
}->{id
}}->{id
} = $dimm->{data
}->{id
};
130 $dimms->{$dimm->{data
}->{id
}}->{node
} = $dimm->{data
}->{node
};
131 $dimms->{$dimm->{data
}->{id
}}->{addr
} = $dimm->{data
}->{addr
};
132 $dimms->{$dimm->{data
}->{id
}}->{size
} = $dimm->{data
}->{size
};
133 $dimms->{$dimm->{data
}->{id
}}->{slot
} = $dimm->{data
}->{slot
};