summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohann Latocha2012-02-22 17:24:45 +0100
committerJohann Latocha2012-02-22 17:24:45 +0100
commit826ade8c69c69a0b25071092c674938bc297f0bf (patch)
treeb0f79816da1acaee0bde5e06885b1f123a651609
parent[SERVER] Segfault on conf reload (hopefully!) fixed (diff)
downloaddnbd3-826ade8c69c69a0b25071092c674938bc297f0bf.tar.gz
dnbd3-826ade8c69c69a0b25071092c674938bc297f0bf.tar.xz
dnbd3-826ade8c69c69a0b25071092c674938bc297f0bf.zip
[ALL] Bugs, bugs, bugs...
-rw-r--r--src/config.h2
-rw-r--r--src/kernel/blk.c5
-rw-r--r--src/kernel/net.c48
-rw-r--r--src/kernel/sysfs.c7
-rw-r--r--src/server/net.c61
-rw-r--r--src/types.h4
6 files changed, 61 insertions, 66 deletions
diff --git a/src/config.h b/src/config.h
index 8a6cdcf..594d7b5 100644
--- a/src/config.h
+++ b/src/config.h
@@ -26,7 +26,7 @@
#define PORTSTR "5003"
#define SOCKET_TIMEOUT_SERVER 30
-#define SOCKET_TIMEOUT_CLIENT_DATA 5
+#define SOCKET_TIMEOUT_CLIENT_DATA 2
#define SOCKET_TIMEOUT_CLIENT_DISCOVERY 1
#define TIMER_INTERVAL_HEARTBEAT 10*HZ
#define TIMER_INTERVAL_PANIC 1*HZ
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 70d4e1f..1023743 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -95,8 +95,6 @@ struct block_device_operations dnbd3_blk_ops =
int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
{
dnbd3_device_t *dev = bdev->bd_disk->private_data;
- int minor = dev->disk->first_minor;
-
dnbd3_ioctl_t *msg = kmalloc(sizeof(dnbd3_ioctl_t), GFP_KERNEL);
copy_from_user((char *)msg, (char *)arg, sizeof(*msg));
@@ -111,9 +109,8 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
break;
case IOCTL_CLOSE:
+ set_capacity(dev->disk, 0);
dnbd3_net_disconnect(dev);
- dnbd3_blk_del_device(dev);
- dnbd3_blk_add_device(dev, minor);
break;
case IOCTL_SWITCH:
diff --git a/src/kernel/net.c b/src/kernel/net.c
index bdab8c2..a820a04 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -36,17 +36,17 @@ void dnbd3_net_connect(dnbd3_device_t *dev)
// do some checks before connecting
if (!req)
{
- printk("ERROR: Kmalloc failed.\n");
+ printk("FATAL: Kmalloc failed.\n");
return;
}
if (!dev->cur_server.host || !dev->cur_server.port || (dev->vid == 0))
{
- printk("ERROR: Host, port or vid not set.\n");
+ printk("FATAL: Host, port or vid not set.\n");
return;
}
if (dev->cur_server.sock)
{
- printk("ERROR: Device %s already connected to %s.\n", dev->disk->disk_name, dev->cur_server.host);
+ printk("ERROR: Device %s is already connected to %s.\n", dev->disk->disk_name, dev->cur_server.host);
return;
}
@@ -73,6 +73,7 @@ void dnbd3_net_connect(dnbd3_device_t *dev)
}
dev->panic = 0;
+ dev->alt_servers_num = 0;
// enqueue request to request_queue_send (ask file size)
req->cmd_type = REQ_TYPE_SPECIAL;
@@ -122,10 +123,12 @@ void dnbd3_net_disconnect(dnbd3_device_t *dev)
// clear socket
if (dev->cur_server.sock)
- {
sock_release(dev->cur_server.sock);
- dev->cur_server.sock = NULL;
- }
+
+ dev->thread_send = NULL;
+ dev->thread_receive = NULL;
+ dev->thread_discover = NULL;
+ dev->cur_server.sock = NULL;
}
void dnbd3_net_heartbeat(unsigned long arg)
@@ -320,6 +323,7 @@ int dnbd3_net_discover(void *data)
}
kfree(buf);
+ printk("INFO: dnbd3_net_discover exit\n");
return 0;
}
@@ -354,6 +358,8 @@ int dnbd3_net_send(void *data)
{
case REQ_TYPE_FS:
dnbd3_request.cmd = CMD_GET_BLOCK;
+ dnbd3_request.vid = dev->vid;
+ dnbd3_request.rid = dev->rid;
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;
@@ -368,6 +374,8 @@ int dnbd3_net_send(void *data)
break;
case REQ_GET_SERVERS:
dnbd3_request.cmd = CMD_GET_SERVERS;
+ dnbd3_request.vid = dev->vid;
+ dnbd3_request.rid = dev->rid;
break;
}
break;
@@ -394,6 +402,8 @@ int dnbd3_net_send(void *data)
spin_unlock_irq(&dev->blk_lock);
wake_up(&dev->process_queue_receive);
}
+
+ printk("INFO: dnbd3_net_send exit\n");
return 0;
error:
@@ -450,29 +460,19 @@ int dnbd3_net_receive(void *data)
}
spin_unlock_irq(&dev->blk_lock);
- // check if server send error
- switch (dnbd3_reply.error)
+ // check error
+ if (dnbd3_reply.size == 0)
{
- case ERROR_SIZE:
printk("FATAL: Requested image does't exist\n");
+ spin_lock_irq(&dev->blk_lock);
list_del_init(&blk_request->queuelist);
- kthread_stop(dev->thread_send);
- del_timer(&dev->hb_timer);
- sock_release(dev->cur_server.sock);
- kfree(blk_request);
- dev->cur_server.sock = NULL;
- return -1;
-
- case ERROR_RELOAD:
- list_del_init(&blk_request->queuelist);
- blk_request->cmd_type = REQ_TYPE_SPECIAL;
- blk_request->cmd_flags = REQ_GET_FILESIZE;
- list_add(&blk_request->queuelist, &dev->request_queue_send);
- wake_up(&dev->process_queue_send);
+ spin_unlock_irq(&dev->blk_lock);
+ if ( (dnbd3_reply.cmd == CMD_GET_SIZE) || (dnbd3_reply.cmd == CMD_GET_SERVERS) )
+ kfree(blk_request);
continue;
-
}
+
// what to do?
switch (dnbd3_reply.cmd)
{
@@ -543,6 +543,8 @@ int dnbd3_net_receive(void *data)
}
}
+
+ printk("INFO: dnbd3_net_receive exit\n");
return 0;
error:
diff --git a/src/kernel/sysfs.c b/src/kernel/sysfs.c
index e363824..177cb8c 100644
--- a/src/kernel/sysfs.c
+++ b/src/kernel/sysfs.c
@@ -163,7 +163,10 @@ struct sysfs_ops server_ops =
.show = server_show,
};
-void release(struct kobject *kobj) {}
+void release(struct kobject *kobj)
+{
+ kobj->state_initialized = 0;
+}
struct kobj_type device_ktype =
{
@@ -202,11 +205,9 @@ void dnbd3_sysfs_init(dnbd3_device_t *dev)
void dnbd3_sysfs_exit(dnbd3_device_t *dev)
{
int i;
-
for (i = 0; i < NUMBER_SERVERS; i++)
{
kobject_put(&dev->alt_servers[i].kobj);
}
-
kobject_put(&dev->kobj);
}
diff --git a/src/server/net.c b/src/server/net.c
index 79bf28c..7e9d788 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -43,74 +43,64 @@ void *dnbd3_handle_query(void *dnbd3_client)
dnbd3_image_t *image = NULL;
int image_file = -1;
- struct in_addr server;
+ struct in_addr alt_server;
int i = 0;
while (recv(client->sock, &request, sizeof(dnbd3_request_t), MSG_WAITALL) > 0)
{
reply.cmd = request.cmd;
- reply.error = 0;
+ reply.size = 0;
memcpy(reply.handle, request.handle, sizeof(request.handle));
pthread_spin_lock(&client->spinlock);
switch (request.cmd)
{
case CMD_GET_SERVERS:
- if(!client->image)
- { // configuration was reloaded, send error
- reply.size = 0;
- reply.error = ERROR_RELOAD;
- send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
- break;
- }
-
- if (client->image->num_servers < NUMBER_SERVERS)
- reply.size = client->image->num_servers * sizeof(struct in_addr);
- else
- reply.size = NUMBER_SERVERS * sizeof(struct in_addr);
+ image = dnbd3_get_image(request.vid, request.rid);
+ if(!image)
+ goto error;
+ int num = (image->num_servers < NUMBER_SERVERS) ? image->num_servers : NUMBER_SERVERS;
+ reply.vid = image->vid;
+ reply.rid = image->rid;
+ reply.size = num * sizeof(struct in_addr);
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
- for (i = 0; i < client->image->num_servers && i < NUMBER_SERVERS; i++)
+ for (i = 0; i < num; i++)
{
- inet_aton(client->image->servers[i], &server);
- send(client->sock, (char *) &server, sizeof(struct in_addr), 0);
+ inet_aton(image->servers[i], &alt_server);
+ send(client->sock, (char *) &alt_server, sizeof(struct in_addr), 0);
}
+ client->image = image;
+ image->atime = time(NULL); // TODO: check if mutex is needed
break;
case CMD_GET_SIZE:
image = dnbd3_get_image(request.vid, request.rid);
-
if(!image)
- { // image not found, send error
- printf("ERROR: Client requested an unknown image id.\n");
- reply.size = 0;
- reply.error = ERROR_SIZE;
- send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
- break;
- }
+ goto error;
- image_file = open(image->file, O_RDONLY);
reply.vid = image->vid;
reply.rid = image->rid;
reply.size = sizeof(uint64_t);
- client->image = image;
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
+
send(client->sock, &image->filesize, sizeof(uint64_t), 0);
- image->atime = time(NULL);
+ image_file = open(image->file, O_RDONLY);
+ client->image = image;
+ image->atime = time(NULL); // TODO: check if mutex is needed
break;
case CMD_GET_BLOCK:
if (image_file < 0)
- break;
+ goto error;
reply.size = request.size;
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
if (sendfile(client->sock, image_file, (off_t *) &request.offset, request.size) < 0)
- printf("ERROR: sendfile returned -1\n");
+ printf("ERROR: Sendfile failed\n");
- image->atime = time(NULL); // TODO: check if mutex is needed
break;
default:
@@ -118,7 +108,16 @@ void *dnbd3_handle_query(void *dnbd3_client)
break;
}
+
pthread_spin_unlock(&client->spinlock);
+ continue;
+
+ error:
+ printf("ERROR: Client requested an unknown image id.\n");
+ send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
+ pthread_spin_unlock(&client->spinlock);
+ continue;
+
}
close(client->sock);
close(image_file);
diff --git a/src/types.h b/src/types.h
index 38e05f4..7c4c5e2 100644
--- a/src/types.h
+++ b/src/types.h
@@ -42,9 +42,6 @@ typedef struct
#define CMD_GET_SIZE 2
#define CMD_GET_SERVERS 3
-#define ERROR_SIZE 1
-#define ERROR_RELOAD 2
-
#pragma pack(1)
typedef struct
{
@@ -63,7 +60,6 @@ typedef struct
uint16_t cmd; // 2byte
uint16_t vid; // 2byte
uint16_t rid; // 2byte
- uint16_t error; // 2byte
uint64_t size; // 8byte
char handle[8]; // 8byte
} dnbd3_reply_t;