]> git.proxmox.com Git - pve-ha-manager.git/blame - src/PVE/HA/NodeStatus.pm
bump version to 0.3-1
[pve-ha-manager.git] / src / PVE / HA / NodeStatus.pm
CommitLineData
cbca2c55
DM
1package PVE::HA::NodeStatus;
2
3use strict;
4use warnings;
5
6use Data::Dumper;
7
8sub new {
c79442f2 9 my ($this, $haenv, $status) = @_;
cbca2c55
DM
10
11 my $class = ref($this) || $this;
12
13 my $self = bless {
c79442f2 14 haenv => $haenv,
c0bbd038 15 status => $status,
5385a606 16 last_online => {},
cbca2c55
DM
17 }, $class;
18
19 return $self;
20}
21
22# possible node state:
b9e715a1 23my $valid_node_states = {
c0bbd038
DM
24 online => "node online and member of quorate partition",
25 unknown => "not member of quorate partition, but possibly still running",
f7ccd1b3 26 fence => "node needs to be fenced",
b9e715a1 27};
cbca2c55
DM
28
29sub get_node_state {
30 my ($self, $node) = @_;
31
f7ccd1b3 32 $self->{status}->{$node} = 'unknown'
b9e715a1 33 if !$self->{status}->{$node};
cbca2c55 34
b9e715a1 35 return $self->{status}->{$node};
cbca2c55
DM
36}
37
f7ccd1b3
DM
38sub node_is_online {
39 my ($self, $node) = @_;
40
41 return $self->get_node_state($node) eq 'online';
42}
43
5385a606
DM
44sub node_is_offline_delayed {
45 my ($self, $node, $delay) = @_;
46
47 return undef if $self->get_node_state($node) eq 'online';
48
49 my $last_online = $self->{last_online}->{$node};
50
51 my $ctime = time();
52
53 if (!defined($last_online)) {
54 $self->{last_online}->{$node} = $ctime;
55 return undef;
56 }
57
58 return (time() - $last_online) >= $delay;
59}
60
f7ccd1b3
DM
61sub list_online_nodes {
62 my ($self) = @_;
63
64 my $res = [];
65
c79442f2 66 foreach my $node (sort keys %{$self->{status}}) {
f7ccd1b3
DM
67 next if $self->{status}->{$node} ne 'online';
68 push @$res, $node;
69 }
70
71 return $res;
72}
73
cbca2c55
DM
74my $set_node_state = sub {
75 my ($self, $node, $state) = @_;
76
c79442f2
DM
77 my $haenv = $self->{haenv};
78
b9e715a1
DM
79 die "unknown node state '$state'\n"
80 if !defined($valid_node_states->{$state});
cbca2c55
DM
81
82 my $last_state = $self->get_node_state($node);
83
84 return if $state eq $last_state;
85
86 $self->{status}->{$node} = $state;
87
c79442f2
DM
88 $haenv->log('info', "node '$node': state changed from " .
89 "'$last_state' => '$state'\n");
cbca2c55
DM
90};
91
92sub update {
93 my ($self, $node_info) = @_;
94
95 foreach my $node (keys %$node_info) {
96 my $d = $node_info->{$node};
97 next if !$d->{online};
98
5385a606
DM
99 # record last time the node was online (required to implement fence delay)
100 $self->{last_online}->{$node} = time();
101
cbca2c55
DM
102 my $state = $self->get_node_state($node);
103
f7ccd1b3 104 if ($state eq 'online') {
c0bbd038
DM
105 # &$set_node_state($self, $node, 'online');
106 } elsif ($state eq 'unknown') {
107 &$set_node_state($self, $node, 'online');
f7ccd1b3 108 } elsif ($state eq 'fence') {
c0bbd038 109 # do nothing, wait until fenced
c0bbd038
DM
110 } else {
111 die "detected unknown node state '$state";
cbca2c55
DM
112 }
113 }
114
115 foreach my $node (keys %{$self->{status}}) {
116 my $d = $node_info->{$node};
117 next if $d && $d->{online};
118
119 my $state = $self->get_node_state($node);
120
c0bbd038
DM
121 # node is not inside quorate partition, possibly not active
122
f7ccd1b3 123 if ($state eq 'online') {
c0bbd038
DM
124 &$set_node_state($self, $node, 'unknown');
125 } elsif ($state eq 'unknown') {
126 # &$set_node_state($self, $node, 'unknown');
f7ccd1b3 127 } elsif ($state eq 'fence') {
c0bbd038 128 # do nothing, wait until fenced
c0bbd038
DM
129 } else {
130 die "detected unknown node state '$state";
131 }
132
cbca2c55
DM
133 }
134}
135
c79442f2 136# start fencing
f7ccd1b3
DM
137sub fence_node {
138 my ($self, $node) = @_;
139
c79442f2
DM
140 my $haenv = $self->{haenv};
141
f7ccd1b3
DM
142 my $state = $self->get_node_state($node);
143
c79442f2
DM
144 if ($state ne 'fence') {
145 &$set_node_state($self, $node, 'fence');
f7ccd1b3
DM
146 }
147
ffa555c5
DM
148 my $success = $haenv->test_ha_agent_lock($node);
149
150 if ($success) {
3c36cbca 151 $haenv->log("info", "fencing: acknowleged - got agent lock for node '$node'");
21e37ed4 152 &$set_node_state($self, $node, 'unknown');
ffa555c5
DM
153 }
154
155 return $success;
f7ccd1b3
DM
156}
157
cbca2c55 1581;