From b7098dd3b66269b82a2253cbd19555693cbfd3b9 Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Wed, 22 Feb 2012 01:25:57 +0100 Subject: [SERVER] Segfault on conf reload (hopefully!) fixed --- src/kernel/net.c | 28 ++++++++++++++-------------- src/server/ipc.c | 2 ++ src/server/net.c | 29 ++++++++++++++--------------- src/server/server.c | 9 ++++++++- src/server/server.h | 1 + src/server/utils.c | 2 ++ 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) -- cgit v1.2.3-55-g7522