]> git.proxmox.com Git - pve-ha-manager.git/blame - src/PVE/HA/FenceConfig.pm
remove unused use statements
[pve-ha-manager.git] / src / PVE / HA / FenceConfig.pm
CommitLineData
f83e7e6e
TL
1package PVE::HA::FenceConfig;
2
3use strict;
4use warnings;
5use PVE::Tools;
f83e7e6e 6
f83e7e6e
TL
7sub parse_config {
8 my ($fn, $raw) = @_;
9
10 $raw = '' if !$raw;
11
12 my $config = {};
13
14 my $lineno = 0;
15 my $priority = 0;
16
45e8e7b1
DM
17 eval {
18 while ($raw =~ /^\h*(.*?)\h*$/gm) {
19 my $line = $1;
20 $lineno++;
f83e7e6e 21
45e8e7b1 22 next if !$line || $line =~ /^#/;
f83e7e6e 23
45e8e7b1
DM
24 if ($line =~ m/^(device|connect)\s+(\S+)\s+(\S+)\s+(.+)$/) {
25 my ($command, $dev_name, $target) = ($1, $2, $3);
f83e7e6e 26
9742f408 27 my $arg_array = PVE::Tools::split_args($4);
f83e7e6e 28
45e8e7b1 29 my $dev_number = 1; # default
f83e7e6e 30
45e8e7b1
DM
31 # check for parallel devices
32 if ($dev_name =~ m/^(\w+)(:(\d+))?/) {
33 $dev_name = $1;
34 $dev_number = $3 if $3;
35 }
f83e7e6e 36
45e8e7b1 37 if ($command eq "device") {
f83e7e6e 38
45e8e7b1 39 my $dev = $config->{$dev_name} || {};
f83e7e6e 40
45e8e7b1
DM
41 die "device '$dev_name:$dev_number' already declared\n"
42 if $dev && $dev->{sub_devs}->{$dev_number};
f83e7e6e 43
45e8e7b1
DM
44 $dev->{sub_devs}->{$dev_number} = {
45 agent => $target,
9742f408 46 args => $arg_array,
45e8e7b1
DM
47 };
48 $dev->{priority} = $priority++ if !$dev->{priority};
f83e7e6e 49
45e8e7b1 50 $config->{$dev_name} = $dev;
f83e7e6e 51
45e8e7b1 52 } else { # connect nodes to devices
f83e7e6e 53
45e8e7b1
DM
54 die "device '$dev_name' must be declared before you can connect to it\n"
55 if !$config->{$dev_name};
f83e7e6e 56
45e8e7b1
DM
57 die "No parallel device '$dev_name:$dev_number' found\n"
58 if !$config->{$dev_name}->{sub_devs}->{$dev_number};
f83e7e6e 59
45e8e7b1 60 my $sdev = $config->{$dev_name}->{sub_devs}->{$dev_number};
f83e7e6e 61
45e8e7b1
DM
62 my ($node) = $target =~ /node=(\w+)/;
63 die "node=nodename needed to connect device '$dev_name' to node\n"
64 if !$node;
f83e7e6e 65
45e8e7b1
DM
66 die "node '$node' already connected to device '$dev_name:$dev_number'\n"
67 if $sdev->{node_args}->{$node};
f83e7e6e 68
9742f408 69 $sdev->{node_args}->{$node} = $arg_array;
f83e7e6e 70
45e8e7b1
DM
71 $config->{$dev_name}->{sub_devs}->{$dev_number} = $sdev;
72 }
f83e7e6e 73
45e8e7b1
DM
74 } else {
75 warn "$fn ignore line $lineno: $line\n"
f83e7e6e 76 }
f83e7e6e 77 }
45e8e7b1
DM
78 };
79 if (my $err = $@) {
80 die "error in '$fn' at $lineno: $err";
f83e7e6e
TL
81 }
82
83 return $config;
f83e7e6e
TL
84}
85
86sub write_config {
87 my ($fn, $data) = @_;
88
89 my $raw = '';
90
b6056542
TL
91 my $prev_priority = -1;
92
9d99786e 93 foreach my $dev_name (sort {$data->{$a}->{priority} <=> $data->{$b}->{priority}} keys %$data) {
f83e7e6e
TL
94 my $d = $data->{$dev_name};
95
b6056542
TL
96 die "Device '$dev_name' reuses priority! Priorities must be unique\n"
97 if $prev_priority == $d->{priority};
98
99 $prev_priority = $d->{priority};
100
f83e7e6e
TL
101 foreach my $sub_dev_nr (sort keys %{$d->{sub_devs}}) {
102 my $sub_dev = $d->{sub_devs}->{$sub_dev_nr};
9d99786e 103 my $dev_arg_str = PVE::Tools::cmd2string($sub_dev->{args});
f83e7e6e
TL
104
105 $raw .= "\ndevice $dev_name:$sub_dev_nr $sub_dev->{agent} $dev_arg_str\n";
106
107 foreach my $node (sort keys %{$sub_dev->{node_args}}) {
108 my $node_arg_str = join (' ', @{$sub_dev->{node_args}->{$node}});
109
9d99786e 110 $raw .= "connect $dev_name:$sub_dev_nr node=$node $node_arg_str\n";
f83e7e6e
TL
111 }
112 }
113 }
114
115 return $raw;
116}
117
118
119
120sub gen_arg_str {
121 my (@arguments) = @_;
122
123 my @shell_args = ();
124 foreach my $arg (@arguments) {
9742f408 125 my ($key, $val) = split /=/, $arg;
f83e7e6e 126 # we need to differ long and short opts!
9742f408
TL
127 my $prefix = (length($key) == 1) ? '-' : '--';
128 # shellquote values and add them again
129 $key .= '='. PVE::Tools::shellquote($val) if $val;
130 push @shell_args, "$prefix$key";
f83e7e6e
TL
131 }
132
133 return join (' ', @shell_args);
134}
135
136
137# returns command list to execute,
138# can be more than one command if parallel devices are configured
139# 'try' denotes the number of devices we should skip and normaly equals to
140# failed fencing tries
141sub get_commands {
142 my ($node, $try, $config) = @_;
143
144 return undef if !$node || !$config;
145
146 $try = 0 if !$try || $try<0;
147
148 foreach my $device (sort {$a->{priority} <=> $b->{priority}} values %$config) {
149 my @commands;
150
151 #foreach my $sub_dev (values %{$device->{sub_devs}}) {
152 foreach my $sub_dev_nr (sort keys %{$device->{sub_devs}}) {
153 my $sub_dev = $device->{sub_devs}->{$sub_dev_nr};
154
155 if (my $node_args = $sub_dev->{node_args}->{$node}) {
156 push @commands, { agent=>$sub_dev->{agent},
157 sub_dev => $sub_dev_nr,
158 param => [@{$sub_dev->{args}}, @{$node_args}]};
159 }
160
161 }
162
163 if (@commands>0) {
164 $try--;
165 return [ @commands ] if $try<0;
166 }
167 }
168
169 # out of tries or no device for this node
170 return undef;
171}
172
173
174sub count_devices {
175 my ($node, $config) = @_;
176
177 my $count = 0;
178
179 return 0 if !$config;
180
181 foreach my $device (values %$config) {
182 foreach my $sub_dev (values %{$device->{sub_devs}}) {
183 if ($sub_dev->{node_args}->{$node}) {
184 $count++;
185 last; # no need to count parallel devices
186 }
187 }
188 }
189
190 return $count;
191}
192
1931;