[pve-devel] [PATCH 2/2] add memory/dimm hotplug incl. migration support

Alexandre DERUMIER aderumier at odiso.com
Fri Jul 4 10:49:13 CEST 2014


Thanks for the patch, I think it's not too much different in qemu 2.1

I see in you code :
my $MAX_DIMMS = 10;



and

+ push @$cmd, '-m', "size=".$memory.",slots=10,maxmem=".$conf->{maxmemory}."G"; 


is "slots=10" = max_dimms ? (if yes,we should remove this hardcoded value)




I wonder if we could set max_dimm= 256 (max supported by acpi),$dimmsize=1G by default.

so like this we can easily hotplug 256G by default.


----- Mail original ----- 

De: "Stefan Priebe" <s.priebe at profihost.ag> 
À: pve-devel at pve.proxmox.com 
Envoyé: Vendredi 4 Juillet 2014 10:23:45 
Objet: [pve-devel] [PATCH 2/2] add memory/dimm hotplug incl. migration support 


Signed-off-by: Stefan Priebe <s.priebe at profihost.ag> 
--- 
PVE/API2/Qemu.pm | 3 ++ 
PVE/QemuServer.pm | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 
2 files changed, 96 insertions(+), 4 deletions(-) 

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm 
index 96c9302..11abcd3 100644 
--- a/PVE/API2/Qemu.pm 
+++ b/PVE/API2/Qemu.pm 
@@ -1008,6 +1008,9 @@ my $update_vm_api = sub { 
if($opt eq 'cores' && $conf->{maxcpus}){ 
PVE::QemuServer::qemu_cpu_hotplug($vmid, $conf, $param->{$opt}); 
} 
+ elsif ($opt eq 'memory' && $running){ 
+ PVE::QemuServer::qemu_memory_hotplug($vmid, $conf, $conf_param->{$opt}); 
+ } 

$conf->{$opt} = $param->{$opt}; 
PVE::QemuServer::update_config_nolock($vmid, $conf, 1); 
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm 
index b94e976..8913ee8 100644 
--- a/PVE/QemuServer.pm 
+++ b/PVE/QemuServer.pm 
@@ -483,6 +483,7 @@ my $MAX_UNUSED_DISKS = 8; 
my $MAX_HOSTPCI_DEVICES = 2; 
my $MAX_SERIAL_PORTS = 4; 
my $MAX_PARALLEL_PORTS = 3; 
+my $MAX_DIMMS = 10; 

my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio', 
'ne2k_isa', 'i82551', 'i82557b', 'i82559er', 'vmxnet3']; 
@@ -520,6 +521,20 @@ for (my $i = 0; $i < $MAX_NETS; $i++) { 
$confdesc->{"net$i"} = $netdesc; 
} 

+my $dimmdesc = { 
+ optional => 1, 
+ type => 'string', 
+ typetext => "size=<BYTES>,start=<startadress>", 
+ description => <<EODESCR, 
+Later / Hotplugged memory DIMM modules 
+EODESCR 
+}; 
+PVE::JSONSchema::register_standard_option("pve-qm-dimm", $dimmdesc); 
+ 
+for (my $i = 0; $i < $MAX_DIMMS; $i++) { 
+ $confdesc->{"dimm$i"} = $dimmdesc; 
+} 
+ 
my $drivename_hash; 

my $idedesc = { 
@@ -2769,12 +2784,24 @@ sub config_to_command { 
push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges); 
}); 

- $conf->{memory} ||= $defaults->{memory}; 
+ my $memory = $conf->{memory} || $defaults->{memory}; 
+ 
+ for (my $i = 0; $i < $MAX_DIMMS; $i++) { 
+ next if !exists $conf->{"dimm$i"}; 
+ $conf->{"dimm$i"} =~ m/size=(\d+)/ or next; 
+ my $dimmsize = $1; 
+ $conf->{"dimm$i"} =~ m/start=(\d+)/ or next; 
+ my $dimmstart = $1; 
+ $memory -= $dimmsize; 
+ push @$cmd, "-object" , "memory-ram,id=mem$i,size=".int(${dimmsize}*1024*1024); 
+ push @$cmd, "-device", "dimm,id=dimm$i,memdev=mem$i,start=$dimmstart"; 
+ } 

