summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/client/client.c57
-rw-r--r--src/kernel/blk.c17
-rw-r--r--src/kernel/dnbd3.h8
-rw-r--r--src/kernel/net.c49
-rw-r--r--src/kernel/net.h2
-rw-r--r--src/server/server.c5
-rw-r--r--src/types.h9
8 files changed, 110 insertions, 41 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c1874d0..78deb01 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,8 +39,8 @@ TARGET_LINK_LIBRARIES(dnbd3-server ${CMAKE_THREAD_LIBS_INIT})
SET(MODULE_NAME dnbd3)
SET(MODULE_FILE ${MODULE_NAME}.ko)
-FILE(GLOB_RECURSE MODULE_SOURCE_FILES src/kernel/*.c)
-FILE(GLOB_RECURSE MODULE_HEADER_FILES src/kernel/*.h src/*.h)
+FILE(GLOB MODULE_SOURCE_FILES src/kernel/*.c)
+FILE(GLOB MODULE_HEADER_FILES src/kernel/*.h src/*.h)
SET(KERNEL_DIR "/lib/modules/${CMAKE_SYSTEM_VERSION}/build")
diff --git a/src/client/client.c b/src/client/client.c
index d60614b..54535a3 100644
--- a/src/client/client.c
+++ b/src/client/client.c
@@ -31,12 +31,13 @@
void print_help(char* argv_0)
{
- printf("Usage: %s -H <host> -p <port> -i <image-id> -d <device>\n", argv_0);
+ printf("Usage: %s -H <host> -p <port> -i <image-id> -d <device> || -c <host> -d <device>\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);
@@ -50,20 +51,23 @@ void print_version()
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:hv?";
+ static const char *optString = "H:p:i:d: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' }, };
@@ -85,6 +89,10 @@ int main(int argc, char *argv[])
case 'd':
dev = optarg;
break;
+ case 'c':
+ host = optarg;
+ change_host = 1;
+ break;
case 'h':
print_help(argv[0]);
break;
@@ -97,28 +105,43 @@ int main(int argc, char *argv[])
opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
}
- if (!host || !port || !dev || !image_id)
+ if (change_host && host && dev && !port && !image_id)
{
- printf("FATAL: Not enough information specified\n");
- exit(EXIT_FAILURE);
+ 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);
}
- int fd;
- fd = open(dev, O_RDONLY);
+ 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_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_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_SET_IMAGE, image_id) < 0)
+ printf("ERROR: ioctl not successful\n");
- if (ioctl(fd, IOCTL_CONNECT) < 0)
- printf("ERROR: ioctl not successful\n");
+ if (ioctl(fd, IOCTL_CONNECT) < 0)
+ printf("ERROR: ioctl not successful\n");
- close(fd);
+ close(fd);
+ exit(EXIT_SUCCESS);
+ }
- exit(EXIT_SUCCESS);
+ print_help(argv[0]);
+ exit(EXIT_FAILURE);
}
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 213ae23..c495205 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -64,7 +64,10 @@ int dnbd3_blk_add_device(struct dnbd3_device *dev, int minor)
int dnbd3_blk_del_device(struct dnbd3_device *dev)
{
if (dev->sock)
+ {
sock_release(dev->sock);
+ dev->sock = NULL;
+ }
del_gendisk(dev->disk);
put_disk(dev->disk);
@@ -83,17 +86,23 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
switch (cmd)
{
case IOCTL_SET_HOST:
- lo->host = (char *) arg;
+ strcpy(lo->host, (char *) arg);
break;
case IOCTL_SET_PORT:
- lo->port = (char *) arg;
+ strcpy(lo->port, (char *) arg);
break;
case IOCTL_SET_IMAGE:
- lo->image_id = (char *) arg;
+ strcpy(lo->image_id, (char *) arg);
break;
case IOCTL_CONNECT:
- dnbd3_net_connect(lo);
+ 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;
diff --git a/src/kernel/dnbd3.h b/src/kernel/dnbd3.h
index 561c554..5f45699 100644
--- a/src/kernel/dnbd3.h
+++ b/src/kernel/dnbd3.h
@@ -39,12 +39,14 @@ struct dnbd3_device
spinlock_t blk_lock;
// network
- char* host;
- char* port;
- char* image_id;
+ char host[16];
+ char port[6];
+ char image_id[MAX_FILE_NAME];
struct socket *sock;
// 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;
diff --git a/src/kernel/net.c b/src/kernel/net.c
index 9a323e8..c3f9782 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -28,8 +28,6 @@ void dnbd3_net_connect(struct dnbd3_device *lo)
struct kvec iov;
struct dnbd3_request dnbd3_request;
struct dnbd3_reply dnbd3_reply;
- struct task_struct *thread_send;
- struct task_struct *thread_receive;
if (!lo->host || !lo->port || !lo->image_id)
{
@@ -37,6 +35,9 @@ void dnbd3_net_connect(struct dnbd3_device *lo)
return;
}
+ // FIXME: 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)
{
@@ -49,7 +50,7 @@ void dnbd3_net_connect(struct dnbd3_device *lo)
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 given host.\n");
+ printk("ERROR: dnbd3 couldn't connect to host %s:%s\n", lo->host, lo->port);
return;
}
@@ -82,12 +83,42 @@ void dnbd3_net_connect(struct dnbd3_device *lo)
set_capacity(lo->disk, dnbd3_reply.filesize >> 9); /* 512 Byte blocks */
// start sending thread
- thread_send = kthread_create(dnbd3_net_send, lo, lo->disk->disk_name);
- wake_up_process(thread_send);
+ lo->thread_send = kthread_create(dnbd3_net_send, lo, lo->disk->disk_name);
+ wake_up_process(lo->thread_send);
// start receiving thread
- thread_receive = kthread_create(dnbd3_net_receive, lo, lo->disk->disk_name);
- wake_up_process(thread_receive);
+ lo->thread_receive = kthread_create(dnbd3_net_receive, lo, lo->disk->disk_name);
+ wake_up_process(lo->thread_receive);
+}
+
+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;
+ }
+
+ // 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)
@@ -167,6 +198,9 @@ int dnbd3_net_receive(void *data)
{
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);
@@ -206,6 +240,5 @@ int dnbd3_net_receive(void *data)
__blk_end_request_all(blk_request, 0);
spin_unlock_irqrestore(&lo->blk_lock, flags);
}
-
return 0;
}
diff --git a/src/kernel/net.h b/src/kernel/net.h
index 5ac8f6f..017a71e 100644
--- a/src/kernel/net.h
+++ b/src/kernel/net.h
@@ -25,6 +25,8 @@
void dnbd3_net_connect(struct dnbd3_device *lo);
+void dnbd3_net_disconnect(struct dnbd3_device *lo);
+
int dnbd3_net_send(void *data);
int dnbd3_net_receive(void *data);
diff --git a/src/server/server.c b/src/server/server.c
index 90ec77b..4dbeb7f 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -79,7 +79,6 @@ void handle_sighup(int signum)
pthread_spin_lock(&spinlock);
reload_config(config_file_name);
pthread_spin_unlock(&spinlock);
- // TODO: stop handle_query or use mutex before image_file = open(ht_search(request.image_id), O_RDONLY);
}
void handle_sigterm(int signum)
@@ -94,7 +93,7 @@ void *handle_query(void *client_socket)
{
int image_file = -1;
off_t filesize = 0;
- int sock = (int) client_socket;
+ int sock = (int)(uintptr_t) client_socket;
struct dnbd3_request request;
struct dnbd3_reply reply;
uint16_t cmd;
@@ -258,7 +257,7 @@ int main(int argc, char* argv[])
// FIXME: catch SIGKILL/SIGTERM and close all socket before exit
pthread_t thread;
- pthread_create(&(thread), NULL, handle_query, (void *) fd);
+ pthread_create(&(thread), NULL, handle_query, (void *)(uintptr_t) fd);
pthread_detach(thread);
}
diff --git a/src/types.h b/src/types.h
index f4ff98e..3e03d97 100644
--- a/src/types.h
+++ b/src/types.h
@@ -25,10 +25,11 @@
// ioctl
#define DNBD3_MAGIC 'd'
-#define IOCTL_SET_HOST _IO(0xab, 1)
-#define IOCTL_SET_PORT _IO(0xab, 2)
-#define IOCTL_SET_IMAGE _IO(0xab, 3)
-#define IOCTL_CONNECT _IO(0xab, 4)
+#define IOCTL_SET_HOST _IO(0xab, 1)
+#define IOCTL_SET_PORT _IO(0xab, 2)
+#define IOCTL_SET_IMAGE _IO(0xab, 3)
+#define IOCTL_CONNECT _IO(0xab, 4)
+#define IOCTL_DISCONNECT _IO(0xab, 5)
// network
#define CMD_GET_BLOCK 1