]>
git.proxmox.com Git - pve-cluster.git/blob - data/PVE/Corosync.pm
11 my $basedir = "/etc/pve";
13 my $conf_array_sections = {
18 # a very simply parser ...
20 my ($filename, $raw) = @_;
24 my $digest = Digest
::SHA
::sha1_hex
(defined($raw) ?
$raw : '');
32 my @tokens = split(/\s/, $raw);
34 my $conf = { 'main' => {} };
37 my $section = $conf->{main
};
39 while (defined(my $token = shift @tokens)) {
40 my $nexttok = $tokens[0];
42 if ($nexttok && ($nexttok eq '{')) {
43 shift @tokens; # skip '{'
45 if ($conf_array_sections->{$token}) {
46 $section->{$token} = [] if !defined($section->{$token});
47 push @{$section->{$token}}, $new_section;
48 } elsif (!defined($section->{$token})) {
49 $section->{$token} = $new_section;
51 die "section '$token' already exists and not marked as array!\n";
53 push @$stack, $section;
54 $section = $new_section;
59 $section = pop @$stack;
60 die "parse error - uncexpected '}'\n" if !$section;
65 die "missing ':' after key '$key'\n" if ! ($key =~ s/:$//);
67 die "parse error - no value for '$key'\n" if !defined($nexttok);
68 my $value = shift @tokens;
70 $section->{$key} = $value;
73 # make working with the config way easier
74 my ($totem, $nodelist) = $conf->{main
}->@{"totem", "nodelist"};
75 $nodelist->{node
} = { map { $_->{name
} // $_->{ring0_addr
} => $_ } @{$nodelist->{node
}} };
76 $totem->{interface
} = { map { $_->{ringnumber
} => $_ } @{$totem->{interface
}} };
78 $conf->{digest
} = $digest;
85 my ($section, $prefix) = @_;
89 foreach my $k (sort keys %$section) {
90 my $v = $section->{$k};
91 if (ref($v) eq 'HASH') {
92 $raw .= $prefix . "$k {\n";
93 $raw .= &$dump_section($v, "$prefix ");
94 $raw .= $prefix . "}\n";
95 $raw .= "\n" if !$prefix; # add extra newline at 1st level only
96 } elsif (ref($v) eq 'ARRAY') {
97 foreach my $child (@$v) {
98 $raw .= $prefix . "$k {\n";
99 $raw .= &$dump_section($child, "$prefix ");
100 $raw .= $prefix . "}\n";
103 $raw .= $prefix . "$k: $v\n";
105 die "unexpected reference in config hash: $k => ". ref($v) ."\n";
113 my ($filename, $conf) = @_;
115 my $c = clone
($conf->{main
}) // die "no main section";
117 # retransform back for easier dumping
118 my $hash_to_array = sub {
120 return [ $hash->@{sort keys %$hash} ];
123 $c->{nodelist
}->{node
} = &$hash_to_array($c->{nodelist
}->{node
});
124 $c->{totem
}->{interface
} = &$hash_to_array($c->{totem
}->{interface
});
126 my $raw = &$dump_section($c, '');
132 my ($conf, $noerr, $new_value) = @_;
134 my $totem = $conf->{main
}->{totem
};
135 if (defined($totem) && defined($totem->{config_version
})) {
136 $totem->{config_version
} = $new_value if $new_value;
137 return $totem->{config_version
};
140 return undef if $noerr;
142 die "invalid corosync config - unable to read version\n";
145 # read only - use "rename corosync.conf.new corosync.conf" to write
146 PVE
::Cluster
::cfs_register_file
('corosync.conf', \
&parse_conf
);
148 PVE
::Cluster
::cfs_register_file
('corosync.conf.new', \
&parse_conf
,
151 sub check_conf_exists
{
154 $silent = $silent // 0;
156 my $exists = -f
"$basedir/corosync.conf";
158 warn "Corosync config '$basedir/corosync.conf' does not exist - is this node part of a cluster?\n"
159 if !$silent && !$exists;
164 sub update_nodelist
{
165 my ($conf, $nodelist) = @_;
167 delete $conf->{digest
};
169 my $version = conf_version
($conf);
170 conf_version
($conf, undef, $version + 1);
172 $conf->{main
}->{nodelist
}->{node
} = $nodelist;
174 PVE
::Cluster
::cfs_write_file
("corosync.conf.new", $conf);
176 rename("/etc/pve/corosync.conf.new", "/etc/pve/corosync.conf")
177 || die "activate corosync.conf.new failed - $!\n";
182 return clone
($conf->{main
}->{nodelist
}->{node
});
187 return clone
($conf->{main
}->{totem
});