Example #1
0
File: cd_srv.c Project: GoodOkk/tfs
static int csrv_thread_routine(void *data)
{
	struct socket *lsock = NULL;
	struct socket *con_sock = NULL;
	struct csrv_con *con = NULL;
	int error = 0;

	while (!kthread_should_stop()) {
		if (!csrv_sock) {
			error = ksock_listen(&lsock, INADDR_ANY, 9111, 5);
			if (error) {
				klog(KL_ERR, "csock_listen err=%d", error);
				msleep_interruptible(LISTEN_RESTART_TIMEOUT_MS);
				continue;
			} else {
				mutex_lock(&csrv_lock);
				csrv_sock = lsock;
				mutex_unlock(&csrv_lock);
			}
		}

		if (csrv_sock && !csrv_stopping) {
			klog(KL_DEBUG, "accepting");
			error = ksock_accept(&con_sock, csrv_sock);
			if (error) {
				if (error == -EAGAIN)
					klog(KL_WARN, "csock_accept err=%d", error);
				else
					klog(KL_ERR, "csock_accept err=%d", error);
				continue;
			}
			klog(KL_DEBUG, "accepted con_sock=%p", con_sock);

			if (!csrv_con_start(con_sock)) {
				klog(KL_ERR, "csrv_con_start failed");
				ksock_release(con_sock);
				continue;
			}
		}
	}

	error = 0;
	klog(KL_INFO, "releasing listen socket");
	
	mutex_lock(&csrv_lock);
	lsock = csrv_sock;
	csrv_sock = NULL;
	mutex_unlock(&csrv_lock);

	if (lsock)
		ksock_release(lsock);
	
	klog(KL_INFO, "releasing cons");

	for (;;) {
		con = NULL;
		mutex_lock(&con_list_lock);
		if (!list_empty(&con_list)) {
			con = list_first_entry(&con_list, struct csrv_con, con_list);
			list_del_init(&con->con_list);		
		}
		mutex_unlock(&con_list_lock);
		if (!con)
			break;

		csrv_con_wait(con);
		csrv_con_free(con);
	}
Example #2
0
/* This function accepts a connection from a client in the listener loop. */
static void kcd_frontend_loop_accept_conn(int *nb_child, int listen_sock) {
    int error = 0;
    int pid;
    struct sockaddr_in sock_addr;
    socklen_t sock_len;
    struct kcd_client *client = kcd_client_new();
    
    kmod_log_msg(KCD_LOG_MISC, "kcd_frontend_accept_conn() called.\n");
    
    do {
	/* Try to accept a connection. */
	error = ksock_accept(listen_sock, &client->sock);
	if (error == -2) { error = 0; break; }
	if (error) break;
	
	/* Get the client address. */
	sock_len = sizeof(sock_addr);
	error = getpeername(client->sock, (struct sockaddr *) &sock_addr, &sock_len);
	if (error) {
	    kmod_set_error("cannot get peer name: %s", strerror(errno));
	    break;
	}
	
	kstr_assign_cstr(&client->addr, inet_ntoa(sock_addr.sin_addr));
	client->port = ntohs(sock_addr.sin_port);
	
	/* Set the socket to non-blocking mode. */
	error = ksock_set_unblocking(client->sock);
	if (error) break;
        
        /* Enable keepalives. */
        error = ksock_enable_keepalive(client->sock, KCD_TCP_KEEPALIVE_TIME,
                                       KCD_TCP_KEEPALIVE_INTVl, KCD_TCP_KEEPALIVE_PROBES);
	if (error) break;
	
	/* We got the connection. Dispatch it. */
	kmod_log_msg(KCD_LOG_BRIEF, "Accepted connection from %s on port %u.\n", client->addr.data, client->port);
	
	/* Fork to handle the connection. */
        error = kcd_fork("Service ID", &pid, 1);
        if (error) break;
        
        /* Child. */
        else if (!pid) {
            kcd_frontend_handle_conn(client);
            exit(0);
        }
        
        /* Parent. */
        else {
            (*nb_child)++;
        }
	
    } while (0);
	    
    if (error) {
	kmod_log_msg(KCD_LOG_BRIEF, "Error accepting connection: %s.\n", kmod_strerror());
    }
	    
    kcd_client_destroy(client);
}