flexnbd: Make the killswitch runtime-selectable

We're not actually using it in production right now because it doesn't
shut its sockets down cleanly enough. This is a better option than
reverting the functionality or keeping production downgraded until
we sort out a handler that cleanly closes the sockets.
This commit is contained in:
nick
2013-07-03 09:56:35 +01:00
parent 81d41f567d
commit 9f34752842
8 changed files with 36 additions and 9 deletions

View File

@@ -500,6 +500,10 @@ void client_arm_killswitch( struct client* client )
.it_interval = { .tv_nsec = 0, .tv_sec = 0 } .it_interval = { .tv_nsec = 0, .tv_sec = 0 }
}; };
if ( !client->serve->use_killswitch ) {
return;
}
debug( "Arming killswitch" ); debug( "Arming killswitch" );
FATAL_IF_NEGATIVE( FATAL_IF_NEGATIVE(
@@ -517,6 +521,10 @@ void client_disarm_killswitch( struct client* client )
.it_interval = { .tv_nsec = 0, .tv_sec = 0 } .it_interval = { .tv_nsec = 0, .tv_sec = 0 }
}; };
if ( !client->serve->use_killswitch ) {
return;
}
debug( "Disarming killswitch" ); debug( "Disarming killswitch" );
FATAL_IF_NEGATIVE( FATAL_IF_NEGATIVE(

View File

@@ -47,7 +47,9 @@ struct client {
/* Have we seen a REQUEST_DISCONNECT message? */ /* Have we seen a REQUEST_DISCONNECT message? */
int disconnect; int disconnect;
/* kill the whole server if a request has been outstanding too long */ /* kill the whole server if a request has been outstanding too long,
* assuming use_killswitch is set in serve
*/
timer_t killswitch; timer_t killswitch;
}; };

View File

@@ -86,7 +86,8 @@ struct flexnbd * flexnbd_create_serving(
int default_deny, int default_deny,
int acl_entries, int acl_entries,
char** s_acl_entries, char** s_acl_entries,
int max_nbd_clients) int max_nbd_clients,
int use_killswitch)
{ {
struct flexnbd * flexnbd = xmalloc( sizeof( struct flexnbd ) ); struct flexnbd * flexnbd = xmalloc( sizeof( struct flexnbd ) );
flexnbd->serve = server_create( flexnbd->serve = server_create(
@@ -98,6 +99,7 @@ struct flexnbd * flexnbd_create_serving(
acl_entries, acl_entries,
s_acl_entries, s_acl_entries,
max_nbd_clients, max_nbd_clients,
use_killswitch,
1); 1);
flexnbd_create_shared( flexnbd, flexnbd_create_shared( flexnbd,
s_ctrl_sock ); s_ctrl_sock );
@@ -123,7 +125,7 @@ struct flexnbd * flexnbd_create_listening(
default_deny, default_deny,
acl_entries, acl_entries,
s_acl_entries, s_acl_entries,
1, 0); 1, 0, 0);
flexnbd_create_shared( flexnbd, s_ctrl_sock ); flexnbd_create_shared( flexnbd, s_ctrl_sock );
return flexnbd; return flexnbd;
} }

View File

