[pve-devel] [PATCH 2/2] add memory/dimm hotplug incl. migration support
Alexandre DERUMIER
aderumier at odiso.com
Fri Jul 4 11:00:43 CEST 2014
>>Why? You could also insert a 4GB module or just a 512MB module.
I have customer which need to increment memory, step by step by 1GB, each month for example
10 seem to be too short for me. (I don't known if 256 is supported by all os, but accordig to qemu doc it should be ok)
also ,can we mix module size ?
how look the vmid.cfg ?
----- Mail original -----
De: "Stefan Priebe - Profihost AG" <s.priebe at profihost.ag>
À: "Alexandre DERUMIER" <aderumier at odiso.com>
Cc: pve-devel at pve.proxmox.com
Envoyé: Vendredi 4 Juillet 2014 10:53:24
Objet: Re: [pve-devel] [PATCH 2/2] add memory/dimm hotplug incl. migration support
Am 04.07.2014 10:49, schrieb Alexandre DERUMIER:
> 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)
Yes it is. It was just a test to verify it is working at all.
>
> 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.
Why? You could also insert a 4GB module or just a 512MB module.
Stefan
> ----- 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;
>
More information about the pve-devel
mailing list