From 1dc88febdcb2a1d09dfca592bb47106512526b29 Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Mon, 30 Jan 2012 22:15:44 +0100 Subject: [ALL] Reformat (line wrapping, indent) --- src/client/client.c | 212 ++++++++++----------- src/kernel/blk.c | 209 +++++++++++---------- src/kernel/blk.h | 3 +- src/kernel/core.c | 50 ++--- src/kernel/dnbd3.h | 38 ++-- src/kernel/net.c | 494 ++++++++++++++++++++++++------------------------- src/kernel/utils.c | 16 +- src/server/hashtable.c | 46 ++--- src/server/hashtable.h | 2 +- src/server/server.c | 407 ++++++++++++++++++++-------------------- src/server/utils.c | 123 ++++++------ src/types.h | 16 +- 12 files changed, 807 insertions(+), 809 deletions(-) (limited to 'src') diff --git a/src/client/client.c b/src/client/client.c index 814c5d0..c51ff86 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -31,117 +31,119 @@ void print_help(char* argv_0) { - printf("Usage: %s -H -p -i -d || -c -d \n", argv_0); - printf("Start the DNBD3 client.\n"); - printf("-H or --host \t\t Host running dnbd3-server.\n"); - printf("-p or --port \t\t Port used by server.\n"); - printf("-i or --image \t\t Exported image ID.\n"); - printf("-d or --device \t\t DNBD3 device name.\n"); - printf("-c or --changehost \t Change dnbd3-server on device (DEBUG).\n"); - printf("-h or --help \t\t Show this help text and quit.\n"); - printf("-v or --version \t Show version and quit.\n"); - exit(EXIT_SUCCESS); + printf("Usage: %s -H -p -i -d \n", argv_0); + printf("Start the DNBD3 client.\n"); + printf("-H or --host \t\t Host running dnbd3-server.\n"); + printf("-p or --port \t\t Port used by server.\n"); + printf("-i or --image \t\t Exported image ID.\n"); + printf("-d or --device \t\t DNBD3 device name.\n"); + printf("-c or --changehost \t Change dnbd3-server on device (DEBUG).\n"); + printf("-h or --help \t\t Show this help text and quit.\n"); + printf("-v or --version \t Show version and quit.\n"); + exit(EXIT_SUCCESS); } void print_version() { - printf("Version: %s\n", VERSION_STRING); - exit(EXIT_SUCCESS); + printf("Version: %s\n", VERSION_STRING); + exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) { - int fd; - char *host = NULL; - char *port = NULL; - char *image_id = NULL; - char *dev = NULL; - int change_host = 0; - - int opt = 0; - int longIndex = 0; - static const char *optString = "H:p:i:d:c:hv?"; - static const struct option longOpts[] = - { - { "host", required_argument, NULL, 'H' }, - { "port", required_argument, NULL, 'p' }, - { "image", required_argument, NULL, 'i' }, - { "device", required_argument, NULL, 'd' }, - { "changehost", required_argument, NULL, 'c' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'v' }, }; - - opt = getopt_long(argc, argv, optString, longOpts, &longIndex); - - while (opt != -1) - { - switch (opt) - { - case 'H': - host = optarg; - break; - case 'p': - port = optarg; - break; - case 'i': - image_id = optarg; - break; - case 'd': - dev = optarg; - break; - case 'c': - host = optarg; - change_host = 1; - break; - case 'h': - print_help(argv[0]); - break; - case 'v': - print_version(); - break; - case '?': - print_help(argv[0]); - } - opt = getopt_long(argc, argv, optString, longOpts, &longIndex); - } - - if (change_host && host && dev && !port && !image_id) - { - fd = open(dev, O_RDONLY); - - if (ioctl(fd, IOCTL_DISCONNECT) < 0) - printf("ERROR: ioctl not successful\n"); - - if (ioctl(fd, IOCTL_SET_HOST, host) < 0) - printf("ERROR: ioctl not successful\n"); - - if (ioctl(fd, IOCTL_CONNECT) < 0) - printf("ERROR: ioctl not successful\n"); - - close(fd); - exit(EXIT_SUCCESS); - } - - if (host && port && dev && image_id) - { - fd = open(dev, O_RDONLY); - - if (ioctl(fd, IOCTL_SET_HOST, host) < 0) - printf("ERROR: ioctl not successful\n"); - - if (ioctl(fd, IOCTL_SET_PORT, port) < 0) - printf("ERROR: ioctl not successful\n"); - - if (ioctl(fd, IOCTL_SET_IMAGE, image_id) < 0) - printf("ERROR: ioctl not successful\n"); - - if (ioctl(fd, IOCTL_CONNECT) < 0) - printf("ERROR: ioctl not successful\n"); - - close(fd); - exit(EXIT_SUCCESS); - } - - print_help(argv[0]); - exit(EXIT_FAILURE); + int fd; + char *host = NULL; + char *port = NULL; + char *image_id = NULL; + char *dev = NULL; + int change_host = 0; + + int opt = 0; + int longIndex = 0; + static const char *optString = "H:p:i:d:c:hv?"; + static const struct option longOpts[] = + { + { "host", required_argument, NULL, 'H' }, + { "port", required_argument, NULL, 'p' }, + { "image", required_argument, NULL, 'i' }, + { "device", required_argument, NULL, 'd' }, + { "changehost", required_argument, NULL, 'c' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, }; + + opt = getopt_long(argc, argv, optString, longOpts, &longIndex); + + while (opt != -1) + { + switch (opt) + { + case 'H': + host = optarg; + break; + case 'p': + port = optarg; + break; + case 'i': + image_id = optarg; + break; + case 'd': + dev = optarg; + break; + case 'c': + host = optarg; + change_host = 1; + break; + case 'h': + print_help(argv[0]); + break; + case 'v': + print_version(); + break; + case '?': + print_help(argv[0]); + } + opt = getopt_long(argc, argv, optString, longOpts, &longIndex); + } + + // change host + if (change_host && host && dev && !port && !image_id) + { + fd = open(dev, O_RDONLY); + + if (ioctl(fd, IOCTL_DISCONNECT) < 0) + printf("ERROR: ioctl not successful\n"); + + if (ioctl(fd, IOCTL_SET_HOST, host) < 0) + printf("ERROR: ioctl not successful\n"); + + if (ioctl(fd, IOCTL_CONNECT) < 0) + printf("ERROR: ioctl not successful\n"); + + close(fd); + exit(EXIT_SUCCESS); + } + + // connect + if (host && port && dev && image_id) + { + fd = open(dev, O_RDONLY); + + if (ioctl(fd, IOCTL_SET_HOST, host) < 0) + printf("ERROR: ioctl not successful\n"); + + if (ioctl(fd, IOCTL_SET_PORT, port) < 0) + printf("ERROR: ioctl not successful\n"); + + if (ioctl(fd, IOCTL_SET_IMAGE, image_id) < 0) + printf("ERROR: ioctl not successful\n"); + + if (ioctl(fd, IOCTL_CONNECT) < 0) + printf("ERROR: ioctl not successful\n"); + + close(fd); + exit(EXIT_SUCCESS); + } + + print_help(argv[0]); + exit(EXIT_FAILURE); } diff --git a/src/kernel/blk.c b/src/kernel/blk.c index fe66e1d..7a61ba3 100644 --- a/src/kernel/blk.c +++ b/src/kernel/blk.c @@ -23,123 +23,122 @@ int dnbd3_blk_add_device(struct dnbd3_device *dev, int minor) { - struct gendisk *disk; - struct request_queue *blk_queue; - - init_waitqueue_head(&dev->process_queue_send); - init_waitqueue_head(&dev->process_queue_receive); - INIT_LIST_HEAD(&dev->request_queue_send); - INIT_LIST_HEAD(&dev->request_queue_receive); - - if (!(disk = alloc_disk(1))) - { - printk("ERROR: dnbd3 alloc_disk failed.\n"); - return -EIO; - } - - disk->major = major; - disk->first_minor = minor; - sprintf(disk->disk_name, "dnbd%d", minor); - set_capacity(disk, 0); - set_disk_ro(disk, 1); - disk->fops = &dnbd3_blk_ops; - - spin_lock_init(&dev->blk_lock); - if ((blk_queue = blk_init_queue(&dnbd3_blk_request, &dev->blk_lock)) == NULL) - { - printk("ERROR: dnbd3 blk_init_queue failed.\n"); - return -EIO; - } - - blk_queue_logical_block_size(blk_queue, DNBD3_BLOCK_SIZE); - disk->queue = blk_queue; - disk->private_data = dev; - 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; + struct gendisk *disk; + struct request_queue *blk_queue; + + init_waitqueue_head(&dev->process_queue_send); + init_waitqueue_head(&dev->process_queue_receive); + INIT_LIST_HEAD(&dev->request_queue_send); + INIT_LIST_HEAD(&dev->request_queue_receive); + + if (!(disk = alloc_disk(1))) + { + printk("ERROR: dnbd3 alloc_disk failed.\n"); + return -EIO; + } + + disk->major = major; + disk->first_minor = minor; + sprintf(disk->disk_name, "dnbd%d", minor); + set_capacity(disk, 0); + set_disk_ro(disk, 1); + disk->fops = &dnbd3_blk_ops; + + spin_lock_init(&dev->blk_lock); + if ((blk_queue = blk_init_queue(&dnbd3_blk_request, &dev->blk_lock)) == NULL) + { + printk("ERROR: dnbd3 blk_init_queue failed.\n"); + return -EIO; + } + + blk_queue_logical_block_size(blk_queue, DNBD3_BLOCK_SIZE); + disk->queue = blk_queue; + disk->private_data = dev; + 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; } int dnbd3_blk_del_device(struct dnbd3_device *dev) { - if (dev->sock) - { - sock_release(dev->sock); - 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); - return 0; + if (dev->sock) + { + sock_release(dev->sock); + 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); + return 0; } struct block_device_operations dnbd3_blk_ops = { .owner = THIS_MODULE, .ioctl = dnbd3_blk_ioctl, }; -int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, - unsigned long arg) +int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct dnbd3_device *lo = bdev->bd_disk->private_data; - - switch (cmd) - { - case IOCTL_SET_HOST: - strcpy(lo->host, (char *) arg); - break; - - case IOCTL_SET_PORT: - strcpy(lo->port, (char *) arg); - break; - case IOCTL_SET_IMAGE: - strcpy(lo->image_id, (char *) arg); - break; - case IOCTL_CONNECT: - if (lo->host && lo->port && lo->image_id) - dnbd3_net_connect(lo); - else - return -1; - break; - case IOCTL_DISCONNECT: - dnbd3_net_disconnect(lo); - break; - case BLKFLSBUF: - break; - - default: - return -1; - - } - return 0; + struct dnbd3_device *lo = bdev->bd_disk->private_data; + + switch (cmd) + { + case IOCTL_SET_HOST: + strcpy(lo->host, (char *) arg); + break; + + case IOCTL_SET_PORT: + strcpy(lo->port, (char *) arg); + break; + case IOCTL_SET_IMAGE: + strcpy(lo->image_id, (char *) arg); + break; + case IOCTL_CONNECT: + if (lo->host && lo->port && lo->image_id) + dnbd3_net_connect(lo); + else + return -1; + break; + case IOCTL_DISCONNECT: + dnbd3_net_disconnect(lo); + break; + case BLKFLSBUF: + break; + + default: + return -1; + + } + return 0; } void dnbd3_blk_request(struct request_queue *q) { - struct request *req; - struct dnbd3_device *lo; - - while ((req = blk_fetch_request(q)) != NULL) - { - lo = req->rq_disk->private_data; - - if (req->cmd_type != REQ_TYPE_FS) - { - __blk_end_request_all(req, 0); - continue; - } - - if (rq_data_dir(req) == READ) - { - list_add_tail(&req->queuelist, &lo->request_queue_send); - spin_unlock_irq(q->queue_lock); - wake_up(&lo->process_queue_send); - spin_lock_irq(q->queue_lock); - } - } + struct request *req; + struct dnbd3_device *lo; + + while ((req = blk_fetch_request(q)) != NULL) + { + lo = req->rq_disk->private_data; + + if (req->cmd_type != REQ_TYPE_FS) + { + __blk_end_request_all(req, 0); + continue; + } + + if (rq_data_dir(req) == READ) + { + list_add_tail(&req->queuelist, &lo->request_queue_send); + spin_unlock_irq(q->queue_lock); + wake_up(&lo->process_queue_send); + spin_lock_irq(q->queue_lock); + } + } } diff --git a/src/kernel/blk.h b/src/kernel/blk.h index 3092b22..039d991 100644 --- a/src/kernel/blk.h +++ b/src/kernel/blk.h @@ -25,8 +25,7 @@ extern struct block_device_operations dnbd3_blk_ops; -int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, - unsigned long arg); +int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); void dnbd3_blk_request(struct request_queue *q); diff --git a/src/kernel/core.c b/src/kernel/core.c index 3dc7ddf..6b50aaa 100644 --- a/src/kernel/core.c +++ b/src/kernel/core.c @@ -26,35 +26,35 @@ 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) - { - printk("ERROR: adding device failed.\n"); - return -EIO; - } - } - printk("INFO: dnbd3 init successful.\n"); - return 0; + 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) + { + printk("ERROR: adding device failed.\n"); + return -EIO; + } + } + printk("INFO: dnbd3 init successful.\n"); + return 0; } static void __exit dnbd3_exit(void) { - int i; - for (i = 0; i < MAX_NUMBER_DEVICES; i++) - { - dnbd3_blk_del_device(&dnbd3_device[i]); - } - unregister_blkdev(major, "dnbd3"); - printk("INFO: dnbd3 exit.\n"); + int i; + for (i = 0; i < MAX_NUMBER_DEVICES; i++) + { + dnbd3_blk_del_device(&dnbd3_device[i]); + } + unregister_blkdev(major, "dnbd3"); + printk("INFO: dnbd3 exit.\n"); } module_init( dnbd3_init); diff --git a/src/kernel/dnbd3.h b/src/kernel/dnbd3.h index 6f31c07..ec9dd6e 100644 --- a/src/kernel/dnbd3.h +++ b/src/kernel/dnbd3.h @@ -33,25 +33,25 @@ extern int major; struct dnbd3_device { - // block - struct gendisk *disk; - spinlock_t blk_lock; - - // network - char host[16]; - 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; - struct task_struct *thread_receive; - wait_queue_head_t process_queue_send; - wait_queue_head_t process_queue_receive; - struct list_head request_queue_send; - struct list_head request_queue_receive; + // block + struct gendisk *disk; + spinlock_t blk_lock; + + // network + char host[16]; + 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; + struct task_struct *thread_receive; + wait_queue_head_t process_queue_send; + wait_queue_head_t process_queue_receive; + struct list_head request_queue_send; + struct list_head request_queue_receive; }; diff --git a/src/kernel/net.c b/src/kernel/net.c index de47ff7..8f3227a 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -23,267 +23,267 @@ void dnbd3_net_connect(struct dnbd3_device *lo) { - struct sockaddr_in sin; - struct msghdr msg; - struct kvec iov; - struct dnbd3_request dnbd3_request; - struct dnbd3_reply dnbd3_reply; - - if (!lo->host || !lo->port || !lo->image_id) - { - printk("ERROR: Host or port not set."); - return; - } - - // TODO: check if allready connected - printk("INFO: Connecting device %s\n", lo->disk->disk_name); - - // initialize socket - if (sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &lo->sock) < 0) - { - printk("ERROR: dnbd3 couldn't create socket.\n"); - return; - } - lo->sock->sk->sk_allocation = GFP_NOIO; - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = inet_addr(lo->host); - sin.sin_port = htons(simple_strtol(lo->port, NULL, 10)); - if (kernel_connect(lo->sock, (struct sockaddr *) &sin, sizeof(sin), 0) < 0) - { - printk("ERROR: dnbd3 couldn't connect to host %s:%s\n", lo->host, lo->port); - return; - } - - // prepare message and send request - dnbd3_request.cmd = CMD_GET_SIZE; - strcpy(dnbd3_request.image_id, lo->image_id); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; // No SIGPIPE - - iov.iov_base = &dnbd3_request; - iov.iov_len = sizeof(dnbd3_request); - kernel_sendmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_request)); - - // receive replay - iov.iov_base = &dnbd3_reply; - iov.iov_len = sizeof(dnbd3_reply); - kernel_recvmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_reply), msg.msg_flags); - - // set filesize - if (dnbd3_reply.filesize <= 0) - { - printk("ERROR: File size returned by server is < 0.\n"); - return; - } - - printk("INFO: dnbd3 filesize: %llu\n", dnbd3_reply.filesize); - set_capacity(lo->disk, dnbd3_reply.filesize >> 9); /* 512 Byte blocks */ - - // start sending thread - lo->thread_send = kthread_create(dnbd3_net_send, lo, lo->disk->disk_name); - wake_up_process(lo->thread_send); - - // 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); + struct sockaddr_in sin; + struct msghdr msg; + struct kvec iov; + struct dnbd3_request dnbd3_request; + struct dnbd3_reply dnbd3_reply; + + if (!lo->host || !lo->port || !lo->image_id) + { + printk("ERROR: Host or port not set."); + return; + } + + // TODO: check if allready connected + printk("INFO: Connecting device %s\n", lo->disk->disk_name); + + // initialize socket + if (sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &lo->sock) < 0) + { + printk("ERROR: dnbd3 couldn't create socket.\n"); + return; + } + lo->sock->sk->sk_allocation = GFP_NOIO; + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(lo->host); + sin.sin_port = htons(simple_strtol(lo->port, NULL, 10)); + if (kernel_connect(lo->sock, (struct sockaddr *) &sin, sizeof(sin), 0) < 0) + { + printk("ERROR: dnbd3 couldn't connect to host %s:%s\n", lo->host, lo->port); + return; + } + + // prepare message and send request + dnbd3_request.cmd = CMD_GET_SIZE; + strcpy(dnbd3_request.image_id, lo->image_id); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; // No SIGPIPE + + iov.iov_base = &dnbd3_request; + iov.iov_len = sizeof(dnbd3_request); + kernel_sendmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_request)); + + // receive replay + iov.iov_base = &dnbd3_reply; + iov.iov_len = sizeof(dnbd3_reply); + kernel_recvmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_reply), msg.msg_flags); + + // set filesize + if (dnbd3_reply.filesize <= 0) + { + printk("ERROR: File size returned by server is < 0.\n"); + return; + } + + printk("INFO: dnbd3 filesize: %llu\n", dnbd3_reply.filesize); + set_capacity(lo->disk, dnbd3_reply.filesize >> 9); /* 512 Byte blocks */ + + // start sending thread + lo->thread_send = kthread_create(dnbd3_net_send, lo, lo->disk->disk_name); + wake_up_process(lo->thread_send); + + // 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) { - struct request *blk_request, *tmp_request; - printk("INFO: Disconnecting device %s\n", lo->disk->disk_name); - - // kill sending and receiving threads - kthread_stop(lo->thread_send); - kthread_stop(lo->thread_receive); - - // clear sock - if (lo->sock) - { - 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)) - { - printk("WARN: Request queue was not empty on %s\n", lo->disk->disk_name); - spin_lock_irq(&lo->blk_lock); - list_for_each_entry_safe(blk_request, tmp_request, &lo->request_queue_receive, queuelist) - { - list_del_init(&blk_request->queuelist); - list_add_tail(&blk_request->queuelist, &lo->request_queue_send); - } - spin_unlock_irq(&lo->blk_lock); - } + struct request *blk_request, *tmp_request; + printk("INFO: Disconnecting device %s\n", lo->disk->disk_name); + + // kill sending and receiving threads + kthread_stop(lo->thread_send); + kthread_stop(lo->thread_receive); + + // clear sock + if (lo->sock) + { + 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)) + { + printk("WARN: Request queue was not empty on %s\n", lo->disk->disk_name); + spin_lock_irq(&lo->blk_lock); + list_for_each_entry_safe(blk_request, tmp_request, &lo->request_queue_receive, queuelist) + { + list_del_init(&blk_request->queuelist); + list_add_tail(&blk_request->queuelist, &lo->request_queue_send); + } + spin_unlock_irq(&lo->blk_lock); + } } int dnbd3_net_send(void *data) { - struct dnbd3_device *lo = data; - struct dnbd3_request dnbd3_request; - struct request *blk_request; - struct msghdr msg; - struct kvec iov; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; // No SIGPIPE - - set_user_nice(current, -20); - - while (!kthread_should_stop() || !list_empty(&lo->request_queue_send)) - { - wait_event_interruptible(lo->process_queue_send, - kthread_should_stop() || !list_empty(&lo->request_queue_send)); - - if (list_empty(&lo->request_queue_send)) - continue; - - // extract block request - spin_lock_irq(&lo->blk_lock); - blk_request = list_entry(lo->request_queue_send.next, struct request, queuelist); - list_del_init(&blk_request->queuelist); - spin_unlock_irq(&lo->blk_lock); - - 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); - - // send net request - if (kernel_sendmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_request)) <= 0) - printk("ERROR: kernel_sendmsg\n"); - - spin_lock_irq(&lo->blk_lock); - list_add_tail(&blk_request->queuelist, &lo->request_queue_receive); - spin_unlock_irq(&lo->blk_lock); - wake_up(&lo->process_queue_receive); - } - return 0; + struct dnbd3_device *lo = data; + struct dnbd3_request dnbd3_request; + struct request *blk_request; + struct msghdr msg; + struct kvec iov; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; // No SIGPIPE + + set_user_nice(current, -20); + + while (!kthread_should_stop() || !list_empty(&lo->request_queue_send)) + { + wait_event_interruptible(lo->process_queue_send, + kthread_should_stop() || !list_empty(&lo->request_queue_send)); + + if (list_empty(&lo->request_queue_send)) + continue; + + // extract block request + spin_lock_irq(&lo->blk_lock); + blk_request = list_entry(lo->request_queue_send.next, struct request, queuelist); + list_del_init(&blk_request->queuelist); + spin_unlock_irq(&lo->blk_lock); + + 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); // bytes left to complete 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); + + // send net request + if (kernel_sendmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_request)) <= 0) + printk("ERROR: kernel_sendmsg\n"); + + spin_lock_irq(&lo->blk_lock); + list_add_tail(&blk_request->queuelist, &lo->request_queue_receive); + spin_unlock_irq(&lo->blk_lock); + wake_up(&lo->process_queue_receive); + } + return 0; } int dnbd3_net_receive(void *data) { - struct dnbd3_device *lo = data; - struct dnbd3_reply dnbd3_reply; - struct request *blk_request; - struct msghdr msg; - struct kvec iov; - struct req_iterator iter; - struct bio_vec *bvec; - unsigned long flags; - sigset_t blocked, oldset; - struct request *tmp_request, *received_request; - void *kaddr; - unsigned int size; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; // No SIGPIPE - - set_user_nice(current, -20); - - while (!kthread_should_stop() || !list_empty(&lo->request_queue_receive)) - { - wait_event_interruptible(lo->process_queue_receive, kthread_should_stop() || !list_empty(&lo->request_queue_receive)); - - if (list_empty(&lo->request_queue_receive)) - continue; - - // receive net replay - iov.iov_base = &dnbd3_reply; - iov.iov_len = sizeof(dnbd3_reply); - kernel_recvmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_reply), - msg.msg_flags); - - // search for replied request in queue - received_request = *(struct request **) dnbd3_reply.handle; - spin_lock_irq(&lo->blk_lock); - list_for_each_entry_safe(blk_request, tmp_request, &lo->request_queue_receive, queuelist) - { - if (blk_request != received_request) - continue; - - list_del_init(&blk_request->queuelist); - break; - } - spin_unlock_irq(&lo->blk_lock); - - 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); - - kaddr = kmap(bvec->bv_page) + bvec->bv_offset; - size = bvec->bv_len; - iov.iov_base = kaddr; - iov.iov_len = size; - kernel_recvmsg(lo->sock, &msg, &iov, 1, size, msg.msg_flags); - kunmap(bvec->bv_page); - - 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; - } - - } - return 0; + struct dnbd3_device *lo = data; + struct dnbd3_reply dnbd3_reply; + struct request *blk_request; + struct msghdr msg; + struct kvec iov; + struct req_iterator iter; + struct bio_vec *bvec; + unsigned long flags; + sigset_t blocked, oldset; + struct request *tmp_request, *received_request; + void *kaddr; + unsigned int size; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; // No SIGPIPE + + set_user_nice(current, -20); + + while (!kthread_should_stop() || !list_empty(&lo->request_queue_receive)) + { + wait_event_interruptible(lo->process_queue_receive, + kthread_should_stop() || !list_empty(&lo->request_queue_receive)); + + if (list_empty(&lo->request_queue_receive)) + continue; + + // receive net replay + iov.iov_base = &dnbd3_reply; + iov.iov_len = sizeof(dnbd3_reply); + kernel_recvmsg(lo->sock, &msg, &iov, 1, sizeof(dnbd3_reply), msg.msg_flags); + + // search for replied request in queue + received_request = *(struct request **) dnbd3_reply.handle; + spin_lock_irq(&lo->blk_lock); + list_for_each_entry_safe(blk_request, tmp_request, &lo->request_queue_receive, queuelist) + { + if (blk_request != received_request) + continue; + + list_del_init(&blk_request->queuelist); + break; + } + spin_unlock_irq(&lo->blk_lock); + + 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); + + kaddr = kmap(bvec->bv_page) + bvec->bv_offset; + size = bvec->bv_len; + iov.iov_base = kaddr; + iov.iov_len = size; + kernel_recvmsg(lo->sock, &msg, &iov, 1, size, msg.msg_flags); + kunmap(bvec->bv_page); + + 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; + } + + } + 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); + 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/utils.c b/src/kernel/utils.c index 423ceb9..85c0ce0 100644 --- a/src/kernel/utils.c +++ b/src/kernel/utils.c @@ -22,12 +22,12 @@ unsigned int inet_addr(char *str) { - int a, b, c, d; - char arr[4]; - sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d); - arr[0] = a; - arr[1] = b; - arr[2] = c; - arr[3] = d; - return *(unsigned int*) arr; + int a, b, c, d; + char arr[4]; + sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d); + arr[0] = a; + arr[1] = b; + arr[2] = c; + arr[3] = d; + return *(unsigned int*) arr; } diff --git a/src/server/hashtable.c b/src/server/hashtable.c index 423e7d2..a9fb63c 100644 --- a/src/server/hashtable.c +++ b/src/server/hashtable.c @@ -32,45 +32,47 @@ char *val_ptr = value_buf; void dnbd3_ht_create() { - (void) hcreate(MAX_NUMBER_IMAGES); + (void) hcreate(MAX_NUMBER_IMAGES); } void dnbd3_ht_destroy() { - key_ptr = key_buf; - val_ptr = value_buf; - hdestroy(); + key_ptr = key_buf; + val_ptr = value_buf; + hdestroy(); } int dnbd3_ht_insert(char* key, char* value) { - if (strlen(key) > MAX_FILE_ID) return -1; - if (strlen(value) > MAX_FILE_NAME) return -2; + if (strlen(key) > MAX_FILE_ID) + return -1; + if (strlen(value) > MAX_FILE_NAME) + return -2; - strcpy(key_ptr, key); - strcpy(val_ptr, value); + strcpy(key_ptr, key); + strcpy(val_ptr, value); - ENTRY item; - item.key = key_ptr; - item.data = val_ptr; + ENTRY item; + item.key = key_ptr; + item.data = val_ptr; - (void) hsearch(item, ENTER); + (void) hsearch(item, ENTER); - key_ptr += strlen(key) + 1; - val_ptr += strlen(value) + 1; + key_ptr += strlen(key) + 1; + val_ptr += strlen(value) + 1; - return 0; + return 0; } char* dnbd3_ht_search(char* key) { - ENTRY *result; + ENTRY *result; - ENTRY item; - item.key = key; + ENTRY item; + item.key = key; - if ((result = hsearch(item, FIND)) != NULL) - return result->data; - else - return NULL; + if ((result = hsearch(item, FIND)) != NULL) + return result->data; + else + return NULL; } diff --git a/src/server/hashtable.h b/src/server/hashtable.h index 2483bbe..3c16dff 100644 --- a/src/server/hashtable.h +++ b/src/server/hashtable.h @@ -21,7 +21,7 @@ #ifndef HASHTABLE_H_ #define HASHTABLE_H_ -void dnbd3_ht_create (); +void dnbd3_ht_create(); void dnbd3_ht_destroy(); diff --git a/src/server/server.c b/src/server/server.c index ffeb0af..0b327e3 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -48,237 +48,234 @@ char *config_file_name = DEFAULT_CONFIG_FILE; void print_help(char* argv_0) { - - printf("Usage: %s [OPTIONS]...\n", argv_0); - printf("Start the DNBD3 server\n"); - printf("-f or --file \t\t Configuration file (default /etc/dnbd3-server.conf)\n"); - printf("-n or --nodaemon \t\t Start server in foreground\n"); - printf("-r or --reload \t\t Reload configuration file\n"); - printf("-s or --stop \t\t Stop running dnbd3-server\n"); - printf("-h or --help \t\t Show this help text and quit\n"); - printf("-v or --version \t Show version and quit\n"); - exit(0); + printf("Usage: %s [OPTIONS]...\n", argv_0); + printf("Start the DNBD3 server\n"); + printf("-f or --file \t\t Configuration file (default /etc/dnbd3-server.conf)\n"); + printf("-n or --nodaemon \t\t Start server in foreground\n"); + printf("-r or --reload \t\t Reload configuration file\n"); + printf("-s or --stop \t\t Stop running dnbd3-server\n"); + printf("-h or --help \t\t Show this help text and quit\n"); + printf("-v or --version \t Show version and quit\n"); + exit(0); } void print_version() { - printf("Version: %s\n", VERSION_STRING); - exit(0); + printf("Version: %s\n", VERSION_STRING); + exit(0); } void cleanup() { - close(_sock); - dnbd3_delete_pid_file(); - exit(EXIT_SUCCESS); + close(_sock); + dnbd3_delete_pid_file(); + exit(EXIT_SUCCESS); } void handle_sigpipe(int signum) { - printf("ERROR: Received signal SIGPIPE, Broken pipe (errno: %i)\n", errno); - return; + printf("ERROR: Received signal SIGPIPE, Broken pipe (errno: %i)\n", errno); + return; } void handle_sighup(int signum) { - printf("INFO: SIGHUP received!\n"); - printf("INFO: Reloading configuration...\n"); - pthread_spin_lock(&spinlock); - dnbd3_reload_config(config_file_name); - pthread_spin_unlock(&spinlock); + printf("INFO: SIGHUP received!\n"); + printf("INFO: Reloading configuration...\n"); + pthread_spin_lock(&spinlock); + dnbd3_reload_config(config_file_name); + pthread_spin_unlock(&spinlock); } void handle_sigterm(int signum) { - printf("INFO: SIGTERM or SIGINT received!\n"); - cleanup(); + printf("INFO: SIGTERM or SIGINT received!\n"); + cleanup(); } void *handle_query(void *client_socket) { - int image_file = -1; - off_t filesize = 0; - int sock = (int)(uintptr_t) client_socket; - struct dnbd3_request request; - struct dnbd3_reply reply; - uint16_t cmd; - - while (recv(sock, &request, sizeof(struct dnbd3_request), MSG_WAITALL) > 0) - { - cmd = request.cmd; - switch (cmd) - { - case CMD_PING: - reply.cmd = request.cmd; - memcpy(reply.handle, request.handle, sizeof(request.handle)); - send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0); - break; - - case CMD_GET_SIZE: - pthread_spin_lock(&spinlock); // because of reloading config - image_file = open(dnbd3_ht_search(request.image_id), O_RDONLY); - pthread_spin_unlock(&spinlock); - if (image_file < 0) - { - printf("ERROR: Client requested an unknown image id.\n"); - filesize = 0; - } - else - { - struct stat st; - fstat(image_file, &st); - filesize = st.st_size; - } - - reply.cmd = request.cmd; - reply.filesize = filesize; - send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0); - break; - - case CMD_GET_BLOCK: - if (image_file < 0) - break; - - reply.cmd = request.cmd; - memcpy(reply.handle, request.handle, sizeof(request.handle)); - send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0); - - if (sendfile(sock, image_file, (off_t *) &request.offset, - request.size) < 0) - printf("ERROR: sendfile returned -1\n"); - - break; - - default: - printf("ERROR: Unknown command\n"); - break; - } - - } - close(sock); - printf("INFO: Client exit.\n"); - pthread_exit((void *) 0); + int image_file = -1; + off_t filesize = 0; + int sock = (int) (uintptr_t) client_socket; + struct dnbd3_request request; + struct dnbd3_reply reply; + uint16_t cmd; + + while (recv(sock, &request, sizeof(struct dnbd3_request), MSG_WAITALL) > 0) + { + cmd = request.cmd; + switch (cmd) + { + case CMD_PING: + reply.cmd = request.cmd; + memcpy(reply.handle, request.handle, sizeof(request.handle)); + send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0); + break; + + case CMD_GET_SIZE: + pthread_spin_lock(&spinlock); // because of reloading config + image_file = open(dnbd3_ht_search(request.image_id), O_RDONLY); + pthread_spin_unlock(&spinlock); + if (image_file < 0) + { + printf("ERROR: Client requested an unknown image id.\n"); + filesize = 0; + } + else + { + struct stat st; + fstat(image_file, &st); + filesize = st.st_size; + } + reply.cmd = request.cmd; + reply.filesize = filesize; + send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0); + break; + + case CMD_GET_BLOCK: + if (image_file < 0) + break; + + reply.cmd = request.cmd; + memcpy(reply.handle, request.handle, sizeof(request.handle)); + send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0); + + if (sendfile(sock, image_file, (off_t *) &request.offset, request.size) < 0) + printf("ERROR: sendfile returned -1\n"); + + break; + + default: + printf("ERROR: Unknown command\n"); + break; + } + + } + close(sock); + printf("INFO: Client exit.\n"); + pthread_exit((void *) 0); } int main(int argc, char* argv[]) { - int demonize = 1; - int opt = 0; - int longIndex = 0; - static const char *optString = "f:nrshv?"; - static const struct option longOpts[] = - { - { "file", required_argument, NULL, 'f' }, - { "nodaemon", no_argument, NULL, 'n' }, - { "reload", no_argument, NULL, 'r' }, - { "stop", no_argument, NULL, 's' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'v' } }; - - opt = getopt_long(argc, argv, optString, longOpts, &longIndex); - - while (opt != -1) - { - switch (opt) - { - case 'f': - config_file_name = optarg; - break; - case 'n': - demonize = 0; - break; - case 'r': - printf("INFO: Reloading configuration file...\n"); - dnbd3_send_signal(SIGHUP); - return EXIT_SUCCESS; - case 's': - printf("INFO: Stopping running server...\n"); - dnbd3_send_signal(SIGTERM); - return EXIT_SUCCESS; - case 'h': - print_help(argv[0]); - break; - case 'v': - print_version(); - break; - case '?': - exit(1); - } - opt = getopt_long(argc, argv, optString, longOpts, &longIndex); - } - - if (demonize) - daemon(1,0); - - pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE); - dnbd3_load_config(config_file_name); - - // setup signal handler - signal(SIGPIPE, handle_sigpipe); - signal(SIGHUP, handle_sighup); - signal(SIGTERM, handle_sigterm); - signal(SIGINT, handle_sigterm); - - // setup network - struct sockaddr_in server; - struct sockaddr_in client; - int fd; - unsigned int len; - - // Create socket - _sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (_sock < 0) - { - printf("ERROR: Socket failure\n"); - exit(EXIT_FAILURE); - } - - memset(&server, 0, sizeof(server)); - server.sin_family = AF_INET; // IPv4 - server.sin_addr.s_addr = htonl(INADDR_ANY); // Take all IPs - server.sin_port = htons(PORT); // set port number - - // Bind to socket - if (bind(_sock, (struct sockaddr*) &server, sizeof(server)) < 0) - { - printf("ERROR: Bind failure\n"); - exit(EXIT_FAILURE); - } - - // Listen on socket - if (listen(_sock, 50) == -1) - { - printf("ERROR: Listen failure\n"); - exit(EXIT_FAILURE); - } - - dnbd3_write_pid_file(getpid()); - printf("INFO: Server is ready...\n"); - - struct timeval timeout; - timeout.tv_sec = SERVER_SOCKET_TIMEOUT; - timeout.tv_usec = 0; - - - while (1) - { - len = sizeof(client); - fd = accept(_sock, (struct sockaddr*) &client, &len); - if (fd < 0) - { - printf("ERROR: Accept failure\n"); - exit(EXIT_FAILURE); - } - printf("INFO: Client: %s connected\n", inet_ntoa(client.sin_addr)); - - setsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); - setsockopt (fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)); - - // FIXME: catch SIGKILL/SIGTERM and close all socket before exit - pthread_t thread; - pthread_create(&(thread), NULL, handle_query, (void *)(uintptr_t) fd); - pthread_detach(thread); - } - - cleanup(); + int demonize = 1; + int opt = 0; + int longIndex = 0; + static const char *optString = "f:nrshv?"; + static const struct option longOpts[] = + { + { "file", required_argument, NULL, 'f' }, + { "nodaemon", no_argument, NULL, 'n' }, + { "reload", no_argument, NULL, 'r' }, + { "stop", no_argument, NULL, 's' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' } }; + + opt = getopt_long(argc, argv, optString, longOpts, &longIndex); + + while (opt != -1) + { + switch (opt) + { + case 'f': + config_file_name = optarg; + break; + case 'n': + demonize = 0; + break; + case 'r': + printf("INFO: Reloading configuration file...\n"); + dnbd3_send_signal(SIGHUP); + return EXIT_SUCCESS; + case 's': + printf("INFO: Stopping running server...\n"); + dnbd3_send_signal(SIGTERM); + return EXIT_SUCCESS; + case 'h': + print_help(argv[0]); + break; + case 'v': + print_version(); + break; + case '?': + exit(1); + } + opt = getopt_long(argc, argv, optString, longOpts, &longIndex); + } + + if (demonize) + daemon(1, 0); + + // load config file + pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE); + dnbd3_load_config(config_file_name); + + // setup signal handler + signal(SIGPIPE, handle_sigpipe); + signal(SIGHUP, handle_sighup); + signal(SIGTERM, handle_sigterm); + signal(SIGINT, handle_sigterm); + + // setup network + struct sockaddr_in server; + struct sockaddr_in client; + int fd; + unsigned int len; + + // Create socket + _sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (_sock < 0) + { + printf("ERROR: Socket failure\n"); + exit(EXIT_FAILURE); + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; // IPv4 + server.sin_addr.s_addr = htonl(INADDR_ANY); // Take all IPs + server.sin_port = htons(PORT); // set port number + + // Bind to socket + if (bind(_sock, (struct sockaddr*) &server, sizeof(server)) < 0) + { + printf("ERROR: Bind failure\n"); + exit(EXIT_FAILURE); + } + + // Listen on socket + if (listen(_sock, 50) == -1) + { + printf("ERROR: Listen failure\n"); + exit(EXIT_FAILURE); + } + + dnbd3_write_pid_file(getpid()); + printf("INFO: Server is ready...\n"); + + struct timeval timeout; + timeout.tv_sec = SERVER_SOCKET_TIMEOUT; + timeout.tv_usec = 0; + + while (1) + { + len = sizeof(client); + fd = accept(_sock, (struct sockaddr*) &client, &len); + if (fd < 0) + { + printf("ERROR: Accept failure\n"); + exit(EXIT_FAILURE); + } + printf("INFO: Client: %s connected\n", inet_ntoa(client.sin_addr)); + + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout)); + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)); + + // FIXME: catch SIGKILL/SIGTERM and close all socket before exit + pthread_t thread; + pthread_create(&(thread), NULL, handle_query, (void *) (uintptr_t) fd); + pthread_detach(thread); + } + + cleanup(); } diff --git a/src/server/utils.c b/src/server/utils.c index ab0d29d..3a42849 100644 --- a/src/server/utils.c +++ b/src/server/utils.c @@ -27,91 +27,90 @@ void dnbd3_write_pid_file(pid_t pid) { - FILE *f = fopen(SERVER_PID_FILE, "w"); - if(f != NULL) - { - fprintf(f, "%i", pid); - fclose(f); - } - else - { - printf("ERROR: Couldn't write pid file (%s).\n", SERVER_PID_FILE); - } + FILE *f = fopen(SERVER_PID_FILE, "w"); + if (f != NULL) + { + fprintf(f, "%i", pid); + fclose(f); + } + else + { + printf("ERROR: Couldn't write pid file (%s).\n", SERVER_PID_FILE); + } } pid_t dnbd3_read_pid_file() { - pid_t pid = 0; + pid_t pid = 0; - FILE *f = fopen(SERVER_PID_FILE, "r"); - if(f != NULL) - { - fscanf(f, "%i", &pid); - fclose(f); - } - else - { - printf("ERROR: Couldn't read pid file (%s).\n", SERVER_PID_FILE); - } + FILE *f = fopen(SERVER_PID_FILE, "r"); + if (f != NULL) + { + fscanf(f, "%i", &pid); + fclose(f); + } + else + { + printf("ERROR: Couldn't read pid file (%s).\n", SERVER_PID_FILE); + } - return pid; + return pid; } void dnbd3_delete_pid_file() { - if (unlink(SERVER_PID_FILE) != 0) - { - printf("ERROR: Couldn't delete pid file (%s).\n", SERVER_PID_FILE); - } + if (unlink(SERVER_PID_FILE) != 0) + { + printf("ERROR: Couldn't delete pid file (%s).\n", SERVER_PID_FILE); + } } - void dnbd3_load_config(char* config_file_name) { - dnbd3_ht_create(); - FILE *config_file = fopen(config_file_name, "r"); + dnbd3_ht_create(); + FILE *config_file = fopen(config_file_name, "r"); - if (config_file == NULL) - { - printf("ERROR: Config file not found: %s\n", config_file_name); - exit(EXIT_FAILURE); - } + if (config_file == NULL) + { + printf("ERROR: Config file not found: %s\n", config_file_name); + exit(EXIT_FAILURE); + } - char line[MAX_FILE_NAME + 1 + MAX_FILE_ID]; - char* image_name = NULL; - char* image_id = NULL; + char line[MAX_FILE_NAME + 1 + MAX_FILE_ID]; + char* image_name = NULL; + char* image_id = NULL; - while (fgets(line, sizeof(line), config_file) != NULL) - { - sscanf(line, "%as %as", &image_name, &image_id); - if (dnbd3_ht_insert(image_id, image_name) < 0) - { - printf("ERROR: Image name or ID is too big\n"); - exit(EXIT_FAILURE); - } - } - fclose(config_file); + while (fgets(line, sizeof(line), config_file) != NULL) + { + sscanf(line, "%as %as", &image_name, &image_id); + if (dnbd3_ht_insert(image_id, image_name) < 0) + { + printf("ERROR: Image name or ID is too big\n"); + exit(EXIT_FAILURE); + } + } + fclose(config_file); } void dnbd3_reload_config(char* config_file_name) { - dnbd3_ht_destroy(); - dnbd3_load_config(config_file_name); + dnbd3_ht_destroy(); + dnbd3_load_config(config_file_name); } void dnbd3_send_signal(int signum) { - pid_t pid = dnbd3_read_pid_file(); - if (pid != 0) - { - if (kill(pid, signum) != 0) - { - printf("ERROR: dnbd3-server is not running\n"); - dnbd3_delete_pid_file(); - } - } - else - { - printf("ERROR: dnbd3-server is not running\n"); - } + pid_t pid = dnbd3_read_pid_file(); + if (pid != 0) + { + if (kill(pid, signum) != 0) + { + printf("ERROR: dnbd3-server is not running\n"); + dnbd3_delete_pid_file(); + } + } + else + { + printf("ERROR: dnbd3-server is not running\n"); + } } diff --git a/src/types.h b/src/types.h index 2d34943..cdde4bd 100644 --- a/src/types.h +++ b/src/types.h @@ -39,20 +39,20 @@ #pragma pack(1) typedef struct dnbd3_request { - uint16_t cmd; - uint64_t offset; - uint64_t size; - char image_id[MAX_FILE_ID]; - char handle[8]; + uint16_t cmd; + uint64_t offset; + uint64_t size; + char image_id[MAX_FILE_ID]; + char handle[8]; } dnbd3_request_t; #pragma pack(0) #pragma pack(1) typedef struct dnbd3_reply { - uint16_t cmd; - uint64_t filesize; - char handle[8]; + uint16_t cmd; + uint64_t filesize; + char handle[8]; } dnbd3_reply_t; #pragma pack(0) -- cgit v1.2.3-55-g7522