diff options
author | Johann Latocha | 2012-01-30 21:57:52 +0100 |
---|---|---|
committer | Johann Latocha | 2012-01-30 21:57:52 +0100 |
commit | 83c80e33b2ad1ecc37e5fb637c411fbb33371a81 (patch) | |
tree | 3c2cdb691e5febcb7340ada5d38465b3e6e56efe /src/kernel/net.c | |
parent | [SERVER] Some refactoring (diff) | |
download | dnbd3-83c80e33b2ad1ecc37e5fb637c411fbb33371a81.tar.gz dnbd3-83c80e33b2ad1ecc37e5fb637c411fbb33371a81.tar.xz dnbd3-83c80e33b2ad1ecc37e5fb637c411fbb33371a81.zip |
[SERVER] Timeout for client sockets
[KERNEL] Send keep alive
Diffstat (limited to 'src/kernel/net.c')
-rw-r--r-- | src/kernel/net.c | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/src/kernel/net.c b/src/kernel/net.c index c3f9782..de47ff7 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -35,7 +35,7 @@ void dnbd3_net_connect(struct dnbd3_device *lo) return; } - // FIXME: check if allready connected + // TODO: check if allready connected printk("INFO: Connecting device %s\n", lo->disk->disk_name); // initialize socket @@ -89,6 +89,13 @@ void dnbd3_net_connect(struct dnbd3_device *lo) // start receiving thread lo->thread_receive = kthread_create(dnbd3_net_receive, lo, lo->disk->disk_name); wake_up_process(lo->thread_receive); + + // Add heartbeat timer + init_timer(&lo->hb_timer); + lo->hb_timer.data = (unsigned long)lo; + lo->hb_timer.function = dnbd3_net_heartbeat; + lo->hb_timer.expires = jiffies + HB_INTERVAL; + add_timer(&lo->hb_timer); } void dnbd3_net_disconnect(struct dnbd3_device *lo) @@ -106,6 +113,9 @@ void dnbd3_net_disconnect(struct dnbd3_device *lo) sock_release(lo->sock); lo->sock = NULL; } + // clear heartbeat timer + if (&lo->hb_timer) + del_timer(&lo->hb_timer); // move already send requests to request_queue_send if (!list_empty(&lo->request_queue_receive)) @@ -151,10 +161,23 @@ int dnbd3_net_send(void *data) list_del_init(&blk_request->queuelist); spin_unlock_irq(&lo->blk_lock); - // prepare net request - dnbd3_request.cmd = CMD_GET_BLOCK; - dnbd3_request.offset = blk_rq_pos(blk_request) << 9; // *512 - dnbd3_request.size = blk_rq_bytes(blk_request); // blk_rq_bytes() Returns bytes left to complete in the entire request + switch (blk_request->cmd_type) + { + case REQ_TYPE_SPECIAL: + dnbd3_request.cmd = CMD_PING; + break; + + case REQ_TYPE_FS: + dnbd3_request.cmd = CMD_GET_BLOCK; + dnbd3_request.offset = blk_rq_pos(blk_request) << 9; // *512 + dnbd3_request.size = blk_rq_bytes(blk_request); // blk_rq_bytes() Returns bytes left to complete in the entire request + break; + + default: + printk("ERROR: Unknown command\n"); + break; + } + memcpy(dnbd3_request.handle, &blk_request, sizeof(blk_request)); iov.iov_base = &dnbd3_request; iov.iov_len = sizeof(dnbd3_request); @@ -220,8 +243,15 @@ int dnbd3_net_receive(void *data) } spin_unlock_irq(&lo->blk_lock); - // receive data and answer to block layer - rq_for_each_segment(bvec, blk_request, iter) + switch (dnbd3_reply.cmd) + { + case CMD_PING: + // TODO: use for rtt? + break; + + case CMD_GET_BLOCK: + // receive data and answer to block layer + rq_for_each_segment(bvec, blk_request, iter) { siginitsetinv(&blocked, sigmask(SIGKILL)); sigprocmask(SIG_SETMASK, &blocked, &oldset); @@ -235,10 +265,25 @@ int dnbd3_net_receive(void *data) sigprocmask(SIG_SETMASK, &oldset, NULL); } + spin_lock_irqsave(&lo->blk_lock, flags); + __blk_end_request_all(blk_request, 0); + spin_unlock_irqrestore(&lo->blk_lock, flags); + break; + + default: + printk("ERROR: Unknown command\n"); + break; + } - spin_lock_irqsave(&lo->blk_lock, flags); - __blk_end_request_all(blk_request, 0); - spin_unlock_irqrestore(&lo->blk_lock, flags); } return 0; } + +void dnbd3_net_heartbeat(unsigned long arg) +{ + struct dnbd3_device *lo = (struct dnbd3_device *) arg; + list_add(&lo->hb_request.queuelist, &lo->request_queue_send); + wake_up(&lo->process_queue_send); + lo->hb_timer.expires = jiffies + HB_INTERVAL; + add_timer(&lo->hb_timer); +} |