]> git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/HA/Sim/Resources.pm
cleanup backup & mounted locks after recovery (fixes #1100)
[pve-ha-manager.git] / src / PVE / HA / Sim / Resources.pm
1 package PVE::HA::Sim::Resources;
2
3 use strict;
4 use warnings;
5
6 use base qw(PVE::HA::Resources);
7
8 # provides some base methods for virtual resources (used in simulation/testing).
9 # reduces code reuse and it's targeted for the main PVE service types, namely
10 # virtual machines (VM) and container (CT)
11
12 sub verify_name {
13 my ($class, $id) = @_;
14
15 die "invalid VMID '$id'\n" if $id !~ m/^[1-9][0-9]+$/;
16 }
17
18 sub options {
19 return {
20 state => { optional => 1 },
21 group => { optional => 1 },
22 comment => { optional => 1 },
23 max_restart => { optional => 1 },
24 max_relocate => { optional => 1 },
25 };
26 }
27
28 sub config_file {
29 my ($class, $id, $nodename) = @_;
30
31 my $service_type = $class->type();
32
33 # virtual path
34 return "$nodename/$service_type:$id";
35 }
36
37 sub start {
38 my ($class, $haenv, $id) = @_;
39
40 my $sid = $class->type() . ":$id";
41 my $nodename = $haenv->nodename();
42 my $hardware = $haenv->hardware();
43 my $ss = $hardware->read_service_status($nodename);
44
45 if (my $lock = $hardware->service_has_lock($sid)) {
46 $haenv->log('err', "service '$sid' locked ($lock), unable to start!");
47 return;
48 }
49
50 $haenv->sleep(2);
51
52 $ss->{$sid} = 1;
53
54 $hardware->write_service_status($nodename, $ss);
55
56 }
57
58 sub shutdown {
59 my ($class, $haenv, $id) = @_;
60
61 my $sid = $class->type() . ":$id";
62 my $nodename = $haenv->nodename();
63 my $hardware = $haenv->hardware();
64 my $ss = $hardware->read_service_status($nodename);
65
66 if (my $lock = $hardware->service_has_lock($sid)) {
67 $haenv->log('err', "service '$sid' locked ($lock), unable to shutdown!");
68 return;
69 }
70
71 $haenv->sleep(2);
72
73 $ss->{$sid} = 0;
74
75 $hardware->write_service_status($nodename, $ss);
76 }
77
78 sub check_running {
79 my ($class, $haenv, $id) = @_;
80
81 my $service_type = $class->type();
82 my $nodename = $haenv->nodename();
83 my $hardware = $haenv->hardware();
84
85 my $ss = $hardware->read_service_status($nodename);
86
87 return ($ss->{"$service_type:$id"}) ? 1 : 0;
88 }
89
90
91 sub migrate {
92 my ($class, $haenv, $id, $target, $online) = @_;
93
94 my $sid = $class->type() . ":$id";
95 my $nodename = $haenv->nodename();
96 my $hardware = $haenv->hardware();
97 my $ss = $hardware->read_service_status($nodename);
98
99 my $cmd = $online ? "migrate" : "relocate";
100 $haenv->log("info", "service $sid - start $cmd to node '$target'");
101
102 if (my $lock = $hardware->service_has_lock($sid)) {
103 $haenv->log('err', "service '$sid' locked ($lock), unable to $cmd!");
104 return;
105 }
106
107 # explicitly shutdown if $online isn't true (relocate)
108 if (!$online && $class->check_running($haenv, $id)) {
109 $haenv->log("info", "stopping service $sid (relocate)");
110 $class->shutdown($haenv, $id);
111 $haenv->log("info", "service status $sid stopped");
112 } else {
113 $haenv->sleep(2); # (live) migration time
114 }
115
116 $hardware->change_service_location($sid, $nodename, $target);
117 $haenv->log("info", "service $sid - end $cmd to node '$target'");
118 # ensure that the old node doesn't has the service anymore
119 delete $ss->{$sid};
120 $hardware->write_service_status($nodename, $ss);
121
122 # check if resource really moved
123 return defined($ss->{$sid}) ? 0 : 1;
124 }
125
126
127 sub remove_locks {
128 my ($self, $haenv, $id, $locks, $service_node) = @_;
129
130 my $sid = $self->type() . ":$id";
131 my $hardware = $haenv->hardware();
132
133 foreach my $lock (@$locks) {
134 if (my $removed_lock = $hardware->unlock_service($sid, $lock)) {
135 return $removed_lock;
136 }
137 }
138
139 return undef;
140 }
141
142 1;