2012-06-27 16:19:13 +01:00
|
|
|
#ifndef MIRROR_H
|
|
|
|
#define MIRROR_H
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
#include "bitset.h"
|
|
|
|
#include "self_pipe.h"
|
|
|
|
enum mirror_state;
|
|
|
|
#include "serve.h"
|
2012-07-15 19:46:35 +01:00
|
|
|
#include "mbox.h"
|
2012-06-27 16:19:13 +01:00
|
|
|
|
2012-06-28 14:45:53 +01:00
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
/* MS_CONNECT_TIME_SECS
|
|
|
|
* The length of time after which the sender will assume a connect() to
|
|
|
|
* the destination has failed.
|
|
|
|
*/
|
|
|
|
#define MS_CONNECT_TIME_SECS 60
|
|
|
|
|
2013-09-24 14:42:21 +01:00
|
|
|
/* MS_MAX_DOWNTIME_SECS
|
|
|
|
* The length of time a migration must be estimated to have remaining for us to
|
|
|
|
* disconnect clients for convergence
|
|
|
|
*
|
|
|
|
* TODO: Make this configurable so refusing-to-converge clients can be manually
|
|
|
|
* fixed.
|
|
|
|
* TODO: Make this adaptive - 5 seconds is fine, as long as we can guarantee
|
|
|
|
* that all migrations will be able to converge in time. We'd add a new
|
|
|
|
* state between open and closed, where gradually-increasing latency is
|
|
|
|
* added to client requests to allow the mirror to be faster.
|
|
|
|
*/
|
|
|
|
#define MS_CONVERGE_TIME_SECS 5
|
2012-06-28 14:45:53 +01:00
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
/* MS_HELLO_TIME_SECS
|
|
|
|
* The length of time the sender will wait for the NBD hello message
|
|
|
|
* after connect() before aborting the connection attempt.
|
|
|
|
*/
|
|
|
|
#define MS_HELLO_TIME_SECS 5
|
|
|
|
|
|
|
|
|
|
|
|
/* MS_RETRY_DELAY_SECS
|
|
|
|
* The delay after a failed migration attempt before launching another
|
|
|
|
* thread to try again.
|
|
|
|
*/
|
|
|
|
#define MS_RETRY_DELAY_SECS 1
|
|
|
|
|
2012-06-28 14:45:53 +01:00
|
|
|
|
|
|
|
/* MS_REQUEST_LIMIT_SECS
|
|
|
|
* We must receive a reply to a request within this time. For a read
|
|
|
|
* request, this is the time between the end of the NBD request and the
|
|
|
|
* start of the NBD reply. For a write request, this is the time
|
|
|
|
* between the end of the written data and the start of the NBD reply.
|
|
|
|
*/
|
|
|
|
#define MS_REQUEST_LIMIT_SECS 4
|
2013-08-09 17:02:10 +01:00
|
|
|
#define MS_REQUEST_LIMIT_SECS_F 4.0
|
2012-06-28 14:45:53 +01:00
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
enum mirror_finish_action {
|
|
|
|
ACTION_EXIT,
|
2012-07-23 10:22:25 +01:00
|
|
|
ACTION_UNLINK,
|
2012-06-27 16:19:13 +01:00
|
|
|
ACTION_NOTHING
|
|
|
|
};
|
|
|
|
|
|
|
|
enum mirror_state {
|
|
|
|
MS_UNKNOWN,
|
|
|
|
MS_INIT,
|
|
|
|
MS_GO,
|
2013-08-12 15:30:21 +01:00
|
|
|
MS_ABANDONED,
|
2012-06-27 16:19:13 +01:00
|
|
|
MS_DONE,
|
|
|
|
MS_FAIL_CONNECT,
|
|
|
|
MS_FAIL_REJECTED,
|
|
|
|
MS_FAIL_NO_HELLO,
|
|
|
|
MS_FAIL_SIZE_MISMATCH
|
|
|
|
};
|
|
|
|
|
2012-07-12 14:54:48 +01:00
|
|
|
struct mirror {
|
2012-06-27 16:19:13 +01:00
|
|
|
pthread_t thread;
|
2013-08-12 15:30:21 +01:00
|
|
|
|
|
|
|
/* Signal to this then join the thread if you want to abandon mirroring */
|
|
|
|
struct self_pipe * abandon_signal;
|
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
union mysockaddr * connect_to;
|
|
|
|
union mysockaddr * connect_from;
|
|
|
|
int client;
|
|
|
|
const char * filename;
|
2013-07-26 11:50:01 +01:00
|
|
|
|
2013-09-18 16:28:05 +01:00
|
|
|
/* Limiter, used to restrict migration speed Only dirty bytes (those going
|
|
|
|
* over the network) are considered */
|
2013-08-13 12:30:18 +01:00
|
|
|
uint64_t max_bytes_per_second;
|
2013-07-26 11:50:01 +01:00
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
enum mirror_finish_action action_at_finish;
|
2013-07-08 09:58:31 +01:00
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
char *mapped;
|
2013-09-19 15:18:30 +01:00
|
|
|
|
2013-09-20 17:08:14 +01:00
|
|
|
/* We need to send every byte at least once; we do so by */
|
|
|
|
uint64_t offset;
|
2012-06-27 16:19:13 +01:00
|
|
|
|
2012-07-15 19:46:35 +01:00
|
|
|
enum mirror_state commit_state;
|
2012-06-27 16:19:13 +01:00
|
|
|
|
|
|
|
/* commit_signal is sent immediately after attempting to connect
|
|
|
|
* and checking the remote size, whether successful or not.
|
|
|
|
*/
|
2012-07-15 19:46:35 +01:00
|
|
|
struct mbox * commit_signal;
|
2013-07-08 09:58:31 +01:00
|
|
|
|
2013-09-20 17:08:14 +01:00
|
|
|
/* The time (from monotonic_time_ms()) the migration was started. Can be
|
|
|
|
* used to calculate bps, etc. */
|
|
|
|
uint64_t migration_started;
|
|
|
|
|
2013-09-23 14:20:05 +01:00
|
|
|
/* Running count of all bytes we've transferred */
|
2013-07-26 11:50:01 +01:00
|
|
|
uint64_t all_dirty;
|
2012-06-27 16:19:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct mirror_super {
|
2012-07-12 14:54:48 +01:00
|
|
|
struct mirror * mirror;
|
2012-06-27 16:19:13 +01:00
|
|
|
pthread_t thread;
|
|
|
|
struct mbox * state_mbox;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* We need these declaration to get around circular dependencies in the
|
|
|
|
* .h's
|
|
|
|
*/
|
|
|
|
struct server;
|
|
|
|
struct flexnbd;
|
|
|
|
|
|
|
|
struct mirror_super * mirror_super_create(
|
|
|
|
const char * filename,
|
|
|
|
union mysockaddr * connect_to,
|
|
|
|
union mysockaddr * connect_from,
|
2013-08-13 12:30:18 +01:00
|
|
|
uint64_t max_Bps,
|
|
|
|
enum mirror_finish_action action_at_finish,
|
2012-07-15 21:57:36 +01:00
|
|
|
struct mbox * state_mbox
|
|
|
|
);
|
2012-06-27 16:19:13 +01:00
|
|
|
void * mirror_super_runner( void * serve_uncast );
|
2013-08-12 15:30:21 +01:00
|
|
|
|
2012-06-27 16:19:13 +01:00
|
|
|
#endif
|
2013-07-08 09:58:31 +01:00
|
|
|
|