diff --git a/sy_old/mars_light.c b/sy_old/mars_light.c index 0a2da69f..67db6fa3 100644 --- a/sy_old/mars_light.c +++ b/sy_old/mars_light.c @@ -1867,14 +1867,36 @@ 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 = parent->d_private; + struct mars_rotate *rot; 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; @@ -1899,18 +1921,7 @@ 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) { - 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; - } + status = __update_all_links(global, parent, trans_brick); rot->last_jiffies = jiffies; } if (do_stop) { @@ -1941,6 +1952,9 @@ 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 { @@ -2267,6 +2281,7 @@ 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) { @@ -2307,8 +2322,7 @@ 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); - status = 0; - goto done; + do_start = false; } brick_string_free(tmp); @@ -2339,11 +2353,11 @@ static int make_sync(void *buf, struct mars_dent *dent) if (unlikely(!src || !dst || !copy_path || !switch_path)) goto done; - MARS_DBG("starting initial sync '%s' => '%s'\n", src, dst); + MARS_DBG("initial sync '%s' => '%s' do_start = %d\n", src, dst, do_start); { const char *argv[2] = { src, dst }; - status = __make_copy(global, dent, switch_path, copy_path, dent->d_parent->d_path, argv, start_pos, ©); + status = __make_copy(global, dent, do_start ? switch_path : "", copy_path, dent->d_parent->d_path, argv, start_pos, ©); } /* Update syncstatus symlink @@ -2363,16 +2377,11 @@ static int make_sync(void *buf, struct mars_dent *dent) done: MARS_DBG("status = %d\n", status); - 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); + brick_string_free(tmp); + brick_string_free(src); + brick_string_free(dst); + brick_string_free(copy_path); + brick_string_free(switch_path); return status; } diff --git a/userspace/marsadm b/userspace/marsadm index 2b96f09c..ff01835d 100644 --- a/userspace/marsadm +++ b/userspace/marsadm @@ -95,12 +95,25 @@ 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) = @_; + my ($res, $key, $val, $wait) = @_; 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); } @@ -109,7 +122,12 @@ sub check_status { sub check_splitbrain { my ($res, $host) = @_; my @links = glob("$mars/resource-$res/version-[0-9]*-$host"); - die "no version information available for host $host\n" unless @links; + 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; + } my $link = pop @links; die "cannot pop last link element\n" unless $link; my $version = readlink($link); @@ -290,15 +308,6 @@ 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"; @@ -453,6 +462,7 @@ 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);