]> git.proxmox.com Git - pve-ha-manager.git/commitdiff
write lrm mode into lrm status file
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 26 Mar 2015 06:26:24 +0000 (07:26 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 26 Mar 2015 06:26:24 +0000 (07:26 +0100)
LRM is normally in 'active' mode, but can be set to 'reboot', 'shutdown' or 'restart'.
We use this to freeze services, so that we can safely reboot a node, or restart
the LRM.

src/PVE/HA/LRM.pm
src/PVE/HA/Manager.pm
src/PVE/HA/NodeStatus.pm

index da30cc8aa024d1b1aec7eb9eec250ecfd9e480f0..99041017b626dec96bc7427202d0fa31b2a6b3b4 100644 (file)
@@ -30,9 +30,13 @@ sub new {
        workers => {},
        results => {},
        shutdown_request => 0,
+       # mode can be: active, reboot, shutdown, restart
+       mode => 'active',
     }, $class;
 
     $self->set_local_status({ state =>         'wait_for_agent_lock' });   
+
+    $self->update_lrm_status();
     
     return $self;
 }
@@ -41,6 +45,13 @@ sub shutdown_request {
     my ($self) = @_;
 
     $self->{shutdown_request} = 1;
+
+    $self->{mode} = 'restart'; # fixme: detect shutdown/reboot
+
+    eval { $self->update_lrm_status(); };
+    if (my $err = $@) {
+       $self->log('err', "unable to update lrm status file");
+    }
 }
 
 sub get_local_status {
@@ -68,6 +79,17 @@ sub set_local_status {
     $self->{status} = $new;
 }
 
+sub update_lrm_status {
+    my ($self) = @_;
+
+    my $lrm_status = { 
+       mode => $self->{mode},
+       results => $self->{results},
+    };
+    
+    $self->{haenv}->write_lrm_status($lrm_status);
+}
+
 sub get_protected_ha_agent_lock {
     my ($self) = @_;
 
@@ -117,6 +139,7 @@ sub active_service_count {
        my $req_state = $sd->{state};
        next if !defined($req_state);
        next if $req_state eq 'stopped';
+       next if $req_state eq 'freeze';
 
        $count++;
     }
@@ -275,6 +298,7 @@ sub manage_resources {
        next if $sd->{node} ne $nodename;
        my $req_state = $sd->{state};
        next if !defined($req_state);
+       next if $req_state eq 'freeze';
        eval {
            $self->queue_resource_command($sid, $sd->{uid}, $req_state, $sd->{target});
        };
@@ -422,7 +446,7 @@ sub resource_command_finished {
     }
     $self->{results} = $results;
 
-    $haenv->write_lrm_status($results);
+    $self->update_lrm_status();
 }
 
 1;
index 1c653de5d4a1f85bad57f4fad31a099cc5788428..61e87400b2aa6cd2c75e00d19bc9fd7142296d3e 100644 (file)
@@ -140,6 +140,7 @@ my $valid_service_states = {
     fence => 1,
     migrate => 1,
     relocate => 1,
+    freeze => 1,
     error => 1,
 };
 
@@ -159,7 +160,7 @@ sub recompute_online_node_usage {
        my $state = $sd->{state};
        if (defined($online_node_usage->{$sd->{node}})) {
            if (($state eq 'started') || ($state eq 'request_stop') || 
-               ($state eq 'fence') || ($state eq 'error')) {
+               ($state eq 'fence') || ($state eq 'freeze') || ($state eq 'error')) {
                $online_node_usage->{$sd->{node}}++;
            } elsif (($state eq 'migrate') || ($state eq 'relocate')) {
                $online_node_usage->{$sd->{target}}++;
@@ -210,24 +211,26 @@ my $change_service_state = sub {
     $haenv->log('info', "service '$sid': state changed from '${old_state}' to '${new_state}' $text_state");
 };
 
-# read LRM status for all active nodes 
+# read LRM status for all nodes 
 sub read_lrm_status {
     my ($self) = @_;
 
-    my $nodes = $self->{ns}->list_online_nodes();
+    my $nodes = $self->{ns}->list_nodes();
     my $haenv = $self->{haenv};
 
-    my $res = {};
-
+    my $results = {};
+    my $modes = {};
     foreach my $node (@$nodes) {
-       my $ls = $haenv->read_lrm_status($node);
-       foreach my $uid (keys %$ls) {
-           next if $res->{$uid}; # should not happen
-           $res->{$uid} = $ls->{$uid};
+       my $lrm_status = $haenv->read_lrm_status($node);
+       $modes->{$node} = $lrm_status->{mode} || 'unknown';
+       foreach my $uid (keys %{$lrm_status->{results}}) {
+           next if $results->{$uid}; # should not happen
+           $results->{$uid} = $lrm_status->{results}->{$uid};
        }
     }
 
-    return $res;
+    
+    return ($results, $modes);
 }
 
 # read new crm commands and save them into crm master status
@@ -277,7 +280,7 @@ sub manage {
        return;
     }
 
-    my $lrm_status = $self->read_lrm_status();
+    my ($lrm_results, $lrm_modes) = $self->read_lrm_status();
 
     my $sc = $haenv->read_service_config();
 
@@ -312,7 +315,7 @@ sub manage {
            my $sd = $ss->{$sid};
            my $cd = $sc->{$sid} || { state => 'disabled' };
 
-           my $lrm_res = $sd->{uid} ? $lrm_status->{$sd->{uid}} : undef;
+           my $lrm_res = $sd->{uid} ? $lrm_results->{$sd->{uid}} : undef;
 
            my $last_state = $sd->{state};
 
@@ -336,6 +339,14 @@ sub manage {
 
                $self->next_state_request_stop($sid, $cd, $sd, $lrm_res);
 
+           } elsif ($last_state eq 'freeze') {
+
+               my $lrm_mode = $sd->{node} ? $lrm_modes->{$sd->{node}} : undef;
+               $lrm_mode = 'unknown'if !$lrm_mode;
+               # unfreeze
+               &$change_service_state($self, $sid, 'started') 
+                   if $lrm_mode eq 'active';
+
            } elsif ($last_state eq 'error') {
 
                # fixme: 
@@ -345,6 +356,14 @@ sub manage {
                die "unknown service state '$last_state'";
            }
 
+
+           my $lrm_mode = $sd->{node} ? $lrm_modes->{$sd->{node}} : undef;
+           $lrm_mode = 'unknown'if !$lrm_mode;
+           if (($sd->{state} eq 'started' || $sd->{state} eq 'stopped' ||
+                $sd->{state} eq 'request_stop') && ($lrm_mode ne 'active')) {
+               &$change_service_state($self, $sid, 'freeze');
+           }
+                   
            $repeat = 1 if $sd->{state} ne $last_state;
        }
 
index 285cf931ed4c6fc3efb6e9be5d5e324848f5bc01..fe8c0ef413186d1ea9608abef41390e523680ea6 100644 (file)
@@ -60,6 +60,12 @@ sub node_is_offline_delayed {
     return ($ctime - $last_online) >= $delay;
 }
 
+sub list_nodes {
+    my ($self) = @_;
+
+    return [sort keys %{$self->{status}}];
+}
+
 sub list_online_nodes {
     my ($self) = @_;