diff --git a/userspace/marsadm b/userspace/marsadm index 40235e5e..b3926072 100644 --- a/userspace/marsadm +++ b/userspace/marsadm @@ -325,6 +325,47 @@ sub _get_ip { return undef; } +sub _fake_versionlink { + my ($basedir, $prev, $primary) = @_; + $prev =~ s/^log-([0-9]+)-.*$/$1/; + $prev--; + if($prev > 0) { + print "creating faked version symlink...\n"; + my $prevversion = sprintf("$basedir/version-%09d-$primary", $prev); + my $prevlink = readlink($prevversion); + if (!$prevlink) { # try any one else + $prevversion = sprintf("$basedir/version-%09d-*", $prev); + my @test = glob($prevversion); + $prevlink = shift @test; + } + die "cannot read symlink '$prevversion'\n" unless $prevlink; + my $myversion = sprintf("$basedir/version-%09d-$host", $prev); + symlink($prevlink, "$myversion.tmp") or die "cannot create faked version symlink '$myversion'\n"; + system("mv $myversion.tmp $myversion"); + } +} + +sub _set_replaylink { + my ($basedir, $replay, $primary) = @_; + my $replaylink = "$basedir/replay-$host"; + my $oldreplay = readlink($replaylink); + # fake old version symlink when necessary + if ($oldreplay) { + my $oldbase = $oldreplay; + my $base = $replay; + $oldbase =~ s/^([^,]+).*/$1/; + $base =~ s/^([^,]+).*/$1/; + if ($base ne $oldbase) { + _fake_versionlink($basedir, $oldreplay, $primary); + } + } + # copy pervious version symlink + _fake_versionlink($basedir, $replay, $primary); + # create replay symlink + symlink($replay, "$replaylink.tmp") or die "cannot create replay status\n"; + system("mv $replaylink.tmp $replaylink"); +} + ################################################################## # commands @@ -499,20 +540,7 @@ sub create_res { rename($tmp, "$mars/resource-$res") or die "cannot finalize resource '$res'\n"; print "successfully created resource '$res'\n"; } else { - # copy pervious version symlink - my $prev = $replay; - $prev =~ s/^log-([0-9]+)-.*$/$1/; - $prev--; - if($prev > 0) { - print "creating faked version symlink...\n"; - my $prevversion = sprintf("$mars/resource-$res/version-%09d-$primary", $prev); - my $prevlink = readlink($prevversion) or die "cannot read symlink '$prevversion'\n"; - my $myversion = sprintf("$mars/resource-$res/version-%09d-$host", $prev); - symlink($prevlink, $myversion) or die "cannot create faked version symlink '$myversion'\n"; - } - # create replay symlink - system("rm -f $tmp/replay-$host"); - symlink($replay, "$tmp/replay-$host") or die "cannot create replay status\n"; + _set_replaylink($tmp, $replay, $primary); symlink("0", "$tmp/syncstatus-$host") or die "cannot start initial sync\n"; system("rm -f $tmp/connect-$host"); symlink($primary, "$tmp/connect-$host") or die "cannot create peer connect symlink\n"; @@ -623,7 +651,7 @@ sub logdelete_res { foreach my $versionlink (glob("$mars/resource-$res/version-*")) { my $nrv = $versionlink; $nrv =~ s/^.*\/version-([0-9]+)-.+$/$1/; - next unless $nrv < $nr; + next unless $nrv < $nr - 1; _create_delete($versionlink); } } @@ -746,9 +774,29 @@ sub primary_res { sub invalidate_res { my ($cmd, $res) = @_; check_not_primary(@_); + my $old_replay = readlink("$mars/resource-$res/replay-$host") or die "cannot read my own replay status symlink\n"; + $old_replay =~ s/^([^,]+),.*/$1/; + my $repl = "$mars/resource-$res/todo-$host/allow-replay"; + my $was_on = readlink($repl); + if ($was_on) { + _switch("pause-replay-local", $res, $repl, 0); + _trigger(); + print "waiting...\n"; + sleep(15); + } my $dst = "$mars/resource-$res/syncstatus-$host"; system("rm -f $dst"); symlink("0", $dst) or die "cannot create invalidation symlink '$dst'\n"; + my $primary = readlink("$mars/resource-$res/primary") or die "cannot determine primary\n"; + my $replay = readlink("$mars/resource-$res/replay-$primary") or die "cannot read replay status of primary '$primary'\n"; + $replay =~ s/,[0-9]+,[0-9]+$/,0,0/; + _set_replaylink("$mars/resource-$res", $replay, $primary); + if ($was_on) { + _trigger(); + print "waiting...\n"; + sleep(15); + _switch("resume-replay-local", $res, $repl, 1); + } } sub resize_res {