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:
@@ -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(
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
14
src/mode.c
14
src/mode.c
@@ -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 );
|
||||||
|
@@ -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"
|
||||||
|
@@ -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");
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user