From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <root@kvmformation3.odiso.net>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id B606B932EA
 for <pve-devel@lists.proxmox.com>; Wed,  4 Jan 2023 07:43:14 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 8A6EB1B6E1
 for <pve-devel@lists.proxmox.com>; Wed,  4 Jan 2023 07:43:14 +0100 (CET)
Received: from bastionodiso.odiso.net (bastionodiso.odiso.net [185.151.191.93])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS
 for <pve-devel@lists.proxmox.com>; Wed,  4 Jan 2023 07:43:12 +0100 (CET)
Received: from kvmformation3.odiso.net (formationkvm3.odiso.net [10.3.94.12])
 by bastionodiso.odiso.net (Postfix) with ESMTP id B7C317B2A;
 Wed,  4 Jan 2023 07:43:04 +0100 (CET)
Received: by kvmformation3.odiso.net (Postfix, from userid 0)
 id B6AB82248F5; Wed,  4 Jan 2023 07:43:04 +0100 (CET)
From: Alexandre Derumier <aderumier@odiso.com>
To: pve-devel@lists.proxmox.com
Date: Wed,  4 Jan 2023 07:42:59 +0100
Message-Id: <20230104064303.2898194-6-aderumier@odiso.com>
X-Mailer: git-send-email 2.30.2
In-Reply-To: <20230104064303.2898194-1-aderumier@odiso.com>
References: <20230104064303.2898194-1-aderumier@odiso.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.085 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 HEADER_FROM_DIFFERENT_DOMAINS 0.249 From and EnvelopeFrom 2nd level mail
 domains are different
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery
 methods
 NO_DNS_FOR_FROM         0.001 Envelope sender has no MX or A DNS records
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_NONE                0.001 SPF: sender does not publish an SPF Record
Subject: [pve-devel] [PATCH v2 qemu-server 5/9] memory: get_max_mem: use
 config memory max
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Wed, 04 Jan 2023 06:43:14 -0000

verify than defined vm memorymax is not bigger than
host cpu supported memory

Add add early check in update vm api

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/API2/Qemu.pm         | 48 ++++++++++++++++++++++++++--------------
 PVE/QemuServer/Memory.pm | 23 +++++++++++++++++--
 2 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 4ffa973..cab1e84 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -32,7 +32,7 @@ use PVE::QemuServer::Drive;
 use PVE::QemuServer::ImportDisk;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer::Machine;
-use PVE::QemuServer::Memory qw(get_current_memory);
+use PVE::QemuServer::Memory qw(get_current_memory parse_memory get_host_max_mem);
 use PVE::QemuMigrate;
 use PVE::RPCEnvironment;
 use PVE::AccessControl;
@@ -476,6 +476,35 @@ my $create_disks = sub {
     return ($vollist, $res);
 };
 
+my $check_memory_param = sub {
+    my ($conf, $param) = @_;
+
+    my $mem = parse_memory($param->{memory});
+    my $host_max_mem = get_host_max_mem($conf);
+
+    if ($mem->{max}) {
+	die "memory max can't be bigger than supported cpu architecture $host_max_mem MB\n"
+	    if $mem->{max} > $host_max_mem;
+    }
+
+    if ($param->{memory} || defined($param->{balloon})) {
+
+	my $maxmem = undef;
+	if ($param->{memory}) {
+	    $maxmem = get_current_memory($param->{memory});
+	} elsif ($conf->{pending}->{memory}) {
+	    $maxmem = get_current_memory($conf->{pending}->{memory});
+	} else {
+	    $maxmem = get_current_memory($conf->{memory});
+	}
+
+	my $balloon = defined($param->{balloon}) ? $param->{balloon} : $conf->{pending}->{balloon} || $conf->{balloon};
+
+	die "balloon value too large (must be smaller than assigned memory)\n"
+	    if $balloon && $balloon > $maxmem;
+    }
+};
+
 my $check_cpu_model_access = sub {
     my ($rpcenv, $authuser, $new, $existing) = @_;
 
@@ -1608,22 +1637,7 @@ my $update_vm_api  = sub {
 	    }
 	}
 
-	if ($param->{memory} || defined($param->{balloon})) {
-
-	    my $maxmem = undef;
-	    if ($param->{memory}) {
-	        $maxmem = get_current_memory($param->{memory});
-	    } elsif ($conf->{pending}->{memory}) {
-	        $maxmem = get_current_memory($conf->{pending}->{memory});
-	    } else {
-	        $maxmem = get_current_memory($conf->{memory});
-	    }
-
-	    my $balloon = defined($param->{balloon}) ? $param->{balloon} : $conf->{pending}->{balloon} || $conf->{balloon};
-
-	    die "balloon value too large (must be smaller than assigned memory)\n"
-		if $balloon && $balloon > $maxmem;
-	}
+	&$check_memory_param($conf, $param);
 
 	PVE::Cluster::log_msg('info', $authuser, "update VM $vmid: " . join (' ', @paramarr));
 
diff --git a/PVE/QemuServer/Memory.pm b/PVE/QemuServer/Memory.pm
index 1c4f356..20b9bf9 100644
--- a/PVE/QemuServer/Memory.pm
+++ b/PVE/QemuServer/Memory.pm
@@ -13,6 +13,8 @@ use base qw(Exporter);
 
 our @EXPORT_OK = qw(
 get_current_memory
+parse_memory
+get_host_max_mem
 );
 
 my $MAX_NUMA = 8;
@@ -94,7 +96,7 @@ my sub get_host_phys_address_bits {
     return; # undef, cannot really do anything..
 }
 
-my sub get_max_mem {
+sub get_host_max_mem {
     my ($conf) = @_;
 
     my $cpu = {};
@@ -125,7 +127,24 @@ my sub get_max_mem {
     # heuristic: remove 20 bits to get MB and half that as QEMU needs some overhead
     my $bits_to_max_mem = int(1<<($bits - 21));
 
-    return $bits_to_max_mem > 4*1024*1024 ? 4*1024*1024 : $bits_to_max_mem;
+    my $host_max_mem = $bits_to_max_mem > 4*1024*1024 ? 4*1024*1024 : $bits_to_max_mem;
+
+    return $host_max_mem;
+}
+
+my sub get_max_mem {
+    my ($conf) = @_;
+
+    my $host_max_mem = get_host_max_mem($conf);
+    my $mem = parse_memory($conf->{memory});
+
+    if ($mem->{max}) {
+	die "configured memory max can't be bigger than supported cpu architecture $host_max_mem MB\n"
+	    if $mem->{max} > $host_max_mem;
+	return $mem->{max};
+    }
+
+    return $host_max_mem;
 }
 
 sub get_current_memory {
-- 
2.30.2