mirror of https://github.com/schoebel/mars
marsadm: new command primary+prosumer
This commit is contained in:
parent
3120cfb984
commit
cda71f2746
|
@ -2777,10 +2777,12 @@ sub wait_cluster {
|
|||
}
|
||||
|
||||
sub wait_cluster_noforce {
|
||||
my ($cmd, $res) = @_;
|
||||
my ($cmd, $res, $hosts) = @_;
|
||||
if (!$force) {
|
||||
lprint "WAITING for communication\n" if $verbose;
|
||||
wait_cluster($cmd, $res, "*", 0);
|
||||
$res = "all" if (!$res || $res =~ m/,/);
|
||||
$hosts = "*" unless $hosts;
|
||||
lprint "WAITING for communication with '$hosts'\n" if $verbose;
|
||||
wait_cluster($cmd, $res, $hosts, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4040,6 +4042,16 @@ sub _get_designated_primary {
|
|||
return $val;
|
||||
}
|
||||
|
||||
my %pri_new;
|
||||
|
||||
sub _get_future_primary {
|
||||
my ($cmd, $res, $unchecked) = @_;
|
||||
if ($pri_new{$res}) {
|
||||
return $pri_new{$res};
|
||||
}
|
||||
return _get_designated_primary(@_);
|
||||
}
|
||||
|
||||
sub is_actual_primary {
|
||||
my ($cmd, $res, $peer) = @_;
|
||||
$peer = $host unless (defined($peer) && $peer);
|
||||
|
@ -6431,6 +6443,9 @@ sub primary_phase0 {
|
|||
}
|
||||
}
|
||||
lprint "Current designated primary: $old\n";
|
||||
lprint "Future designated primary: $new\n";
|
||||
$pri_old{$res} = $old;
|
||||
$pri_new{$res} = $new;
|
||||
if ($cmd =~ m/primary/) {
|
||||
if ($host ne $old) {
|
||||
lprint "Allowing handover in cases of sync: ignore_sync=$ignore_sync\n" if $ignore_sync;
|
||||
|
@ -6518,7 +6533,7 @@ sub primary_phase0 {
|
|||
# otherwise: prepare prosumers
|
||||
sub primary_phase0a {
|
||||
my ($cmd, $res) = @_;
|
||||
my $new = $host;
|
||||
my $new = $pri_new{$res};
|
||||
if (!$force && $cmd =~ m/primary/) {
|
||||
lprint "Prepare new primary '$new' handover\n";
|
||||
_switch($cmd, $res, "$mars/resource-$res/todo-$new/fetch", 1);
|
||||
|
@ -6715,8 +6730,8 @@ sub primary_phase1b {
|
|||
return 0 if $force;
|
||||
my $check_logger = 0;
|
||||
my $this_stamp = 0;
|
||||
my $old = _get_designated_primary($cmd, $res, -1);
|
||||
my $new = $host;
|
||||
my $old = $pri_old{$res};
|
||||
my $new = $pri_new{$res};
|
||||
if (todo_local(@_)) {
|
||||
my $status = check_primary_gone($cmd, $res, $old);
|
||||
return $status if $status;
|
||||
|
@ -6824,9 +6839,8 @@ sub primary_phase2b {
|
|||
sub primary_phase3 {
|
||||
my ($cmd, $res) = @_;
|
||||
return 0 unless $cmd =~ m/primary/;
|
||||
my $old = _get_designated_primary($cmd, $res, -1);
|
||||
$pri_old{$res} = $old;
|
||||
my $new = $host;
|
||||
my $old = $pri_old{$res};
|
||||
my $new = $pri_new{$res};
|
||||
_primary_res($res, $new, $old);
|
||||
$allow_fail_action = \&compensate_primary_fail_switched;
|
||||
my $prosumers = get_prosumers(@_);
|
||||
|
@ -6902,6 +6916,7 @@ sub primary_phase3c {
|
|||
$allow_fail_action = \&compensate_primary_fail_prepared;
|
||||
_trigger(3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# wait for prosumer-handover finished
|
||||
|
@ -6909,7 +6924,7 @@ sub primary_phase3d {
|
|||
my ($cmd, $res) = @_;
|
||||
return 0 if $force || todo_local(@_);
|
||||
my $old = $pri_old{$res};
|
||||
my $new = $host;
|
||||
my $new = $pri_new{$res};
|
||||
my $prosumers = get_prosumers(@_);
|
||||
foreach my $peer (split("\\+", $prosumers)) {
|
||||
my $lnk = "$mars/resource-$res/actual-$peer/prosumer-on";
|
||||
|
@ -6985,7 +7000,7 @@ sub primary_phase3f {
|
|||
my ($cmd, $res) = @_;
|
||||
if (!$force && !todo_local(@_)) {
|
||||
my $old = $pri_old{$res};
|
||||
my $new = $host;
|
||||
my $new = $pri_new{$res};
|
||||
if ($old ne $new) {
|
||||
my $lnk = "$mars/resource-$res/actual-$old/is-primary";
|
||||
my $val = get_link($lnk, 1);
|
||||
|
@ -7032,12 +7047,14 @@ sub primary_phase4 {
|
|||
check_mars_device($cmd, $res, 1, 0);
|
||||
} elsif (!$force) {
|
||||
my $old = $pri_old{$res};
|
||||
my $new = $host;
|
||||
lprint "Unexporting old primary '$old' for safety.\n";
|
||||
my $lnk = "$mars/resource-$res/todo-$old/exports";
|
||||
set_link("(none)", $lnk);
|
||||
$lnk = "$mars/resource-$res/todo-$old/multi-prosumer";
|
||||
set_link("0", $lnk);
|
||||
my $new = $pri_new{$res};
|
||||
if ($old && $new && $new ne $old && $old ne "(none)") {
|
||||
lprint "Unexporting old primary '$old' for safety.\n";
|
||||
my $lnk = "$mars/resource-$res/todo-$old/exports";
|
||||
set_link("(none)", $lnk);
|
||||
$lnk = "$mars/resource-$res/todo-$old/multi-prosumer";
|
||||
set_link("0", $lnk);
|
||||
}
|
||||
}
|
||||
# new switch semantics, when nothing has failed before: up
|
||||
up_res_phase1(@_);
|
||||
|
@ -7078,19 +7095,34 @@ my %pros_umount;
|
|||
|
||||
sub prosumer_phase0 {
|
||||
my ($cmd, $res) = @_;
|
||||
my $primary = _get_designated_primary($cmd, $res, 0);
|
||||
lprint "Current designated primary: $primary\n";
|
||||
if ($primary eq "(none)") {
|
||||
my $max_retry = 3;
|
||||
retry:
|
||||
my $old_primary = _get_designated_primary($cmd, $res, 0);
|
||||
my $new_primary = _get_future_primary($cmd, $res, 0);
|
||||
lprint "Current designated primary: $old_primary\n";
|
||||
lprint "Future designated primary: $new_primary\n";
|
||||
if ($new_primary eq "(none)") {
|
||||
my $old_prosumers = _get_prosumer(@_);
|
||||
my $new_prosumers = parse_list_spec($cmd_suffix{"prosumer"}, $old_prosumers, $host);
|
||||
if ($new_prosumers ne "(local)" && $new_prosumers ne "(none)") {
|
||||
ldie "Cannot activate prosumers '$new_prosumers' when there is no designated primary.\n";
|
||||
if ($max_retry-- > 0) {
|
||||
lwarn "cannot find a designated primary.\n";
|
||||
update_cluster($cmd, $res);
|
||||
goto retry;
|
||||
}
|
||||
ldie "Cannot activate prosumers '$new_prosumers' without a designated primary.\n";
|
||||
}
|
||||
}
|
||||
if ($primary ne "(none)" &&
|
||||
!is_actual_primary($cmd, $res, $primary)) {
|
||||
ldie "Designated primary '$primary' is not actually primary\n" unless $force;
|
||||
lwarn "CONTINUE AT YOUR RISK, although designated primary '$primary' is not actually primary\n";
|
||||
if ($old_primary ne "(none)" &&
|
||||
!is_actual_primary($cmd, $res, $old_primary)) {
|
||||
if ($max_retry-- > 0) {
|
||||
lwarn "current designated primary '$old_primary' is not actually primary\n";
|
||||
sleep(1);
|
||||
wait_cluster_noforce($cmd, $res, $old_primary);
|
||||
goto retry;
|
||||
}
|
||||
ldie "Designated primary '$old_primary' is not actually primary\n" unless $force;
|
||||
lwarn "CONTINUE AT YOUR RISK, although current designated primary '$old_primary' is not actually primary\n";
|
||||
}
|
||||
|
||||
my $old_prosumers = _get_prosumer(@_);
|
||||
|
@ -7109,8 +7141,8 @@ sub prosumer_phase0 {
|
|||
$old_prosumers = "";
|
||||
$old_means .= " means ''";
|
||||
} elsif ($old_prosumers eq "(local)") {
|
||||
$old_prosumers = $primary;
|
||||
$old_means .= " means designated primary '$primary'";
|
||||
$old_prosumers = $new_primary;
|
||||
$old_means .= " means designated primary '$new_primary'";
|
||||
}
|
||||
if ($new_prosumers eq "(none)") {
|
||||
$new_prosumers = "";
|
||||
|
@ -7205,7 +7237,7 @@ sub prosumer_phase0 {
|
|||
|
||||
sub prosumer_phase1 {
|
||||
my ($cmd, $res) = @_;
|
||||
my $primary = _get_designated_primary($cmd, $res, 0);
|
||||
my $primary = _get_future_primary($cmd, $res, 0);
|
||||
my $new_prosumers = $pros_new{$res};
|
||||
my $uni_prosumers = $pros_uni{$res};
|
||||
my $inter_prosumers = $pros_inter{$res};
|
||||
|
@ -10815,6 +10847,89 @@ my %cmd_table =
|
|||
\&prosumer_phase5,
|
||||
"set final prosumers",
|
||||
|
||||
"LOOP",
|
||||
\&prosumer_phase6,
|
||||
"wait for device",
|
||||
],
|
||||
"primary+prosumer"
|
||||
=> [
|
||||
"usage: primary=<host_list_1> prosumer=<host_list_2> [<resource_name>]",
|
||||
" where <host_list_*> is '+'-separated.",
|
||||
" Operators += and -= are also allowed in place of = .",
|
||||
"Switch both the primary and the prosumer device at the same time.",
|
||||
[
|
||||
\&update_guests,
|
||||
],
|
||||
|
||||
\&primary_phase0,
|
||||
"check primary preconditions",
|
||||
\&prosumer_phase0,
|
||||
"check prosumer preconditions",
|
||||
|
||||
"FORK",
|
||||
"LOOP",
|
||||
\&prosumer_phase1,
|
||||
"remove old prosumers",
|
||||
|
||||
\&primary_phase0a,
|
||||
"conditionally wait for fetch off",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase0b,
|
||||
"wait for systemd",
|
||||
|
||||
"LOOP",
|
||||
\&prosumer_phase2,
|
||||
"check that any old prosumers are gone when necessary",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase1,
|
||||
"leave primary state",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase1b,
|
||||
"trigger remote",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase2,
|
||||
"wait for cluster when necessary",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase2b,
|
||||
"avoid split brain",
|
||||
|
||||
\&primary_phase3,
|
||||
"switch to primary",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase3b,
|
||||
"trigger remote",
|
||||
|
||||
\&primary_phase3c,
|
||||
"trigger prosumer handover",
|
||||
|
||||
\&prosumer_phase3,
|
||||
"set new prosumers",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase3d,
|
||||
"wait for prosumer handover and open gate",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase3e,
|
||||
"wait for gate open and reset old primary exports",
|
||||
|
||||
"LOOP",
|
||||
\&primary_phase3f,
|
||||
"wait for old primary gone",
|
||||
|
||||
"LOOP",
|
||||
\&prosumer_phase4,
|
||||
"check that all old prosumers are finally gone",
|
||||
|
||||
\&prosumer_phase5,
|
||||
"set final prosumers",
|
||||
|
||||
"LOOP",
|
||||
\&prosumer_phase6,
|
||||
"wait for device",
|
||||
|
|
Loading…
Reference in New Issue