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 350161FF0A7 for ; Wed, 30 Sep 2026 09:46:50 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 20F0021637; Wed, 30 Sep 2026 09:46:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dualfroz.com; s=dkim; t=1790688690; h=from:subject:date:message-id:to:mime-version: content-transfer-encoding; bh=j0UwEwgXTCZ4+SdrZJA6pgF/MLNRvbLCvfc6SZWOFGU=; b=190OW+fM7NlcrlEMm/8q+RixZL23EpgoQjAjD27WJIlGVrVtjoY0FTwqVqLgR6+pmM/15J +ZY403Dk1KbYHLwZCnYKNHJJQqvs6dCxbQbjW1cG8kbs2sBPha7Ob3yLIJT8WfeR75kDdk 671SJl+uUV0mlh5Q86d4nqX3hr2M1SnVX1/EDZiT5wQamIH9Gh1IlMw4HsjEcbCUjwqpcB 71RkuixgobdNcroG0EDCUnIxKZub5sd10uMzeplJNplttKHgHJURFTnZhsXg6Lhug1PeeS jTGMdLNxdncGdROb2VvGOYT9/WMfF1ggduttmvXB3OfX/7PgVfz50JigLn0CdA== From: Michal Fox To: pve-devel@lists.proxmox.com Subject: [PATCH cluster] fix #7326: corosync config: allow whitespace in values Date: Tue, 29 Sep 2026 15:31:27 +0200 Message-ID: <20260929133127.2500284-1-me@dualfroz.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.050 Adjusted score from AWL reputation of From: address DKIM_INVALID 0.1 DKIM or DK signature exists, but is not valid DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DMARC_PASS -0.1 DMARC pass policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record X-MailFrom: me@dualfroz.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation Message-ID-Hash: 3ODDVAYIOQYVXYZYLK7K6XEPOFL7D3WG X-Message-ID-Hash: 3ODDVAYIOQYVXYZYLK7K6XEPOFL7D3WG X-Mailman-Approved-At: Wed, 30 Sep 2026 09:46:15 +0200 X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The corosync.conf parser split the whole file into whitespace separated tokens and always took exactly one token as value. Values containing whitespace, like a manually set cluster_name "my cluster", are accepted by corosync, but made the parser fail with "missing ':' after key". Any API call reading the corosync config then failed, for example when adding an HA resource. Parse the file line by line instead, like corosync does, and take the rest of the line after the first ':' as value. Section headers and closing brackets still need to be on their own line, which corosync requires anyway. Add a test config with whitespace in the cluster name. Signed-off-by: Michal Fox --- src/PVE/Corosync.pm | 26 +++++++--------- .../cluster-name-with-spaces.conf | 30 +++++++++++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 src/test/corosync_configs/cluster-name-with-spaces.conf diff --git a/src/PVE/Corosync.pm b/src/PVE/Corosync.pm index aef0d31..4be755a 100644 --- a/src/PVE/Corosync.pm +++ b/src/PVE/Corosync.pm @@ -99,23 +99,20 @@ sub parse_conf { my $digest = Digest::SHA::sha1_hex(defined($raw) ? $raw : ''); $raw =~ s/#.*$//mg; - $raw =~ s/\r?\n/ /g; - $raw =~ s/\s+/ /g; - $raw =~ s/^\s+//; - $raw =~ s/\s*$//; - - my @tokens = split(/\s/, $raw); my $conf = { 'main' => {} }; my $stack = []; my $section = $conf->{main}; - while (defined(my $token = shift @tokens)) { - my $nexttok = $tokens[0]; + # like corosync itself, parse line by line, so that values may contain whitespace + for my $line (split(/\r?\n/, $raw)) { + $line =~ s/^\s+//; + $line =~ s/\s+$//; + next if $line eq ''; - if ($nexttok && ($nexttok eq '{')) { - shift @tokens; # skip '{' + if ($line =~ m/^(\S+?)\s*\{$/) { + my $token = $1; my $new_section = {}; if ($conf_array_sections->{$token}) { $section->{$token} = [] if !defined($section->{$token}); @@ -130,17 +127,16 @@ sub parse_conf { next; } - if ($token eq '}') { + if ($line eq '}') { $section = pop @$stack; die "parse error - uncexpected '}'\n" if !$section; next; } - my $key = $token; - die "missing ':' after key '$key'\n" if !($key =~ s/:$//); + my ($key, $value) = $line =~ m/^([^\s:]+)\s*:\s*(.*)$/ + or die "parse error - unable to parse line '$line'\n"; - die "parse error - no value for '$key'\n" if !defined($nexttok); - my $value = shift @tokens; + die "parse error - no value for '$key'\n" if $value eq ''; $section->{$key} = $value; } diff --git a/src/test/corosync_configs/cluster-name-with-spaces.conf b/src/test/corosync_configs/cluster-name-with-spaces.conf new file mode 100644 index 0000000..e13b005 --- /dev/null +++ b/src/test/corosync_configs/cluster-name-with-spaces.conf @@ -0,0 +1,30 @@ +logging { + debug: off + to_syslog: yes +} + +nodelist { + node { + name: prox1 + nodeid: 1 + quorum_votes: 1 + ring0_addr: prox1 + } +} + +quorum { + provider: corosync_votequorum +} + +totem { + cluster_name: cloud with spaces + config_version: 1 + interface { + bindnetaddr: 192.168.0.42 + ringnumber: 0 + } + ip_version: ipv4 + secauth: on + version: 2 +} + -- 2.43.0