From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 995D41FF0DF for ; Thu, 15 Oct 2026 09:19:57 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 3383121434; Thu, 15 Oct 2026 09:19:54 +0200 (CEST) From: Kefu Chai To: pve-devel@lists.proxmox.com Subject: [PATCH manager] fix #8163: ceph: pool create: pass the CRUSH rule on creation Date: Thu, 15 Oct 2026 15:19:43 +0800 Message-ID: <20261015071943.3058549-1-k.chai@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1792048787419 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.340 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: JSLIYZ5E7OHIJH7NYN3QKRDS6Z5CFOXP X-Message-ID-Hash: JSLIYZ5E7OHIJH7NYN3QKRDS6Z5CFOXP X-MailFrom: k.chai@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: create_pool() only passes the pool name and pg_num to "osd pool create" and sets the CRUSH rule afterwards with "osd pool set". Ceph checks mon_max_pg_per_osd when a pool is created, against the rule it is created with, but not when the rule of an existing pool changes. So a pool with a non-default rule is checked against the OSDs and pools of the default rule. It is refused if those are near the limit, even if it would fit on its own rule, and it is never checked against its own rule. Pass the rule to "osd pool create" for replicated pools. Erasure-coded pools stay as they are, since Ceph creates their rule from the profile. Keep setting the size afterwards. Ceph checks the limit again when the size grows, and with this change that check uses the pool's own rule. Passing the size on creation would also make it fail in stretch mode, unless the size matches mon_stretch_pool_size. Signed-off-by: Kefu Chai --- PVE/Ceph/Tools.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PVE/Ceph/Tools.pm b/PVE/Ceph/Tools.pm index 1eed2a2d..94177709 100644 --- a/PVE/Ceph/Tools.pm +++ b/PVE/Ceph/Tools.pm @@ -349,6 +349,10 @@ sub create_pool { $mon_params->{erasure_code_profile} = extract_param($param, 'erasure_code_profile') if $param->{erasure_code_profile}; + # Ceph checks mon_max_pg_per_osd against the rule given on create, not on a later rule change + $mon_params->{rule} = extract_param($param, 'crush_rule') + if $param->{crush_rule} && ($mon_params->{pool_type} // '') ne 'erasure'; + $rados->mon_command($mon_params); set_pool($pool, $param); -- 2.47.3