Files
flexnbd-c/src/listen.c

124 lines
2.7 KiB
C
Raw Normal View History

2012-06-21 18:01:50 +01:00
#include "listen.h"
#include "serve.h"
#include "util.h"
2012-06-27 15:45:33 +01:00
#include "flexnbd.h"
2012-06-21 18:01:50 +01:00
#include <stdlib.h>
struct listen * listen_create(
2012-06-27 15:45:33 +01:00
struct flexnbd * flexnbd,
2012-06-21 18:01:50 +01:00
char* s_ip_address,
char* s_rebind_ip_address,
char* s_port,
char* s_rebind_port,
char* s_file,
int default_deny,
int acl_entries,
char** s_acl_entries,
int max_nbd_clients )
{
2012-06-27 15:45:33 +01:00
NULLCHECK( flexnbd );
2012-06-21 18:01:50 +01:00
struct listen * listen;
2012-06-22 10:05:41 +01:00
listen = (struct listen *)xmalloc( sizeof( struct listen ) );
2012-06-27 15:45:33 +01:00
listen->flexnbd = flexnbd;
2012-06-22 10:05:41 +01:00
listen->init_serve = server_create(
2012-06-27 15:45:33 +01:00
flexnbd,
2012-06-22 10:05:41 +01:00
s_ip_address,
2012-06-21 18:01:50 +01:00
s_port,
s_file,
default_deny,
acl_entries,
s_acl_entries,
1, 0);
listen->main_serve = server_create(
2012-06-27 15:45:33 +01:00
flexnbd,
2012-06-21 18:01:50 +01:00
s_rebind_ip_address ? s_rebind_ip_address : s_ip_address,
2012-06-22 10:05:41 +01:00
s_rebind_port ? s_rebind_port : s_port,
2012-06-21 18:01:50 +01:00
s_file,
default_deny,
acl_entries,
s_acl_entries,
max_nbd_clients, 1);
return listen;
}
void listen_destroy( struct listen * listen )
{
NULLCHECK( listen );
free( listen );
}
2012-06-27 15:45:33 +01:00
struct server *listen_switch( struct listen * listen )
2012-06-21 18:01:50 +01:00
{
NULLCHECK( listen );
/* TODO: Copy acl from init_serve to main_serve */
/* TODO: rename underlying file from foo.INCOMPLETE to foo */
2012-06-27 15:45:33 +01:00
server_destroy( listen->init_serve );
listen->init_serve = NULL;
info( "Switched to the main server, serving." );
return listen->main_serve;
2012-06-21 18:01:50 +01:00
}
void listen_cleanup( struct listen * listen )
2012-06-21 18:01:50 +01:00
{
NULLCHECK( listen );
if ( flexnbd_switch_locked( listen->flexnbd ) ) {
flexnbd_unlock_switch( listen->flexnbd );
}
2012-06-21 18:01:50 +01:00
}
2012-06-27 15:45:33 +01:00
int do_listen( struct listen * listen )
2012-06-21 18:01:50 +01:00
{
NULLCHECK( listen );
int have_control = 0;
flexnbd_lock_switch( listen->flexnbd );
2012-06-27 15:45:33 +01:00
{
flexnbd_set_server( listen->flexnbd, listen->init_serve );
flexnbd_mark_incomplete( listen->flexnbd );
2012-06-27 15:45:33 +01:00
}
flexnbd_unlock_switch( listen->flexnbd );
2012-06-27 15:45:33 +01:00
/* WATCH FOR RACES HERE: flexnbd->serve is set, but the server
* isn't running yet and the switch lock is released.
*/
2012-06-21 18:01:50 +01:00
have_control = do_serve( listen->init_serve );
2012-06-27 15:45:33 +01:00
2012-06-21 18:01:50 +01:00
if( have_control ) {
flexnbd_mark_complete( listen->flexnbd );
2012-06-21 18:01:50 +01:00
info( "Taking control.");
2012-06-27 15:45:33 +01:00
flexnbd_switch( listen->flexnbd, listen_switch );
/* WATCH FOR RACES HERE: the server hasn't been
* restarted before we release the flexnbd switch lock.
* do_serve doesn't return, so there's not a lot of
* choice about that.
*/
2012-06-21 18:01:50 +01:00
do_serve( listen->main_serve );
}
else {
warn("Failed to take control, giving up.");
server_destroy( listen->init_serve );
2012-06-27 15:45:33 +01:00
listen->init_serve = NULL;
2012-06-21 18:01:50 +01:00
}
2012-06-27 15:45:33 +01:00
/* TODO: here we must signal the control thread to stop before
* it tries to */
2012-06-21 18:01:50 +01:00
server_destroy( listen->main_serve );
2012-06-27 15:45:33 +01:00
listen->main_serve = NULL;
2012-06-21 18:01:50 +01:00
2012-06-27 15:45:33 +01:00
debug("Listen done, cleaning up");
2012-06-21 18:01:50 +01:00
listen_cleanup( listen );
2012-06-27 15:45:33 +01:00
return have_control;
2012-06-21 18:01:50 +01:00
}