- if ($conf->{maxmemory} && $conf->{maxmemory}*1024 > $conf->{memory}) { 
- push @$cmd, '-m', "size=".$conf->{memory}.",slots=10,maxmem=".$conf->{maxmemory}."G"; 
+ if ($conf->{maxmemory}) { 
+ die "Memory is bigger than maxmemory\n" if $conf->{memory} > $conf->{maxmemory}*1024; 
+ push @$cmd, '-m', "size=".$memory.",slots=10,maxmem=".$conf->{maxmemory}."G"; 
} else { 
- push @$cmd, '-m', $conf->{memory}; 
+ push @$cmd, '-m', $memory; 
} 

for (my $i = 0; $i < $MAX_NETS; $i++) { 
@@ -3133,6 +3160,56 @@ sub qemu_cpu_hotplug { 
} 
} 

+sub qemu_memory_hotplug { 
+ my ($vmid, $conf, $memory) = @_; 
+ 
+ return if !check_running($vmid); 
+ 
+ die "memory hot add is not possible maxmemory config is missing!\n" if !$conf->{maxmemory}; 
+ die "you cannot add more memory than maxmemory!\n" if $memory > $conf->{'maxmemory'}*1024; 
+ 
+ # delta of memory must be a multiple of 1024 
+ my $toadd = $memory - $conf->{memory}; 
+ 
+ die "memory hot remove is not supported!\n" if $toadd <= 0; 
+ 
+ die "memory hot add must be in gb steps!\n" if ($toadd/1024 != int($toadd/1024)); 
+ 
+ # check for free dimms 
+ my $i = 0; 
+ while (defined $conf->{"dimm$i"} && $i < $MAX_DIMMS) {$i++;} 
+ 
+ die "no free dimm slot found!\n" if ($i >= $MAX_DIMMS); 
+ 
+ eval { 
+ # size is in BYTES 
+ vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-ram", id => "mem$i", props => { size => int($toadd*1024*1024) } ) 
+ }; 
+ my $err = $@; 
+ 
+ $conf->{"dimm$i"} = "size=$toadd"; 
+ 
+ # slot is consumed even on failure and also if device_add fails 
+ update_config_nolock($vmid, $conf, 1); 
+ 
+ if (!$err) { 
+ eval { 
+ vm_mon_cmd($vmid, "device_add", driver => "dimm", id => "dimm$i", memdev => "mem$i"); 
+ 
+ my $cmd = { execute => 'qom-get', arguments => { path => "/machine/peripheral/dimm$i", property => "start" } }; 
+ my $start = vm_qmp_command($vmid, $cmd); 
+ 
+ $conf->{"dimm$i"} .= ",start=$start"; 
+ 
+ # slot is consumed even on failure and also if device_add fails 
+ update_config_nolock($vmid, $conf, 1); 
+ }; 
+ $err = $@; 
+ } 
+ 
+ die "Memory hot add failed!: $err\n" if $err; 
+} 
+ 
sub qemu_block_set_io_throttle { 
my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_; 

@@ -3341,6 +3418,18 @@ sub vm_start { 
# set environment variable useful inside network script 
$ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom; 

+ # fresh VM start ignore DIMMs / delete them 
+ if (!$migratedfrom) { 
+ my $found = 0; 
+ for (my $i = 0; $i < $MAX_DIMMS; $i++) { 
+ next if !exists $conf->{"dimm$i"}; 
+ delete($conf->{"dimm$i"}); 
+ $found = 1; 
+ } 
+ update_config_nolock($vmid, $conf, 1); 
+ $conf = load_config($vmid, $migratedfrom); 
+ } 
+ 
my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine); 

my $migrate_port = 0; 
-- 
1.7.10.4 

_______________________________________________ 
pve-devel mailing list 
pve-devel at pve.proxmox.com 
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel 



More information about the pve-devel mailing list