diff --git a/src/client.c b/src/client.c index fb99c39..a5cd56d 100644 --- a/src/client.c +++ b/src/client.c @@ -500,6 +500,10 @@ void client_arm_killswitch( struct client* client ) .it_interval = { .tv_nsec = 0, .tv_sec = 0 } }; + if ( !client->serve->use_killswitch ) { + return; + } + debug( "Arming killswitch" ); FATAL_IF_NEGATIVE( @@ -517,6 +521,10 @@ void client_disarm_killswitch( struct client* client ) .it_interval = { .tv_nsec = 0, .tv_sec = 0 } }; + if ( !client->serve->use_killswitch ) { + return; + } + debug( "Disarming killswitch" ); FATAL_IF_NEGATIVE( diff --git a/src/client.h b/src/client.h index 8a16109..0f0ae0c 100644 --- a/src/client.h +++ b/src/client.h @@ -47,7 +47,9 @@ struct client { /* Have we seen a REQUEST_DISCONNECT message? */ 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; }; diff --git a/src/flexnbd.c b/src/flexnbd.c index 59c9f09..b2ee744 100644 --- a/src/flexnbd.c +++ b/src/flexnbd.c @@ -86,7 +86,8 @@ struct flexnbd * flexnbd_create_serving( int default_deny, int acl_entries, char** s_acl_entries, - int max_nbd_clients) + int max_nbd_clients, + int use_killswitch) { struct flexnbd * flexnbd = xmalloc( sizeof( struct flexnbd ) ); flexnbd->serve = server_create( @@ -98,6 +99,7 @@ struct flexnbd * flexnbd_create_serving( acl_entries, s_acl_entries, max_nbd_clients, + use_killswitch, 1); flexnbd_create_shared( flexnbd, s_ctrl_sock ); @@ -123,7 +125,7 @@ struct flexnbd * flexnbd_create_listening( default_deny, acl_entries, s_acl_entries, - 1, 0); + 1, 0, 0); flexnbd_create_shared( flexnbd, s_ctrl_sock ); return flexnbd; } diff --git a/src/flexnbd.h b/src/flexnbd.h index 9e226ef..cb4a04b 100644 --- a/src/flexnbd.h +++ b/src/flexnbd.h @@ -36,7 +36,8 @@ struct flexnbd * flexnbd_create_serving( int default_deny, int acl_entries, char** s_acl_entries, - int max_nbd_clients); + int max_nbd_clients, + int use_killswitch); struct flexnbd * flexnbd_create_listening( char* s_ip_address, diff --git a/src/mode.c b/src/mode.c index 3122583..eae6fc7 100644 --- a/src/mode.c +++ b/src/mode.c @@ -15,10 +15,11 @@ static struct option serve_options[] = { GETOPT_SOCK, GETOPT_DENY, GETOPT_QUIET, + GETOPT_KILLSWITCH, GETOPT_VERBOSE, {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[] = "Usage: flexnbd " CMD_SERVE " [*]\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 \tThe port to serve on.\n" "\t--" OPT_FILE ",-f \tThe file to serve.\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 VERBOSE_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 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){ case 'h': @@ -221,6 +223,9 @@ void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char case 'v': log_level = VERBOSE_LOG_LEVEL; break; + case 'k': + *use_killswitch = 1; + break; default: exit_err( serve_help_text ); break; @@ -404,6 +409,7 @@ int mode_serve( int argc, char *argv[] ) char *file = NULL; char *sock = NULL; int default_deny = 0; // not on by default + int use_killswitch = 0; int err = 0; int success; @@ -414,7 +420,7 @@ int mode_serve( int argc, char *argv[] ) c = getopt_long(argc, argv, serve_short_options, serve_options, NULL); 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 ) { @@ -427,7 +433,7 @@ int mode_serve( int argc, char *argv[] ) } 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 ); success = flexnbd_serve( flexnbd ); flexnbd_destroy( flexnbd ); diff --git a/src/mode.h b/src/mode.h index d62168b..1f902ff 100644 --- a/src/mode.h +++ b/src/mode.h @@ -22,6 +22,7 @@ void mode(char* mode, int argc, char **argv); #define OPT_UNLINK "unlink" #define OPT_CONNECT_ADDR "conn-addr" #define OPT_CONNECT_PORT "conn-port" +#define OPT_KILLSWITCH "killswitch" #define CMD_SERVE "serve" #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_CONNECT_ADDR GETOPT_ARG( OPT_CONNECT_ADDR, 'C' ) #define GETOPT_CONNECT_PORT GETOPT_ARG( OPT_CONNECT_PORT, 'P' ) +#define GETOPT_KILLSWITCH GETOPT_ARG( OPT_KILLSWITCH, 'k' ) #define OPT_VERBOSE "verbose" #define SOPT_VERBOSE "v" diff --git a/src/serve.c b/src/serve.c index 0995f1e..43e8cb2 100644 --- a/src/serve.c +++ b/src/serve.c @@ -30,6 +30,7 @@ struct server * server_create ( int acl_entries, char** s_acl_entries, int max_nbd_clients, + int use_killswitch, int success) { NULLCHECK( flexnbd ); @@ -38,8 +39,9 @@ struct server * server_create ( out->flexnbd = flexnbd; out->success = success; 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? */ FATAL_IF_NULL(s_ip_address, "No IP address supplied"); diff --git a/src/serve.h b/src/serve.h index 2d44408..97faa37 100644 --- a/src/serve.h +++ b/src/serve.h @@ -87,6 +87,9 @@ struct server { int max_nbd_clients; 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 * the file, or if we're waiting to receive it from an inbound @@ -107,6 +110,7 @@ struct server * server_create( int acl_entries, char** s_acl_entries, int max_nbd_clients, + int use_killswitch, int success ); void server_destroy( struct server * ); int server_is_closed(struct server* serve);