@@ -36,7 +36,8 @@ struct flexnbd * flexnbd_create_serving(
int default_deny, int default_deny,
int acl_entries, int acl_entries,
char** s_acl_entries, char** s_acl_entries,
int max_nbd_clients); int max_nbd_clients,
int use_killswitch);
struct flexnbd * flexnbd_create_listening( struct flexnbd * flexnbd_create_listening(
char* s_ip_address, char* s_ip_address,

View File

@@ -15,10 +15,11 @@ static struct option serve_options[] = {
GETOPT_SOCK, GETOPT_SOCK,
GETOPT_DENY, GETOPT_DENY,
GETOPT_QUIET, GETOPT_QUIET,
GETOPT_KILLSWITCH,
GETOPT_VERBOSE, GETOPT_VERBOSE,
{0} {0}
}; };
static char serve_short_options[] = "hl:p:f:s:d" SOPT_QUIET SOPT_VERBOSE; static char serve_short_options[] = "hl:p:f:s:dk" SOPT_QUIET SOPT_VERBOSE;
static char serve_help_text[] = static char serve_help_text[] =
"Usage: flexnbd " CMD_SERVE " <options> [<acl address>*]\n\n" "Usage: flexnbd " CMD_SERVE " <options> [<acl address>*]\n\n"
"Serve FILE from ADDR:PORT, with an optional control socket at SOCK.\n\n" "Serve FILE from ADDR:PORT, with an optional control socket at SOCK.\n\n"
@@ -27,6 +28,7 @@ static char serve_help_text[] =
"\t--" OPT_PORT ",-p <PORT>\tThe port to serve on.\n" "\t--" OPT_PORT ",-p <PORT>\tThe port to serve on.\n"
"\t--" OPT_FILE ",-f <FILE>\tThe file to serve.\n" "\t--" OPT_FILE ",-f <FILE>\tThe file to serve.\n"
"\t--" OPT_DENY ",-d\tDeny connections by default unless in ACL.\n" "\t--" OPT_DENY ",-d\tDeny connections by default unless in ACL.\n"
"\t--" OPT_KILLSWITCH",-k \tKill the server if a request takes 120 seconds.\n"
SOCK_LINE SOCK_LINE
VERBOSE_LINE VERBOSE_LINE
QUIET_LINE; QUIET_LINE;
@@ -193,7 +195,7 @@ void do_write(struct mode_readwrite_params* params);
void do_remote_command(char* command, char* mode, int argc, char** argv); void do_remote_command(char* command, char* mode, int argc, char** argv);
void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char **sock, int *default_deny ) void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char **sock, int *default_deny, int *use_killswitch )
{ {
switch(c){ switch(c){
case 'h': case 'h':
@@ -221,6 +223,9 @@ void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char
case 'v': case 'v':
log_level = VERBOSE_LOG_LEVEL; log_level = VERBOSE_LOG_LEVEL;
break; break;
case 'k':
*use_killswitch = 1;
break;
default: default:
exit_err( serve_help_text ); exit_err( serve_help_text );
break; break;
@@ -404,6 +409,7 @@ int mode_serve( int argc, char *argv[] )
char *file = NULL; char *file = NULL;
char *sock = NULL; char *sock = NULL;
int default_deny = 0; // not on by default int default_deny = 0; // not on by default
int use_killswitch = 0;
int err = 0; int err = 0;
int success; int success;
@@ -414,7 +420,7 @@ int mode_serve( int argc, char *argv[] )
c = getopt_long(argc, argv, serve_short_options, serve_options, NULL); c = getopt_long(argc, argv, serve_short_options, serve_options, NULL);
if ( c == -1 ) { break; } if ( c == -1 ) { break; }
read_serve_param( c, &ip_addr, &ip_port, &file, &sock, &default_deny ); read_serve_param( c, &ip_addr, &ip_port, &file, &sock, &default_deny, &use_killswitch );
} }
if ( NULL == ip_addr || NULL == ip_port ) { if ( NULL == ip_addr || NULL == ip_port ) {
@@ -427,7 +433,7 @@ int mode_serve( int argc, char *argv[] )
} }
if ( err ) { exit_err( serve_help_text ); } if ( err ) { exit_err( serve_help_text ); }
flexnbd = flexnbd_create_serving( ip_addr, ip_port, file, sock, default_deny, argc - optind, argv + optind, MAX_NBD_CLIENTS ); flexnbd = flexnbd_create_serving( ip_addr, ip_port, file, sock, default_deny, argc - optind, argv + optind, MAX_NBD_CLIENTS, use_killswitch );
info( "Serving file %s", file ); info( "Serving file %s", file );
success = flexnbd_serve( flexnbd ); success = flexnbd_serve( flexnbd );
flexnbd_destroy( flexnbd ); flexnbd_destroy( flexnbd );

View File

@@ -22,6 +22,7 @@ void mode(char* mode, int argc, char **argv);
#define OPT_UNLINK "unlink" #define OPT_UNLINK "unlink"
#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 CMD_SERVE "serve" #define CMD_SERVE "serve"
#define CMD_LISTEN "listen" #define CMD_LISTEN "listen"
@@ -52,6 +53,7 @@ void mode(char* mode, int argc, char **argv);
#define GETOPT_UNLINK GETOPT_ARG( OPT_UNLINK, 'u' ) #define GETOPT_UNLINK GETOPT_ARG( OPT_UNLINK, 'u' )
#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 OPT_VERBOSE "verbose" #define OPT_VERBOSE "verbose"
#define SOPT_VERBOSE "v" #define SOPT_VERBOSE "v"

View File

@@ -30,6 +30,7 @@ struct server * server_create (
int acl_entries, int acl_entries,
char** s_acl_entries, char** s_acl_entries,
int max_nbd_clients, int max_nbd_clients,
int use_killswitch,
int success) int success)
{ {
NULLCHECK( flexnbd ); NULLCHECK( flexnbd );
@@ -38,8 +39,9 @@ struct server * server_create (
out->flexnbd = flexnbd; out->flexnbd = flexnbd;
out->success = success; out->success = success;
out->max_nbd_clients = max_nbd_clients; out->max_nbd_clients = max_nbd_clients;
out->nbd_client = xmalloc( max_nbd_clients * sizeof( struct client_tbl_entry ) ); out->use_killswitch = use_killswitch;
out->nbd_client = xmalloc( max_nbd_clients * sizeof( struct client_tbl_entry ) );
out->tcp_backlog = 10; /* does this need to be settable? */ out->tcp_backlog = 10; /* does this need to be settable? */
FATAL_IF_NULL(s_ip_address, "No IP address supplied"); FATAL_IF_NULL(s_ip_address, "No IP address supplied");

View File

@@ -87,6 +87,9 @@ struct server {
int max_nbd_clients; int max_nbd_clients;
struct client_tbl_entry *nbd_client; struct client_tbl_entry *nbd_client;
/* Should clients use the killswitch? */
int use_killswitch;
/* Marker for whether this server has control over the data in /* Marker for whether this server has control over the data in
* the file, or if we're waiting to receive it from an inbound * the file, or if we're waiting to receive it from an inbound
@@ -107,6 +110,7 @@ struct server * server_create(
int acl_entries, int acl_entries,
char** s_acl_entries, char** s_acl_entries,
int max_nbd_clients, int max_nbd_clients,
int use_killswitch,
int success ); int success );
void server_destroy( struct server * ); void server_destroy( struct server * );
int server_is_closed(struct server* serve); int server_is_closed(struct server* serve);