Commit Graph

16 Commits

Author SHA1 Message Date
Alex Young
fd935ce4c9 Simplify the migration handover protocol
The three-way hand-off has a problem: there's no way to arrange for the
state of the migration to be unambiguous in case of failure.  If the
final "disconnect" message is lost (as in, the destination never
receives it whether it is sent by the sender or not), the destination
has no option but to quit with an error status and let a human sort it
out.  However, at that point we can either arrange to have a .INCOMPLETE
file still on disc or not - and it doesn't matter which we choose, we
can still end up with dataloss by picking a specific calamity to have
befallen the sender.

Given this, it makes sense to fall back to a simpler protocol: just send
all the data, then send a "disconnect" message.  This has the same
downside that we need a human to sort out specific failure cases, but
combined with --unlink before sending "disconnect" (see next patch) it
will always be possible for a human to disambiguate, whether the
destination quit with an error status or not.
2012-07-23 10:22:25 +01:00
Alex Young
d0b39cce08 Flush bad write data from the client socket.
If the client makes a write that's out of range, by the time we get to
validate the message at the server end the client has already stuffed
the socket with data we can't use, so we have to flush it.

This patch also fixes a potential problem in the acceptance tests where
the error field was being returned as an array rather than a value.
2012-07-15 23:19:12 +01:00
Alex Young
b20fbc6a66 Don't retry a mirror which failed on the first attempt
If the mirror attempt failed and we were able to report an error to the
user, it makes no sense to attempt a retry.  We don't have a way to
abort a mirror attempt yet, so if the user got a setting wrong and it's
failing for that reason, the only recourse they'd have would be to
restart the server.
2012-07-15 20:07:17 +01:00
Alex Young
e77234c6b1 Close the mirror client socket on rejection
If the mirror attempt connects ok, but is rejected (say, for reporting
the wrong size), the client socket needs to be closed.  The destination
end can't close its socket and accept another connection attempt unless
it does.
2012-07-15 18:30:20 +01:00
Alex Young
69ad6d6b7a Only copy constants from C to Ruby once
This avoids unnecessary duplicate constant warnings for C constants that
are defined in two legs of an #ifdef.
2012-07-14 17:25:26 +01:00
Alex Young
e4d2b9a667 Make test sockets less dependent on enviroment
It seems that ruby in a default wheezy VM can't handle a source address
of nil.
2012-07-14 10:04:55 +01:00
Alex Young
10b46beeea Retry failed rebind attempts
When we receive a migration, if rebinding to the new listen address and
port fails for a reason which might be fixable, rather than killing the
server we retry once a second.  Also in this patch: non-overlapping log
messages and a fix for the client going away halfway through a sendfile
loop.
2012-07-12 14:14:46 +01:00
Alex Young
eb90308b6e Handle a failed disconnect correctly
If the sender disconnects its socket before sending the disconnect
message, the destination should restart the migration process.  This
patch makes sure that happens.
2012-07-12 09:39:39 +01:00
Alex Young
f3cebcdcd5 Test a source crashing after an entrust.
This adds a test for destination behaviour, in that if a source crashes
after sending an entrust message but before the destination can reply,
the destination must allow the source to reconnect and retry the mirror.
2012-07-11 15:19:50 +01:00
Alex Young
f3f017a87d Free all possibly held mutexes in error handlers
Now that we have 3 mutexes lying around, it's important that we check
and free these if necessary if error() is called in any thread that can
hold them.  To do this, we now have flexthread.c, which defines a
flexthread_mutex struct.  This is a wrapper around a pthread_mutex_t and
a pthread_t.  The idea is that in the error handler, the thread can
check whether it holds the mutex and can free it if and only if it does.
This is important because pthread fast mutexes can be freed by *any*
thread, not just the thread which holds them.

Note: it is only ever safe for a thread to check if it holds the mutex
itself.  It is *never* safe to check if another thread holds a mutex
without first locking that mutex, which makes the whole operation rather
pointless.
2012-07-11 09:43:16 +01:00
Alex Young
061512f3dc Test that a write reply with the wrong magic will force a retry 2012-07-03 17:01:39 +01:00
Alex Young
5c66d35677 Test that closing the socket immediately after sending write data causes an error 2012-07-03 15:33:00 +01:00
Alex Young
d16aebf36e Test that a disconnect after the write request but before the data is an error 2012-07-03 15:25:39 +01:00
Alex Young
64ebbe7688 Refactor FakeSource from a module to a class 2012-07-03 14:39:05 +01:00
Alex Young
ded4914c84 Simplified FlexNBD::FakeDest 2012-07-03 14:23:20 +01:00
Alex Young
988b2ec014 Moved acceptance tests into tests/acceptance 2012-07-03 10:59:31 +01:00