- } while (!list_empty(&zombies));
-}
-
-int
-kranal_listener(void *arg)
-{
- struct sockaddr_in addr;
- wait_queue_t wait;
- struct socket *sock;
- struct socket *newsock;
- int port;
- int backlog;
- int timeout;
- kra_connreq_t *connreqs;
- char name[16];
-
- /* Parent thread holds kra_nid_mutex, and is, or is about to
- * block on kra_listener_signal */
-
- port = kra_tunables.kra_port;
- snprintf(name, "kranal_lstn%03d", port);
- kportal_daemonize(name);
- kportal_blockallsigs();
-
- init_waitqueue_entry(&wait, current);
-
- rc = -ENOMEM;
- PORTAL_ALLOC(connreqs, 2 * sizeof(*connreqs));
- if (connreqs == NULL)
- goto out_0;
-
- rc = kranal_create_sock(&sock, port);
- if (rc != 0)
- goto out_1;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = INADDR_ANY
-
- rc = sock->ops->bind(sock, &addr, sizeof(addr));
- if (rc != 0) {
- CERROR("Can't bind to port %d\n", port);
- goto out_2;
- }
-
- rc = sock->ops->listen(sock, kra_tunalbes.kra_backlog);
- if (rc != 0) {
- CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
- goto out_2;
- }
-
- LASSERT (kranal_data.kra_listener_sock == NULL);
- kranal_data.kra_listener_sock = sock;
-
- /* unblock waiting parent */
- LASSERT (kranal_data.kra_listener_shutdown == 0);
- up(&kranal_data.kra_listener_signal);
-
- /* Wake me any time something happens on my socket */
- add_wait_queue(sock->sk->sk_sleep, &wait);
-
- while (kranal_data.kra_listener_shutdown == 0) {
-
- newsock = sock_alloc();
- if (newsock == NULL) {
- CERROR("Can't allocate new socket for accept\n");
- kranal_pause(HZ);
- continue;
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
-
- if (rc == -EAGAIN &&
- kranal_data.kra_listener_shutdown == 0)
- schedule();
-
- set_current_state(TASK_RUNNING);
-
- if (rc != 0) {
- sock_release(newsock);
- if (rc != -EAGAIN) {
- CERROR("Accept failed: %d\n", rc);
- kranal_pause(HZ);
- }
- continue;
- }
-
- kranal_conn_handshake(newsock, NULL);
- sock_release(newsock);
- }
-
- rc = 0;
- remove_wait_queue(sock->sk->sk_sleep, &wait);
- out_2:
- sock_release(sock);
- kranal_data.kra_listener_sock = NULL;
- out_1:
- PORTAL_FREE(connreqs, 2 * sizeof(*connreqs));
- out_0:
- /* set completion status and unblock thread waiting for me
- * (parent on startup failure, executioner on normal shutdown) */
- kranal_data.kra_listener_shutdown = rc;
- up(&kranal_data.kra_listener_signal);
-
- return 0;
-}
-
-int
-kranal_start_listener ()
-{
- long pid;
- int rc;
-
- CDEBUG(D_WARNING, "Starting listener\n");
-
- /* Called holding kra_nid_mutex: listener stopped */
- LASSERT (kranal_data.kra_listener_sock == NULL);
-
- kranal_data.kra_listener_shutdown == 0;
- pid = kernel_thread(kranal_listener, sock, 0);
- if (pid < 0) {
- CERROR("Can't spawn listener: %ld\n", pid);
- return (int)pid;
- }
-
- /* Block until listener has started up. */
- down(&kranal_data.kra_listener_signal);
-
- rc = kranal_data.kra_listener_shutdown;
- LASSERT ((rc != 0) == (kranal_data.kra_listener_sock == NULL));
-
- CDEBUG(D_WARNING, "Listener %ld started OK\n", pid);
- return rc;