]> git.proxmox.com Git - pve-ha-manager.git/blame - src/PVE/HA/Env/PVE2.pm
use new watchdog-mux.sock socket
[pve-ha-manager.git] / src / PVE / HA / Env / PVE2.pm
CommitLineData
714a4016
DM
1package PVE::HA::Env::PVE2;
2
3use strict;
4use warnings;
76737af5
DM
5use POSIX qw(:errno_h :fcntl_h);
6use IO::File;
115805fd 7use IO::Socket::UNIX;
714a4016
DM
8
9use PVE::SafeSyslog;
10use PVE::Tools;
abc920b4 11use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_lock_file);
714a4016
DM
12
13use PVE::HA::Tools;
14use PVE::HA::Env;
abc920b4 15use PVE::HA::Groups;
714a4016 16
007fcc8b
DM
17my $lockdir = "/etc/pve/priv/lock";
18
714a4016 19my $manager_status_filename = "/etc/pve/manager_status";
abc920b4
DM
20my $ha_groups_config = "ha/groups.cfg";
21
6cbcb5f7
DM
22#cfs_register_file($ha_groups_config,
23# sub { PVE::HA::Groups->parse_config(@_); },
24# sub { PVE::HA::Groups->write_config(@_); });
714a4016
DM
25
26sub new {
27 my ($this, $nodename) = @_;
28
29 die "missing nodename" if !$nodename;
30
31 my $class = ref($this) || $this;
32
33 my $self = bless {}, $class;
34
35 $self->{nodename} = $nodename;
36
37 return $self;
38}
39
40sub nodename {
41 my ($self) = @_;
42
43 return $self->{nodename};
44}
45
46sub read_manager_status {
47 my ($self) = @_;
48
49 my $filename = $manager_status_filename;
50
51 return PVE::HA::Tools::read_json_from_file($filename, {});
52}
53
54sub write_manager_status {
55 my ($self, $status_obj) = @_;
56
57 my $filename = $manager_status_filename;
58
59 PVE::HA::Tools::write_json_to_file($filename, $status_obj);
60}
61
c4a221bc
DM
62sub read_lrm_status {
63 my ($self, $node) = @_;
64
65 $node = $self->{nodename} if !defined($node);
66
67 my $filename = "/etc/pve/nodes/$node/lrm_status";
68
69 return PVE::HA::Tools::read_json_from_file($filename, {});
70}
71
72sub write_lrm_status {
73 my ($self, $status_obj) = @_;
74
6cbcb5f7 75 my $node = $self->{nodename};
c4a221bc
DM
76
77 my $filename = "/etc/pve/nodes/$node/lrm_status";
78
79 PVE::HA::Tools::write_json_to_file($filename, $status_obj);
80}
81
714a4016
DM
82sub manager_status_exists {
83 my ($self) = @_;
84
85 return -f $manager_status_filename ? 1 : 0;
86}
87
88sub read_service_config {
89 my ($self) = @_;
90
91 die "implement me";
92}
93
8456bde2
DM
94sub change_service_location {
95 my ($self, $sid, $node) = @_;
96
97 die "implement me";
98}
99
abc920b4
DM
100sub read_group_config {
101 my ($self) = @_;
102
103 return cfs_read_file($ha_groups_config);
104}
105
3b996922
DM
106sub queue_crm_commands {
107 my ($self, $cmd) = @_;
108
109 die "implement me";
110}
111
112sub read_crm_commands {
113 my ($self) = @_;
114
115 die "implement me";
116}
117
714a4016
DM
118# this should return a hash containing info
119# what nodes are members and online.
120sub get_node_info {
121 my ($self) = @_;
122
123 die "implement me";
124}
125
126sub log {
127 my ($self, $level, $msg) = @_;
128
129 chomp $msg;
130
131 syslog($level, $msg);
132}
133
007fcc8b
DM
134my $last_lock_status = {};
135
136sub get_pve_lock {
137 my ($self, $lockid) = @_;
714a4016 138
007fcc8b 139 my $got_lock = 0;
4d24e7db 140
4d24e7db
DM
141 my $filename = "$lockdir/$lockid";
142
007fcc8b
DM
143 my $last = $last_lock_status->{$lockid} || 0;
144
145 my $ctime = time();
4d24e7db
DM
146
147 eval {
148
149 mkdir $lockdir;
150
007fcc8b
DM
151 # pve cluster filesystem not online
152 die "can't create '$lockdir' (pmxcfs not mounted?)\n" if ! -d $lockdir;
153
154 if ($last && (($ctime - $last) < 100)) { # fixme: what timeout
155 utime(0, $ctime, $filename) || # cfs lock update request
156 die "cfs lock update failed - $!\n";
157 } else {
158
159 # fixme: wait some time?
160 if (!(mkdir $filename)) {
161 utime 0, 0, $filename; # cfs unlock request
162 die "can't get cfs lock\n";
163 }
164 }
4d24e7db 165
007fcc8b 166 $got_lock = 1;
4d24e7db
DM
167 };
168
007fcc8b
DM
169 my $err = $@;
170
171 $last_lock_status->{$lockid} = $got_lock ? $ctime : 0;
172
173 if ($got_lock != $last) {
174 if ($got_lock) {
175 $self->log('info', "successfully aquired lock '$lockid'");
176 } else {
177 my $msg = "lost lock '$lockid";
178 $msg .= " - $err" if $err;
179 $self->log('err', $msg);
180 }
181 }
182
183 return $got_lock;
184}
185
186sub get_ha_manager_lock {
187 my ($self) = @_;
188
189 my $lockid = "ha_manager_lock";
190
191 my $filename = "$lockdir/$lockid";
192
193 return $self->get_pve_lock("ha_manager_lock");
714a4016
DM
194}
195
196sub get_ha_agent_lock {
197 my ($self) = @_;
007fcc8b
DM
198
199 my $node = $self->nodename();
714a4016 200
007fcc8b 201 return $self->get_pve_lock("ha_agent_${node}_lock");
714a4016
DM
202}
203
204sub test_ha_agent_lock {
205 my ($self, $node) = @_;
007fcc8b
DM
206
207 my $lockid = "ha_agent_${node}_lock";
208 my $filename = "$lockdir/$lockid";
209 my $res = $self->get_pve_lock($lockid);
210 rmdir $filename if $res; # cfs unlock
714a4016 211
007fcc8b 212 return $res;
714a4016
DM
213}
214
215sub quorate {
216 my ($self) = @_;
217
4d24e7db
DM
218 my $quorate = 0;
219 eval {
220 $quorate = PVE::Cluster::check_cfs_quorum();
221 };
222
223 return $quorate;
714a4016
DM
224}
225
226sub get_time {
227 my ($self) = @_;
228
229 return time();
230}
231
232sub sleep {
233 my ($self, $delay) = @_;
234
235 CORE::sleep($delay);
236}
237
238sub sleep_until {
239 my ($self, $end_time) = @_;
240
241 for (;;) {
242 my $cur_time = time();
243
244 last if $cur_time >= $end_time;
245
246 $self->sleep(1);
247 }
248}
249
250sub loop_start_hook {
251 my ($self) = @_;
252
4d24e7db
DM
253 PVE::Cluster::cfs_update();
254
714a4016
DM
255 $self->{loop_start} = $self->get_time();
256}
257
258sub loop_end_hook {
259 my ($self) = @_;
260
261 my $delay = $self->get_time() - $self->{loop_start};
262
263 warn "loop take too long ($delay seconds)\n" if $delay > 30;
264}
265
76737af5
DM
266my $watchdog_fh;
267
714a4016
DM
268sub watchdog_open {
269 my ($self) = @_;
270
76737af5
DM
271 die "watchdog already open\n" if defined($watchdog_fh);
272
115805fd
DM
273 $watchdog_fh = IO::Socket::UNIX->new(
274 Type => SOCK_STREAM(),
275 Peer => "/run/watchdog-mux.sock") ||
276 die "unable to open watchdog socket - $!\n";
277
76737af5 278 $self->log('info', "watchdog active");
714a4016
DM
279}
280
281sub watchdog_update {
282 my ($self, $wfh) = @_;
283
76737af5
DM
284 my $res = $watchdog_fh->syswrite("\0", 1);
285 if (!defined($res)) {
286 $self->log('err', "watchdog update failed - $!\n");
287 return 0;
288 }
289 if ($res != 1) {
290 $self->log('err', "watchdog update failed - write $res bytes\n");
291 return 0;
292 }
293
294 return 1;
714a4016
DM
295}
296
297sub watchdog_close {
298 my ($self, $wfh) = @_;
299
76737af5
DM
300 $watchdog_fh->syswrite("V", 1); # magic watchdog close
301 if (!$watchdog_fh->close()) {
302 $self->log('err', "watchdog close failed - $!");
303 } else {
304 $watchdog_fh = undef;
305 $self->log('info', "watchdog closed (disabled)");
306 }
714a4016
DM
307}
308
c4a221bc
DM
309sub exec_resource_agent {
310 my ($self, $sid, $cmd, @params) = @_;
311
312 die "implement me";
313}
314
714a4016 3151;