]>
git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/HA/Env/PVE2.pm
1 package PVE
::HA
::Env
::PVE2
;
5 use POSIX
qw(:errno_h :fcntl_h);
11 use PVE
::Cluster
qw(cfs_register_file cfs_read_file cfs_lock_file);
17 my $lockdir = "/etc/pve/priv/lock";
19 my $manager_status_filename = "/etc/pve/ha/manager_status";
20 my $ha_groups_config = "/etc/pve/ha/groups.cfg";
21 my $ha_resources_config = "/etc/pve/ha/resources.cfg";
23 #cfs_register_file($ha_groups_config,
24 # sub { PVE::HA::Groups->parse_config(@_); },
25 # sub { PVE::HA::Groups->write_config(@_); });
28 my ($this, $nodename) = @_;
30 die "missing nodename" if !$nodename;
32 my $class = ref($this) || $this;
34 my $self = bless {}, $class;
36 $self->{nodename
} = $nodename;
44 return $self->{nodename
};
47 sub read_manager_status
{
50 my $filename = $manager_status_filename;
52 return PVE
::HA
::Tools
::read_json_from_file
($filename, {});
55 sub write_manager_status
{
56 my ($self, $status_obj) = @_;
58 my $filename = $manager_status_filename;
60 PVE
::HA
::Tools
::write_json_to_file
($filename, $status_obj);
64 my ($self, $node) = @_;
66 $node = $self->{nodename
} if !defined($node);
68 my $filename = "/etc/pve/nodes/$node/lrm_status";
70 return PVE
::HA
::Tools
::read_json_from_file
($filename, {});
73 sub write_lrm_status
{
74 my ($self, $status_obj) = @_;
76 my $node = $self->{nodename
};
78 my $filename = "/etc/pve/nodes/$node/lrm_status";
80 PVE
::HA
::Tools
::write_json_to_file
($filename, $status_obj);
83 sub manager_status_exists
{
86 return -f
$manager_status_filename ?
1 : 0;
89 sub read_service_config
{
92 # fixme: use cfs_read_file
96 $raw = PVE
::Tools
::file_get_contents
($ha_resources_config)
97 if -f
$ha_resources_config;
99 my $res = PVE
::HA
::Config
::parse_resources_config
($ha_resources_config, $raw);
101 my $vmlist = PVE
::Cluster
::get_vmlist
();
104 foreach my $sid (keys %{$res->{ids
}}) {
105 my $d = $res->{ids
}->{$sid};
106 $d->{state} = 'enabled' if !defined($d->{state});
107 if ($d->{type
} eq 'pvevm') {
108 if (my $vmd = $vmlist->{ids
}->{$d->{name
}}) {
110 warn "no such VM '$d->{name}'\n";
112 $d->{node
} = $vmd->{node
};
116 if (defined($d->{node
})) {
119 warn "service '$sid' without node\n";
128 sub change_service_location
{
129 my ($self, $sid, $node) = @_;
134 sub read_group_config
{
137 # fixme: use cfs_read_file
141 $raw = PVE
::Tools
::file_get_contents
($ha_groups_config)
142 if -f
$ha_groups_config;
144 return PVE
::HA
::Config
::parse_groups_config
($ha_groups_config, $raw);
147 sub queue_crm_commands
{
148 my ($self, $cmd) = @_;
154 my $filename = "/etc/pve/ha/crm_commands";
156 $data = PVE
::Tools
::file_get_contents
($filename);
159 PVE
::Tools
::file_set_contents
($filename, $data);
162 # fixme: do not use cfs_lock_storage (replace with cfs_lock_ha)
163 my $res = PVE
::Cluster
::cfs_lock_storage
("_ha_crm_commands", undef, $code);
168 sub read_crm_commands
{
174 my $filename = "/etc/pve/ha/crm_commands";
176 $data = PVE
::Tools
::file_get_contents
($filename);
177 PVE
::Tools
::file_set_contents
($filename, '');
183 # fixme: do not use cfs_lock_storage (replace with cfs_lock_ha)
184 my $res = PVE
::Cluster
::cfs_lock_storage
("_ha_crm_commands", undef, $code);
189 # this should return a hash containing info
190 # what nodes are members and online.
194 my ($node_info, $quorate) = ({}, 0);
196 my $nodename = $self->{nodename
};
198 $quorate = PVE
::Cluster
::check_cfs_quorum
(1) || 0;
200 my $members = PVE
::Cluster
::get_members
();
202 foreach my $node (keys %$members) {
203 my $d = $members->{$node};
204 $node_info->{$node}->{online
} = $d->{online
};
207 $node_info->{$nodename}->{online
} = 1; # local node is always up
209 return ($node_info, $quorate);
213 my ($self, $level, $msg) = @_;
217 syslog
($level, $msg);
220 my $last_lock_status = {};
223 my ($self, $lockid) = @_;
227 my $filename = "$lockdir/$lockid";
229 my $last = $last_lock_status->{$lockid} || 0;
237 # pve cluster filesystem not online
238 die "can't create '$lockdir' (pmxcfs not mounted?)\n" if ! -d
$lockdir;
240 if ($last && (($ctime - $last) < 100)) { # fixme: what timeout
241 utime(0, $ctime, $filename) || # cfs lock update request
242 die "cfs lock update failed - $!\n";
245 # fixme: wait some time?
246 if (!(mkdir $filename)) {
247 utime 0, 0, $filename; # cfs unlock request
248 die "can't get cfs lock\n";
257 $last_lock_status->{$lockid} = $got_lock ?
$ctime : 0;
259 if (!!$got_lock != !!$last) {
261 $self->log('info', "successfully aquired lock '$lockid'");
263 my $msg = "lost lock '$lockid";
264 $msg .= " - $err" if $err;
265 $self->log('err', $msg);
272 sub get_ha_manager_lock
{
275 return $self->get_pve_lock("ha_manager_lock");
278 sub get_ha_agent_lock
{
281 my $node = $self->nodename();
283 return $self->get_pve_lock("ha_agent_${node}_lock");
286 sub test_ha_agent_lock
{
287 my ($self, $node) = @_;
289 my $lockid = "ha_agent_${node}_lock";
290 my $filename = "$lockdir/$lockid";
291 my $res = $self->get_pve_lock($lockid);
292 rmdir $filename if $res; # cfs unlock
302 $quorate = PVE
::Cluster
::check_cfs_quorum
();
315 my ($self, $delay) = @_;
321 my ($self, $end_time) = @_;
324 my $cur_time = time();
326 last if $cur_time >= $end_time;
332 sub loop_start_hook
{
335 PVE
::Cluster
::cfs_update
();
337 $self->{loop_start
} = $self->get_time();
343 my $delay = $self->get_time() - $self->{loop_start
};
345 warn "loop take too long ($delay seconds)\n" if $delay > 30;
353 die "watchdog already open\n" if defined($watchdog_fh);
355 $watchdog_fh = IO
::Socket
::UNIX-
>new(
356 Type
=> SOCK_STREAM
(),
357 Peer
=> "/run/watchdog-mux.sock") ||
358 die "unable to open watchdog socket - $!\n";
360 $self->log('info', "watchdog active");
363 sub watchdog_update
{
364 my ($self, $wfh) = @_;
366 my $res = $watchdog_fh->syswrite("\0", 1);
367 if (!defined($res)) {
368 $self->log('err', "watchdog update failed - $!\n");
372 $self->log('err', "watchdog update failed - write $res bytes\n");
380 my ($self, $wfh) = @_;
382 $watchdog_fh->syswrite("V", 1); # magic watchdog close
383 if (!$watchdog_fh->close()) {
384 $self->log('err', "watchdog close failed - $!");
386 $watchdog_fh = undef;
387 $self->log('info', "watchdog closed (disabled)");
391 sub exec_resource_agent
{
392 my ($self, $sid, $cmd, @params) = @_;