summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohann Latocha2012-02-22 01:25:57 +0100
committerJohann Latocha2012-02-22 01:25:57 +0100
commitb7098dd3b66269b82a2253cbd19555693cbfd3b9 (patch)
tree624b20111d7ac632acead73a1e968ab954d8ae85 /src
parent[ALL] Send proper rid (diff)
downloaddnbd3-b7098dd3b66269b82a2253cbd19555693cbfd3b9.tar.gz
dnbd3-b7098dd3b66269b82a2253cbd19555693cbfd3b9.tar.xz
dnbd3-b7098dd3b66269b82a2253cbd19555693cbfd3b9.zip
[SERVER] Segfault on conf reload (hopefully!) fixed
Diffstat (limited to 'src')
-rw-r--r--src/kernel/net.c28
-rw-r--r--src/server/ipc.c2
-rw-r--r--src/server/net.c29
-rw-r--r--src/server/server.c9
-rw-r--r--src/server/server.h1
-rw-r--r--src/server/utils.c2
6 files changed, 41 insertions, 30 deletions
diff --git a/src/kernel/net.c b/src/kernel/net.c
index baa2966..bdab8c2 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -219,19 +219,6 @@ int dnbd3_net_discover(void *data)
continue;
}
- // panic mode, take first responding server
- if (dev->panic)
- {
- printk("WARN: Panic mode, taking server %s\n", current_server);
- sock_release(sock);
- kfree(buf);
- dev->thread_discover = NULL;
- dnbd3_net_disconnect(dev);
- strcpy(dev->cur_server.host, current_server);
- dnbd3_net_connect(dev);
- return 0;
- }
-
// Request filesize
dnbd3_request.cmd = CMD_GET_SIZE;
dnbd3_request.vid = dev->vid;
@@ -253,6 +240,19 @@ int dnbd3_net_discover(void *data)
if (kernel_recvmsg(sock, &msg, &iov, 1, dnbd3_reply.size, msg.msg_flags) <= 0)
goto error;
+ // panic mode, take first responding server
+ if (dev->panic)
+ {
+ printk("WARN: Panic mode, taking server %s\n", current_server);
+ sock_release(sock);
+ kfree(buf);
+ dev->thread_discover = NULL;
+ dnbd3_net_disconnect(dev);
+ strcpy(dev->cur_server.host, current_server);
+ dnbd3_net_connect(dev);
+ return 0;
+ }
+
do_gettimeofday(&start); // start rtt measurement
// Request block
@@ -295,7 +295,7 @@ int dnbd3_net_discover(void *data)
continue;
error:
- printk("ERROR: kernel_sendmsg or kernel_recvmsg (discover)\n");
+ printk("ERROR: Send/Receive failed, host %s:%s (discover)\n", current_server, dev->cur_server.port);
sock_release(sock);
sock = NULL;
continue;
diff --git a/src/server/ipc.c b/src/server/ipc.c
index bc7b7a5..522c4ca 100644
--- a/src/server/ipc.c
+++ b/src/server/ipc.c
@@ -95,6 +95,7 @@ void* dnbd3_ipc_receive()
break;
case IPC_INFO:
+ pthread_spin_lock(&_spinlock);
num = g_slist_length(_dnbd3_clients) + _num_images +4;
send(client_sock, &num, sizeof(int), MSG_WAITALL); // send number of lines to print
@@ -128,6 +129,7 @@ void* dnbd3_ipc_receive()
sprintf(buf, "\nNumber clients: %i\n\n", g_slist_length(_dnbd3_clients));
send(client_sock, buf, sizeof(buf), MSG_WAITALL);
+ pthread_spin_unlock(&_spinlock);
close(client_sock);
break;
diff --git a/src/server/net.c b/src/server/net.c
index 67a64c9..79bf28c 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -40,6 +40,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
dnbd3_request_t request;
dnbd3_reply_t reply;
+ dnbd3_image_t *image = NULL;
int image_file = -1;
struct in_addr server;
@@ -51,6 +52,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
reply.error = 0;
memcpy(reply.handle, request.handle, sizeof(request.handle));
+ pthread_spin_lock(&client->spinlock);
switch (request.cmd)
{
case CMD_GET_SERVERS:
@@ -59,10 +61,9 @@ void *dnbd3_handle_query(void *dnbd3_client)
reply.size = 0;
reply.error = ERROR_RELOAD;
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
- continue;
+ break;
}
- pthread_spin_lock(&client->spinlock);
if (client->image->num_servers < NUMBER_SERVERS)
reply.size = client->image->num_servers * sizeof(struct in_addr);
else
@@ -75,13 +76,10 @@ void *dnbd3_handle_query(void *dnbd3_client)
inet_aton(client->image->servers[i], &server);
send(client->sock, (char *) &server, sizeof(struct in_addr), 0);
}
- pthread_spin_unlock(&client->spinlock);
- continue;
+ break;
case CMD_GET_SIZE:
- pthread_spin_lock(&client->spinlock);
- dnbd3_image_t *image = dnbd3_get_image(request.vid, request.rid);
- pthread_spin_unlock(&client->spinlock);
+ image = dnbd3_get_image(request.vid, request.rid);
if(!image)
{ // image not found, send error
@@ -89,7 +87,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
reply.size = 0;
reply.error = ERROR_SIZE;
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
- continue;
+ break;
}
image_file = open(image->file, O_RDONLY);
@@ -100,11 +98,11 @@ void *dnbd3_handle_query(void *dnbd3_client)
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
send(client->sock, &image->filesize, sizeof(uint64_t), 0);
image->atime = time(NULL);
- continue;
+ break;
case CMD_GET_BLOCK:
if (image_file < 0)
- continue;
+ break;
reply.size = request.size;
send(client->sock, (char *) &reply, sizeof(dnbd3_reply_t), 0);
@@ -113,19 +111,20 @@ void *dnbd3_handle_query(void *dnbd3_client)
printf("ERROR: sendfile returned -1\n");
image->atime = time(NULL); // TODO: check if mutex is needed
-
- continue;
+ break;
default:
printf("ERROR: Unknown command\n");
- continue;
+ break;
}
-
+ pthread_spin_unlock(&client->spinlock);
}
close(client->sock);
close(image_file);
+ pthread_spin_lock(&_spinlock);
_dnbd3_clients = g_slist_remove(_dnbd3_clients, client);
+ pthread_spin_unlock(&_spinlock);
printf("INFO: Client %s exit\n", client->ip);
free(client);
pthread_exit((void *) 0);
@@ -157,7 +156,7 @@ int dnbd3_setup_socket()
}
// Listen on socket
- if (listen(sock, 50) == -1)
+ if (listen(sock, 100) == -1)
{
printf("ERROR: Listen failure\n");
return -1;
diff --git a/src/server/server.c b/src/server/server.c
index dba7cdd..48dd545 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -35,6 +35,7 @@
#include "ipc.h"
int _sock;
+pthread_spinlock_t _spinlock;
GSList *_dnbd3_clients = NULL;
char *_config_file_name = DEFAULT_SERVER_CONFIG_FILE;
@@ -64,6 +65,8 @@ void dnbd3_print_version()
void dnbd3_cleanup()
{
printf("INFO: Cleanup...\n");
+
+ pthread_spin_lock(&_spinlock);
GSList *iterator = NULL;
for (iterator = _dnbd3_clients; iterator; iterator = iterator->next)
{
@@ -71,8 +74,8 @@ void dnbd3_cleanup()
shutdown(client->sock, SHUT_RDWR);
pthread_join(*client->thread, NULL);
}
-
g_slist_free(_dnbd3_clients);
+ pthread_spin_unlock(&_spinlock);
close(_sock);
free(_images);
@@ -158,6 +161,8 @@ int main(int argc, char* argv[])
pthread_t thread_ipc;
pthread_create(&(thread_ipc), NULL, dnbd3_ipc_receive, NULL);
+ pthread_spin_init(&_spinlock, PTHREAD_PROCESS_PRIVATE);
+
printf("INFO: Server is ready...\n");
// main loop
@@ -182,7 +187,9 @@ int main(int argc, char* argv[])
dnbd3_client->thread = &thread;
dnbd3_client->image = NULL;
+ pthread_spin_lock(&_spinlock);
_dnbd3_clients = g_slist_append(_dnbd3_clients, dnbd3_client);
+ pthread_spin_unlock(&_spinlock);
pthread_create(&(thread), NULL, dnbd3_handle_query, (void *) (uintptr_t) dnbd3_client);
pthread_detach(thread);
diff --git a/src/server/server.h b/src/server/server.h
index 00a04e8..e73c171 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -49,6 +49,7 @@ typedef struct
} dnbd3_client_t;
extern GSList *_dnbd3_clients;
+extern pthread_spinlock_t _spinlock;
extern char *_config_file_name;
extern dnbd3_image_t *_images;
extern size_t _num_images;
diff --git a/src/server/utils.c b/src/server/utils.c
index 70e195e..eda6216 100644
--- a/src/server/utils.c
+++ b/src/server/utils.c
@@ -74,6 +74,7 @@ void dnbd3_load_config(char *file)
void dnbd3_reload_config(char* config_file_name)
{
+ pthread_spin_lock(&_spinlock);
GSList *iterator = NULL;
for (iterator = _dnbd3_clients; iterator; iterator = iterator->next)
{
@@ -89,6 +90,7 @@ void dnbd3_reload_config(char* config_file_name)
dnbd3_client_t *client = iterator->data;
pthread_spin_unlock(&client->spinlock);
}
+ pthread_spin_unlock(&_spinlock);
}
dnbd3_image_t* dnbd3_get_image(int vid, int rid)