fix marsadm for replay links

This commit is contained in:
jmann 2011-10-20 11:05:42 +02:00 committed by Thomas Schoebel-Theuer
parent ad9f40eac5
commit 538bff0812
6 changed files with 42 additions and 61 deletions

View File

@ -2,8 +2,6 @@
#ifndef BRICK_H
#define BRICK_H
#define msleep msleep_interruptible
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/sched.h>

2
mars.h
View File

@ -7,6 +7,8 @@
//#define MARS_TRACING // write runtime trace data to /mars/trace.csv
#define msleep msleep_interruptible
/////////////////////////////////////////////////////////////////////////
// include the generic brick infrastructure

View File

@ -130,7 +130,7 @@ static int check_watchdog(void *data)
unsigned long flags;
unsigned long now;
msleep(5000);
msleep_interruptible(5000);
traced_lock(&output->check_lock, flags);

View File

@ -358,7 +358,7 @@ static int sio_watchdog(void *data)
while (!kthread_should_stop()) {
int i;
msleep(5000);
msleep_interruptible(5000);
for (i = 0; i <= WITH_THREAD; i++) {
struct sio_threadinfo *tinfo = &output->tinfo[i];

View File

@ -1867,36 +1867,14 @@ done:
return status;
}
static
int __update_all_links(struct mars_global *global, struct mars_dent *parent, struct trans_logger_brick *trans_brick)
{
struct trans_logger_input *old_input = NULL; // FIXME: kludge, do it right(tm)
int i;
int status = 0;
for (i = TL_INPUT_FW_LOG1; i <= TL_INPUT_FW_LOG2; i++) {
struct trans_logger_input *trans_input;
trans_input = trans_brick->inputs[i];
if (!trans_input || trans_input == old_input) {
continue;
}
status = _update_replaylink(parent, trans_input->inf_host, trans_input->inf_sequence, trans_input->replay_min_pos, trans_input->replay_max_pos, true);
status = _update_versionlink(global, parent, trans_input->inf_host, trans_input->inf_sequence, trans_input->replay_min_pos, trans_input->replay_max_pos);
old_input = trans_input;
}
return status;
}
static
int make_log_finalize(struct mars_global *global, struct mars_dent *dent)
{
struct mars_dent *parent = dent->d_parent;
struct mars_rotate *rot;
struct mars_rotate *rot = parent->d_private;
struct trans_logger_brick *trans_brick;
int status = -EINVAL;
CHECK_PTR(parent, done);
rot = parent->d_private;
CHECK_PTR(rot, done);
trans_brick = rot->trans_brick;
status = 0;
@ -1921,7 +1899,18 @@ int make_log_finalize(struct mars_global *global, struct mars_dent *dent)
MARS_DBG("do_stop = %d\n", (int)do_stop);
if (do_stop || (long long)jiffies > rot->last_jiffies + 5 * HZ) {
status = __update_all_links(global, parent, trans_brick);
struct trans_logger_input *old_input = NULL; // FIXME: kludge, do it right(tm)
int i;
for (i = TL_INPUT_FW_LOG1; i <= TL_INPUT_FW_LOG2; i++) {
struct trans_logger_input *trans_input;
trans_input = trans_brick->inputs[i];
if (!trans_input || trans_input == old_input) {
continue;
}
status = _update_replaylink(parent, trans_input->inf_host, trans_input->inf_sequence, trans_input->replay_min_pos, trans_input->replay_max_pos, true);
status = _update_versionlink(global, parent, trans_input->inf_host, trans_input->inf_sequence, trans_input->replay_min_pos, trans_input->replay_max_pos);
old_input = trans_input;
}
rot->last_jiffies = jiffies;
}
if (do_stop) {
@ -1952,9 +1941,6 @@ int make_log_finalize(struct mars_global *global, struct mars_dent *dent)
if (do_start) {
status = _start_trans(rot);
if (status >= 0) {
status = __update_all_links(global, parent, trans_brick);
}
rot->current_log = rot->relevant_log;
}
} else {
@ -2281,7 +2267,6 @@ static int make_sync(void *buf, struct mars_dent *dent)
const char *copy_path = NULL;
const char *src = NULL;
const char *dst = NULL;
bool do_start = true;
int status;
if (!global->global_power.button || !dent->d_parent || !dent->new_link) {
@ -2322,7 +2307,8 @@ static int make_sync(void *buf, struct mars_dent *dent)
}
if (start_pos == end_pos) {
MARS_DBG("no data sync necessary, size = %lld\n", start_pos);
do_start = false;
status = 0;
goto done;
}
brick_string_free(tmp);
@ -2353,11 +2339,11 @@ static int make_sync(void *buf, struct mars_dent *dent)
if (unlikely(!src || !dst || !copy_path || !switch_path))
goto done;
MARS_DBG("initial sync '%s' => '%s' do_start = %d\n", src, dst, do_start);
MARS_DBG("starting initial sync '%s' => '%s'\n", src, dst);
{
const char *argv[2] = { src, dst };
status = __make_copy(global, dent, do_start ? switch_path : "", copy_path, dent->d_parent->d_path, argv, start_pos, &copy);
status = __make_copy(global, dent, switch_path, copy_path, dent->d_parent->d_path, argv, start_pos, &copy);
}
/* Update syncstatus symlink
@ -2377,11 +2363,16 @@ static int make_sync(void *buf, struct mars_dent *dent)
done:
MARS_DBG("status = %d\n", status);
brick_string_free(tmp);
brick_string_free(src);
brick_string_free(dst);
brick_string_free(copy_path);
brick_string_free(switch_path);
if (tmp)
brick_string_free(tmp);
if (src)
brick_string_free(src);
if (dst)
brick_string_free(dst);
if (copy_path)
brick_string_free(copy_path);
if (switch_path)
brick_string_free(switch_path);
return status;
}

View File

@ -95,25 +95,12 @@ sub check_primary_gone {
}
}
sub check_todo {
my ($res, $key, $val, $wait) = @_;
for(;;) {
my $path = "$mars/resource-$res/todo-$host/$key";
my $link = readlink($path) or die "cannot read symlink '$path'\n";
last if $link == $val;
die "$path must have value $val\n" if $wait;
print "waiting until $key reaches the value $val....\n";
sleep(5);
}
}
sub check_status {
my ($res, $key, $val, $wait) = @_;
my ($res, $key, $val) = @_;
for(;;) {
my $path = "$mars/resource-$res/actual-$host/$key";
my $link = readlink($path) or die "cannot read symlink '$path'\n";
last if $link == $val;
die "$path must have value $val\n" if $wait;
print "waiting until $key reaches the value $val....\n";
sleep(5);
}
@ -122,12 +109,7 @@ sub check_status {
sub check_splitbrain {
my ($res, $host) = @_;
my @links = glob("$mars/resource-$res/version-[0-9]*-$host");
if(!@links) {
my @links = glob("$mars/resource-$res/version-[0-9]*-*");
die "no version information available\n" unless @links;
print "assuming that I am primary for the first time\n";
return;
}
die "no version information available for host $host\n" unless @links;
my $link = pop @links;
die "cannot pop last link element\n" unless $link;
my $version = readlink($link);
@ -308,6 +290,15 @@ sub create_res {
}
die "sizes differ: real size = $oldsize, but requested size = $size\n" unless $oldsize == $size;
$replay = readlink("$tmp/replay-$primary") or die "cannot read replay status of primary '$primary'\n";
$replay =~ s/,[0-9]+,[0-9]+$/,0,0/ or die "something is wrong here\n";
my $nr = $replay;
$nr =~ s/^.*log-([0-9]+)-.+$/$1/;
if($nr > 1) { # fake version symlink for predecessor logfile
my $prev = sprintf("$tmp/version-%09d-$primary", $nr - 1);
my $version = readlink($prev) or die "cannot read symlink '$prev'\n";
my $old = sprintf("$tmp/version-%09d-$host", $nr - 1);
symlink($version, $old) or die "cann create symlink '$old'\n";
}
}
my $file = "$tmp/data-$host";
@ -462,7 +453,6 @@ sub primary_res {
} else { # try to switch myself to primary
print "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)";
check_primary_gone($res);
check_splitbrain($res, $host);