flexnbd: add a mirror-speed command to change mirror->max_bytes_per_second
It's not actually honoured yet, and ideally, you'd also be able to set it as part of the initial setup: "flexnbd mirror ... -m 4G". remote_argv for the mirror case would need to become x=y z=w format first, though.
This commit is contained in:
@@ -310,7 +310,6 @@ enum mirror_state control_client_mirror_wait(
|
|||||||
return mirror_state;
|
return mirror_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define write_socket(msg) write(client->socket, (msg "\n"), strlen((msg))+1)
|
#define write_socket(msg) write(client->socket, (msg "\n"), strlen((msg))+1)
|
||||||
/** Command parser to start mirror process from socket input */
|
/** Command parser to start mirror process from socket input */
|
||||||
int control_mirror(struct control_client* client, int linesc, char** lines)
|
int control_mirror(struct control_client* client, int linesc, char** lines)
|
||||||
@@ -437,8 +436,41 @@ int control_mirror(struct control_client* client, int linesc, char** lines)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef write_socket
|
int control_mirror_max_bps( struct control_client* client, int linesc, char** lines )
|
||||||
|
{
|
||||||
|
NULLCHECK( client );
|
||||||
|
NULLCHECK( client->flexnbd );
|
||||||
|
|
||||||
|
struct server* serve = flexnbd_server( client->flexnbd );
|
||||||
|
uint64_t max_Bps;
|
||||||
|
|
||||||
|
if ( !serve->mirror_super ) {
|
||||||
|
write_socket( "1: Not currently mirroring" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( linesc != 1 ) {
|
||||||
|
write_socket( "1: Bad format" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
max_Bps = strtoull( lines[0], NULL, 10 );
|
||||||
|
if ( errno == ERANGE ) {
|
||||||
|
write_socket( "1: max_bps out of range" );
|
||||||
|
return -1;
|
||||||
|
} else if ( errno != 0 ) {
|
||||||
|
write_socket( "1: max_bps couldn't be parsed" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
serve->mirror->max_bytes_per_second = max_Bps;
|
||||||
|
write_socket( "0: updated" );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef write_socket
|
||||||
|
|
||||||
/** Command parser to alter access control list from socket input */
|
/** Command parser to alter access control list from socket input */
|
||||||
int control_acl(struct control_client* client, int linesc, char** lines)
|
int control_acl(struct control_client* client, int linesc, char** lines)
|
||||||
@@ -581,6 +613,11 @@ void control_respond(struct control_client * client)
|
|||||||
if (control_status(client, linesc-1, lines+1) < 0) {
|
if (control_status(client, linesc-1, lines+1) < 0) {
|
||||||
debug("status command failed");
|
debug("status command failed");
|
||||||
}
|
}
|
||||||
|
} else if ( strcmp( lines[0], "mirror_max_bps" ) == 0 ) {
|
||||||
|
info( "mirror_max_bps command received" );
|
||||||
|
if( control_mirror_max_bps( client, linesc-1, lines+1 ) < 0 ) {
|
||||||
|
debug( "mirror_max_bps command failed" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
write(client->socket, "10: unknown command\n", 23);
|
write(client->socket, "10: unknown command\n", 23);
|
||||||
|
78
src/mode.c
78
src/mode.c
@@ -113,6 +113,24 @@ static char acl_help_text[] =
|
|||||||
VERBOSE_LINE
|
VERBOSE_LINE
|
||||||
QUIET_LINE;
|
QUIET_LINE;
|
||||||
|
|
||||||
|
static struct option mirror_speed_options[] = {
|
||||||
|
GETOPT_HELP,
|
||||||
|
GETOPT_SOCK,
|
||||||
|
GETOPT_MAX_SPEED,
|
||||||
|
GETOPT_QUIET,
|
||||||
|
GETOPT_VERBOSE,
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
static char mirror_speed_short_options[] = "hs:m:" SOPT_QUIET SOPT_VERBOSE;
|
||||||
|
static char mirror_speed_help_text[] =
|
||||||
|
"Usage: flexnbd " CMD_MIRROR_SPEED " <options>\n\n"
|
||||||
|
"Set the maximum speed of a migration from a mirring server listening on SOCK.\n\n"
|
||||||
|
HELP_LINE
|
||||||
|
SOCK_LINE
|
||||||
|
MAX_SPEED_LINE
|
||||||
|
VERBOSE_LINE
|
||||||
|
QUIET_LINE;
|
||||||
|
|
||||||
static struct option mirror_options[] = {
|
static struct option mirror_options[] = {
|
||||||
GETOPT_HELP,
|
GETOPT_HELP,
|
||||||
GETOPT_SOCK,
|
GETOPT_SOCK,
|
||||||
@@ -179,6 +197,7 @@ char help_help_text_arr[] =
|
|||||||
"\tflexnbd write\n"
|
"\tflexnbd write\n"
|
||||||
"\tflexnbd acl\n"
|
"\tflexnbd acl\n"
|
||||||
"\tflexnbd mirror\n"
|
"\tflexnbd mirror\n"
|
||||||
|
"\tflexnbd mirror-speed\n"
|
||||||
"\tflexnbd break\n"
|
"\tflexnbd break\n"
|
||||||
"\tflexnbd status\n"
|
"\tflexnbd status\n"
|
||||||
"\tflexnbd help\n\n"
|
"\tflexnbd help\n\n"
|
||||||
@@ -333,6 +352,36 @@ void read_acl_param( int c, char **sock )
|
|||||||
read_sock_param( c, sock, acl_help_text );
|
read_sock_param( c, sock, acl_help_text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read_mirror_speed_param(
|
||||||
|
int c,
|
||||||
|
char **sock,
|
||||||
|
char **max_speed
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch( c ) {
|
||||||
|
case 'h':
|
||||||
|
fprintf( stdout, "%s\n", mirror_speed_help_text );
|
||||||
|
exit( 0 );
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
*sock = optarg;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
*max_speed = optarg;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
log_level = QUIET_LOG_LEVEL;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
log_level = VERBOSE_LOG_LEVEL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit_err( mirror_speed_help_text );
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void read_mirror_param(
|
void read_mirror_param(
|
||||||
int c,
|
int c,
|
||||||
char **sock,
|
char **sock,
|
||||||
@@ -655,6 +704,33 @@ int mode_acl( int argc, char *argv[] )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mode_mirror_speed( int argc, char *argv[] )
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
char *sock = NULL;
|
||||||
|
char *speed = NULL;
|
||||||
|
|
||||||
|
while( 1 ) {
|
||||||
|
c = getopt_long( argc, argv, mirror_speed_short_options, mirror_speed_options, NULL );
|
||||||
|
if ( -1 == c ) { break; }
|
||||||
|
read_mirror_speed_param( c, &sock, &speed );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( NULL == sock ) {
|
||||||
|
fprintf( stderr, "--sock is required.\n" );
|
||||||
|
exit_err( mirror_speed_help_text );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( NULL == speed ) {
|
||||||
|
fprintf( stderr, "--max-speed is required.\n");
|
||||||
|
exit_err( mirror_speed_help_text );
|
||||||
|
}
|
||||||
|
|
||||||
|
do_remote_command( "mirror_max_bps", sock, 1, &speed );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int mode_mirror( int argc, char *argv[] )
|
int mode_mirror( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -787,6 +863,8 @@ void mode(char* mode, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if ( IS_CMD( CMD_ACL, mode ) ) {
|
else if ( IS_CMD( CMD_ACL, mode ) ) {
|
||||||
mode_acl( argc, argv );
|
mode_acl( argc, argv );
|
||||||
|
} else if ( IS_CMD ( CMD_MIRROR_SPEED, mode ) ) {
|
||||||
|
mode_mirror_speed( argc, argv );
|
||||||
}
|
}
|
||||||
else if ( IS_CMD( CMD_MIRROR, mode ) ) {
|
else if ( IS_CMD( CMD_MIRROR, mode ) ) {
|
||||||
mode_mirror( argc, argv );
|
mode_mirror( argc, argv );
|
||||||
|
@@ -23,6 +23,7 @@ void mode(char* mode, int argc, char **argv);
|
|||||||
#define OPT_CONNECT_ADDR "conn-addr"
|
#define OPT_CONNECT_ADDR "conn-addr"
|
||||||
#define OPT_CONNECT_PORT "conn-port"
|
#define OPT_CONNECT_PORT "conn-port"
|
||||||
#define OPT_KILLSWITCH "killswitch"
|
#define OPT_KILLSWITCH "killswitch"
|
||||||
|
#define OPT_MAX_SPEED "max-speed"
|
||||||
|
|
||||||
#define CMD_SERVE "serve"
|
#define CMD_SERVE "serve"
|
||||||
#define CMD_LISTEN "listen"
|
#define CMD_LISTEN "listen"
|
||||||
@@ -30,10 +31,11 @@ void mode(char* mode, int argc, char **argv);
|
|||||||
#define CMD_WRITE "write"
|
#define CMD_WRITE "write"
|
||||||
#define CMD_ACL "acl"
|
#define CMD_ACL "acl"
|
||||||
#define CMD_MIRROR "mirror"
|
#define CMD_MIRROR "mirror"
|
||||||
|
#define CMD_MIRROR_SPEED "mirror-speed"
|
||||||
#define CMD_BREAK "break"
|
#define CMD_BREAK "break"
|
||||||
#define CMD_STATUS "status"
|
#define CMD_STATUS "status"
|
||||||
#define CMD_HELP "help"
|
#define CMD_HELP "help"
|
||||||
#define LEN_CMD_MAX 7
|
#define LEN_CMD_MAX 13
|
||||||
|
|
||||||
#define PATH_LEN_MAX 1024
|
#define PATH_LEN_MAX 1024
|
||||||
#define ADDR_LEN_MAX 64
|
#define ADDR_LEN_MAX 64
|
||||||
@@ -54,6 +56,7 @@ void mode(char* mode, int argc, char **argv);
|
|||||||
#define GETOPT_CONNECT_ADDR GETOPT_ARG( OPT_CONNECT_ADDR, 'C' )
|
#define GETOPT_CONNECT_ADDR GETOPT_ARG( OPT_CONNECT_ADDR, 'C' )
|
||||||
#define GETOPT_CONNECT_PORT GETOPT_ARG( OPT_CONNECT_PORT, 'P' )
|
#define GETOPT_CONNECT_PORT GETOPT_ARG( OPT_CONNECT_PORT, 'P' )
|
||||||
#define GETOPT_KILLSWITCH GETOPT_ARG( OPT_KILLSWITCH, 'k' )
|
#define GETOPT_KILLSWITCH GETOPT_ARG( OPT_KILLSWITCH, 'k' )
|
||||||
|
#define GETOPT_MAX_SPEED GETOPT_ARG( OPT_MAX_SPEED, 'm' )
|
||||||
|
|
||||||
#define OPT_VERBOSE "verbose"
|
#define OPT_VERBOSE "verbose"
|
||||||
#define SOPT_VERBOSE "v"
|
#define SOPT_VERBOSE "v"
|
||||||
@@ -82,7 +85,8 @@ void mode(char* mode, int argc, char **argv);
|
|||||||
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket.\n"
|
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket.\n"
|
||||||
#define BIND_LINE \
|
#define BIND_LINE \
|
||||||
"\t--" OPT_BIND ",-b <BIND-ADDR>\tBind the local socket to a particular IP address.\n"
|
"\t--" OPT_BIND ",-b <BIND-ADDR>\tBind the local socket to a particular IP address.\n"
|
||||||
|
#define MAX_SPEED_LINE \
|
||||||
|
"\t--" OPT_MAX_SPEED ",-m <bps>\tMaximum speed of the migration, in bytes/sec.\n"
|
||||||
|
|
||||||
char * help_help_text;
|
char * help_help_text;
|
||||||
|
|
||||||
|
18
src/remote.c
18
src/remote.c
@@ -17,7 +17,7 @@ void print_response( const char * response )
|
|||||||
exit_status = atoi(response);
|
exit_status = atoi(response);
|
||||||
response_text = strchr( response, ':' );
|
response_text = strchr( response, ':' );
|
||||||
|
|
||||||
FATAL_IF_NULL( response_text,
|
FATAL_IF_NULL( response_text,
|
||||||
"Error parsing server response: '%s'", response );
|
"Error parsing server response: '%s'", response );
|
||||||
|
|
||||||
out = exit_status > 0 ? stderr : stdout;
|
out = exit_status > 0 ? stderr : stdout;
|
||||||
@@ -32,19 +32,19 @@ void do_remote_command(char* command, char* socket_name, int argc, char** argv)
|
|||||||
int remote = socket(AF_UNIX, SOCK_STREAM, 0);
|
int remote = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
struct sockaddr_un address;
|
struct sockaddr_un address;
|
||||||
char response[max_response];
|
char response[max_response];
|
||||||
|
|
||||||
memset(&address, 0, sizeof(address));
|
memset(&address, 0, sizeof(address));
|
||||||
|
|
||||||
FATAL_IF_NEGATIVE(remote, "Couldn't create client socket");
|
FATAL_IF_NEGATIVE(remote, "Couldn't create client socket");
|
||||||
|
|
||||||
address.sun_family = AF_UNIX;
|
address.sun_family = AF_UNIX;
|
||||||
strncpy(address.sun_path, socket_name, sizeof(address.sun_path));
|
strncpy(address.sun_path, socket_name, sizeof(address.sun_path));
|
||||||
|
|
||||||
FATAL_IF_NEGATIVE(
|
FATAL_IF_NEGATIVE(
|
||||||
connect(remote, (struct sockaddr*) &address, sizeof(address)),
|
connect(remote, (struct sockaddr*) &address, sizeof(address)),
|
||||||
"Couldn't connect to %s", socket_name
|
"Couldn't connect to %s", socket_name
|
||||||
);
|
);
|
||||||
|
|
||||||
write(remote, command, strlen(command));
|
write(remote, command, strlen(command));
|
||||||
write(remote, &newline, 1);
|
write(remote, &newline, 1);
|
||||||
for (i=0; i<argc; i++) {
|
for (i=0; i<argc; i++) {
|
||||||
@@ -54,16 +54,16 @@ void do_remote_command(char* command, char* socket_name, int argc, char** argv)
|
|||||||
write(remote, &newline, 1);
|
write(remote, &newline, 1);
|
||||||
}
|
}
|
||||||
write(remote, &newline, 1);
|
write(remote, &newline, 1);
|
||||||
|
|
||||||
FATAL_IF_NEGATIVE(
|
FATAL_IF_NEGATIVE(
|
||||||
read_until_newline(remote, response, max_response),
|
read_until_newline(remote, response, max_response),
|
||||||
"Couldn't read response from %s", socket_name
|
"Couldn't read response from %s", socket_name
|
||||||
);
|
);
|
||||||
|
|
||||||
print_response( response );
|
print_response( response );
|
||||||
|
|
||||||
exit(atoi(response));
|
exit(atoi(response));
|
||||||
|
|
||||||
close(remote);
|
close(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user