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 | |
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')
-rw-r--r-- | src/kernel/blk.c | 5 | ||||
-rw-r--r-- | src/kernel/core.c | 4 | ||||
-rw-r--r-- | src/kernel/dnbd3.h | 3 | ||||
-rw-r--r-- | src/kernel/net.c | 65 | ||||
-rw-r--r-- | src/kernel/net.h | 2 |
5 files changed, 65 insertions, 14 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c index c495205..fe66e1d 100644 --- a/src/kernel/blk.c +++ b/src/kernel/blk.c @@ -57,6 +57,8 @@ int dnbd3_blk_add_device(struct dnbd3_device *dev, int minor) queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue); dev->disk = disk; + dev->hb_request.cmd_type = REQ_TYPE_SPECIAL; + add_disk(disk); // must be last return 0; } @@ -69,6 +71,9 @@ int dnbd3_blk_del_device(struct dnbd3_device *dev) dev->sock = NULL; } + if (&dev->hb_timer) + del_timer(&dev->hb_timer); + del_gendisk(dev->disk); put_disk(dev->disk); blk_cleanup_queue(dev->disk->queue); diff --git a/src/kernel/core.c b/src/kernel/core.c index 1483704..3dc7ddf 100644 --- a/src/kernel/core.c +++ b/src/kernel/core.c @@ -27,13 +27,13 @@ struct dnbd3_device dnbd3_device[MAX_NUMBER_DEVICES]; static int __init dnbd3_init(void) { int i; - // initialize block device if ((major = register_blkdev(0, "dnbd3")) == 0) { printk("ERROR: dnbd3 register_blkdev failed.\n"); return -EIO; } + // add MAX_NUMBER_DEVICES devices for (i = 0; i < MAX_NUMBER_DEVICES; i++) { if (dnbd3_blk_add_device(&dnbd3_device[i], i) != 0) @@ -42,7 +42,6 @@ static int __init dnbd3_init(void) return -EIO; } } - printk("INFO: dnbd3 init successful.\n"); return 0; } @@ -54,7 +53,6 @@ static void __exit dnbd3_exit(void) { dnbd3_blk_del_device(&dnbd3_device[i]); } - unregister_blkdev(major, "dnbd3"); printk("INFO: dnbd3 exit.\n"); } diff --git a/src/kernel/dnbd3.h b/src/kernel/dnbd3.h index 5f45699..6f31c07 100644 --- a/src/kernel/dnbd3.h +++ b/src/kernel/dnbd3.h @@ -33,7 +33,6 @@ extern int major; struct dnbd3_device { - // block struct gendisk *disk; spinlock_t blk_lock; @@ -43,6 +42,8 @@ struct dnbd3_device char port[6]; char image_id[MAX_FILE_NAME]; struct socket *sock; + struct timer_list hb_timer; + struct request hb_request; // process struct task_struct *thread_send; 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); +} diff --git a/src/kernel/net.h b/src/kernel/net.h index 017a71e..66bc195 100644 --- a/src/kernel/net.h +++ b/src/kernel/net.h @@ -31,4 +31,6 @@ int dnbd3_net_send(void *data); int dnbd3_net_receive(void *data); +void dnbd3_net_heartbeat(unsigned long arg); + #endif /* NET_H_ */ |