X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=server.c;h=9c11b23cbb4801f15e08ae3c1a0a559322b38578;hp=66c93ab259d1c26e26a904c312cd45916407cb2a;hb=631fb4db2cea7bc44e91631957db8cd852fe75ee;hpb=b6e25b286c553ac1f971f3c8e0a736f9e731d2b7 diff --git a/server.c b/server.c index 66c93ab2..9c11b23c 100644 --- a/server.c +++ b/server.c @@ -108,8 +108,9 @@ pid_t afs_pid = 0; /** The task responsible for server command handling. */ struct server_command_task { - /** TCP port on which para_server listens for connections. */ - int listen_fd; + unsigned num_listen_fds; /* only one by default */ + /** TCP socket(s) on which para_server listens for connections. */ + int *listen_fds; /** Copied from para_server's main function. */ int argc; /** Argument vector passed to para_server's main function. */ @@ -346,20 +347,22 @@ static void init_signal_task(void) static void command_pre_select(struct sched *s, void *context) { + unsigned n; struct server_command_task *sct = context; - para_fd_set(sct->listen_fd, &s->rfds, &s->max_fileno); + + for (n = 0; n < sct->num_listen_fds; n++) + para_fd_set(sct->listen_fds[n], &s->rfds, &s->max_fileno); } -static int command_post_select(struct sched *s, void *context) +static int command_task_accept(unsigned listen_idx, fd_set *rfds, + struct server_command_task *sct) { - struct server_command_task *sct = context; - int new_fd, ret, i; char *peer_name; pid_t child_pid; uint32_t *chunk_table; - ret = para_accept(sct->listen_fd, &s->rfds, NULL, 0, &new_fd); + ret = para_accept(sct->listen_fds[listen_idx], rfds, NULL, 0, &new_fd); if (ret <= 0) goto out; mmd->num_connects++; @@ -410,23 +413,61 @@ out: return 0; } +static int command_post_select(struct sched *s, void *context) +{ + struct server_command_task *sct = context; + unsigned n; + int ret; + + for (n = 0; n < sct->num_listen_fds; n++) { + ret = command_task_accept(n, &s->rfds, sct); + if (ret < 0) { + free(sct->listen_fds); + return ret; + } + } + return 0; +} + static void init_server_command_task(int argc, char **argv) { int ret; static struct server_command_task server_command_task_struct, *sct = &server_command_task_struct; + unsigned n; + uint32_t port = OPT_UINT32_VAL(PORT); + PARA_NOTICE_LOG("initializing tcp command socket\n"); sct->argc = argc; sct->argv = argv; - ret = para_listen_simple(IPPROTO_TCP, OPT_UINT32_VAL(PORT)); - if (ret < 0) - goto err; - sct->listen_fd = ret; - ret = mark_fd_nonblocking(sct->listen_fd); - if (ret < 0) - goto err; - add_close_on_fork_list(sct->listen_fd); /* child doesn't need the listener */ + if (!OPT_GIVEN(LISTEN_ADDRESS)) { + sct->num_listen_fds = 1; + sct->listen_fds = para_malloc(sizeof(int)); + ret = para_listen_simple(IPPROTO_TCP, port); + if (ret < 0) + goto err; + sct->listen_fds[0] = ret; + } else { + sct->num_listen_fds = OPT_GIVEN(LISTEN_ADDRESS); + sct->listen_fds = para_malloc(sct->num_listen_fds * sizeof(int)); + for (n = 0; n < OPT_GIVEN(LISTEN_ADDRESS); n++) { + const char *arg; + arg = lls_string_val(n, OPT_RESULT(LISTEN_ADDRESS)); + ret = para_listen(IPPROTO_TCP, arg, port); + if (ret < 0) + goto err; + sct->listen_fds[n] = ret; + } + } + for (n = 0; n < sct->num_listen_fds; n++) { + ret = mark_fd_nonblocking(sct->listen_fds[n]); + if (ret < 0) + goto err; + /* child doesn't need the listener */ + add_close_on_fork_list(sct->listen_fds[n]); + } + sct->task = task_register(&(struct task_info) { .name = "server command", .pre_select = command_pre_select,