mirror of https://github.com/schoebel/mars
marsadm: use actual primary where appropriate instead of target primary
The actual primary is decoded in 'actual-*/is-primary' links, while the
target primary is decoded in the 'primary' link. This is not clearly
taken into account in several functions of marsadm. This commit fixes
this problem.
- Added _get_actual_primary() function
- Remove $pri parameter in _primary_res
- Use _get_actual_primary() where actual state should be used
Commits 3e96a5e 578d003 5dccbdc rebased to dfeb8e6
Signed-off-by: Thomas Schoebel-Theuer <tst@1und1.de>
This commit is contained in:
parent
3bf3745ec8
commit
4dafa9467a
|
@ -154,26 +154,21 @@ sub check_not_primary {
|
|||
my $lnk = "$mars/resource-$res/actual-$host/is-primary";
|
||||
my $is_primary = readlink($lnk);
|
||||
if ($is_primary) {
|
||||
ldie "operation '$cmd' cannot be executed on primary\n";
|
||||
ldie "operation '$cmd' cannot be executed on primary\n";
|
||||
}
|
||||
else { # also check whether we intend to become primary
|
||||
$lnk = "$mars/resource-$res/primary";
|
||||
my $primary = readlink($lnk) or ldie "cannot determine primary\n";
|
||||
ldie "operation '$cmd' cannot be executed on designated primary\n";
|
||||
$lnk = "$mars/resource-$res/primary";
|
||||
my $primary = readlink($lnk) or ldie "cannot determine primary\n";
|
||||
ldie "operation '$cmd' cannot be executed on designated primary\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub check_primary_gone {
|
||||
my ($res) = @_;
|
||||
for (;;) {
|
||||
my @links = glob("$mars/resource-$res/actual-*/is-primary");
|
||||
my $found = 0;
|
||||
foreach my $link (@links) {
|
||||
my $val = readlink($link);
|
||||
$found++ if $val;
|
||||
}
|
||||
last if !$found;
|
||||
lprint "waiting for $found other primary host(s) to disappear....\n";
|
||||
my $pri = _get_actual_primary($res);
|
||||
last if !$pri;
|
||||
lprint "waiting for other primary host ($pri) to disappear....\n";
|
||||
sleep_timeout();
|
||||
}
|
||||
}
|
||||
|
@ -289,9 +284,8 @@ sub check_splitbrain {
|
|||
# check up to $sequence (or for all if < 0)
|
||||
my ($res, $host, $sequence) = @_;
|
||||
if ($sequence < 0) {
|
||||
my $pri = "$mars/resource-$res/primary";
|
||||
my $old = readlink($pri) or ldie "cannot determine primary\n";
|
||||
_primary_res($res, "(none)", $pri, $old) unless $old eq "(none)";
|
||||
my $old = _get_actual_primary($res) || "(none)";
|
||||
_primary_res($res, "(none)", $old) unless $old eq "(none)";
|
||||
_trigger();
|
||||
sleep(5);
|
||||
while (!_check_files_modified_any_of("$mars/resource-$res/{log,version,replay}-*", 60)) {
|
||||
|
@ -372,6 +366,24 @@ sub get_size {
|
|||
return $arg;
|
||||
}
|
||||
|
||||
#
|
||||
# Get actual primary node from links below actual-*/ subdirs
|
||||
#
|
||||
sub _get_actual_primary {
|
||||
my ($res) = @_;
|
||||
my @primary_links = glob("$mars/resource-$res/actual-*/is-primary");
|
||||
my $primary;
|
||||
foreach my $link (@primary_links) {
|
||||
if (my $val = readlink($link)) {
|
||||
$primary = ($link =~ qr%.*actual-([^/]+)/is-primary%)[0];
|
||||
last;
|
||||
# Note: if there are more than one 'is-primary' links (an insane state anyway),
|
||||
# the first 'is-primary' link is selected. Other links are ignored.
|
||||
}
|
||||
}
|
||||
return $primary;
|
||||
}
|
||||
|
||||
sub get_peers {
|
||||
my ($res) = @_;
|
||||
my @list = glob("$mars/resource-$res/connect-*");
|
||||
|
@ -830,19 +842,19 @@ sub fake_local_res {
|
|||
}
|
||||
|
||||
sub _primary_res {
|
||||
my ($res, $host, $pri, $old) = @_;
|
||||
my ($res, $host, $old) = @_;
|
||||
my $tmp = "$mars/resource-$res/.tmp.primary";
|
||||
my $pri = "$mars/resource-$res/primary";
|
||||
system("rm -f $tmp");
|
||||
symlink($host, $tmp) or ldie "cannot create new primary symlink\n";
|
||||
rename($tmp, $pri) or ldie "cannot install new primary symlink\n";
|
||||
lprint "primary changed from '$old' to '$host'\n";
|
||||
lprint "primary will change from '$old' to '$host'\n";
|
||||
}
|
||||
|
||||
sub primary_res {
|
||||
my ($cmd, $res) = @_;
|
||||
my $sec = ($cmd eq "secondary");
|
||||
my $pri = "$mars/resource-$res/primary";
|
||||
my $old = readlink($pri) or ldie "cannot determine primary\n";
|
||||
my $old = _get_actual_primary($res) || '(none)';
|
||||
if ($sec) {
|
||||
ldie "for safety reasons, switching to secondary is only allowed when I ($host) am primary\n" if ($old ne $host) && !$force;
|
||||
$host = "(none)";
|
||||
|
@ -859,11 +871,11 @@ sub primary_res {
|
|||
lprint "trying to switch $host to primary...\n";
|
||||
check_sync_finished($res, $host);
|
||||
check_todo($res, "connect", 1, 1);
|
||||
_primary_res($res, "(none)", $pri, $old) unless $old eq "(none)";
|
||||
_primary_res($res, "(none)", $old) unless $old eq "(none)";
|
||||
check_primary_gone($res);
|
||||
check_splitbrain($res, $host, -1);
|
||||
}
|
||||
_primary_res($res, $host, $pri, $old);
|
||||
_primary_res($res, $host, $old);
|
||||
}
|
||||
|
||||
sub invalidate_res {
|
||||
|
@ -934,41 +946,43 @@ sub resize_res {
|
|||
|
||||
sub role_cmd {
|
||||
my ($cmd, $res) = @_;
|
||||
my $pri = "$mars/resource-$res/primary";
|
||||
my $old = readlink($pri) or ldie "cannot determine primary\n";
|
||||
my $is_primary = readlink("$mars/resource-$res/actual-$host/is-primary");
|
||||
if ($old eq $host) {
|
||||
if ($is_primary) {
|
||||
lprint "I am actually primary\n";
|
||||
} else {
|
||||
lprint "I am actually secondary although I should be primary\n";
|
||||
}
|
||||
} elsif ($is_primary) {
|
||||
lprint "I am actually primary although the primary should be $old\n";
|
||||
} else {
|
||||
lprint "I am actually secondary\n";
|
||||
my $primary = _get_actual_primary($res) || '(none)';
|
||||
my $todo_primary = readlink("$mars/resource-$res/primary") or ldie "cannot determine primary\n";
|
||||
my $msg = "I am actually ";
|
||||
$msg .= ($primary eq $host) ? "primary" : "secondary";
|
||||
if ($primary eq $todo_primary) {
|
||||
$msg .= " and $primary is primary" if ($primary ne $host);
|
||||
}
|
||||
elsif ($primary ne $todo_primary) {
|
||||
$todo_primary = "I" if ($todo_primary eq $host);
|
||||
$msg .= " and $todo_primary should be primary";
|
||||
}
|
||||
lprint $msg . "\n";
|
||||
}
|
||||
|
||||
sub mars_state_cmd {
|
||||
my ($cmd, $res) = @_;
|
||||
my $pri = "$mars/resource-$res/primary";
|
||||
my $primary = readlink($pri) or ldie "cannot determine primary\n";
|
||||
my $primary = _get_actual_primary($res) || '(none)';
|
||||
my $todo_primary = readlink("$mars/resource-$res/primary") or ldie "cannot determine primary\n";
|
||||
|
||||
if ($primary eq $host) {
|
||||
my $is_primary = readlink("$mars/resource-$res/actual-$host/is-primary");
|
||||
if ($is_primary) {
|
||||
lprint "is_primary\n";
|
||||
} else {
|
||||
lprint "becoming_primary\n";
|
||||
}
|
||||
lprint "is_primary\n";
|
||||
return;
|
||||
}
|
||||
elsif ($todo_primary eq $host) {
|
||||
lprint "becoming_primary\n";
|
||||
return;
|
||||
}
|
||||
|
||||
# secondary without ambitions to become primary
|
||||
|
||||
my $size = readlink("$mars/resource-$res/size") or ldie "cannot read size link";
|
||||
my $syncstatus = readlink("$mars/resource-$res/syncstatus-$host") or ldie "cannot read syncstatus link";
|
||||
if ($syncstatus != $size) {
|
||||
lprint "secondary inconsistent ($syncstatus bytes of $size)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if ($primary eq "(none)") {
|
||||
my $min = 0;
|
||||
foreach my $path (glob("$mars/resource-$res/log-*")) {
|
||||
|
|
Loading…
Reference in New Issue