summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr2013-07-18 13:47:01 +0200
committersr2013-07-18 13:47:01 +0200
commitf2efd7f97baf6ab5d590ac7642bbf7317f8c47ed (patch)
tree7ed2e5f2ae802742ff59a7d73e6570054df39d78
parentRemove all glib dependencies from server (diff)
downloaddnbd3-f2efd7f97baf6ab5d590ac7642bbf7317f8c47ed.tar.gz
dnbd3-f2efd7f97baf6ab5d590ac7642bbf7317f8c47ed.tar.xz
dnbd3-f2efd7f97baf6ab5d590ac7642bbf7317f8c47ed.zip
kernel module changes
-rw-r--r--src/kernel/blk.c12
-rw-r--r--src/kernel/net.c28
-rw-r--r--src/server/locks.c43
-rw-r--r--src/server/locks.h4
-rw-r--r--src/server/server.c15
5 files changed, 69 insertions, 33 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 938a0e8..2bb70de 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -106,6 +106,11 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
dnbd3_ioctl_t *msg = NULL;
//unsigned long irqflags;
+ while (dev->disconnecting)
+ {
+ // do nothing
+ }
+
if (arg != 0)
{
msg = kmalloc(sizeof(*msg), GFP_KERNEL);
@@ -232,6 +237,7 @@ void dnbd3_blk_request(struct request_queue *q)
{
struct request *req;
dnbd3_device_t *dev;
+ unsigned long flags;
while ((req = blk_fetch_request(q)) != NULL)
{
@@ -261,7 +267,9 @@ void dnbd3_blk_request(struct request_queue *q)
continue;
}
+ spin_lock_irqsave(&dev->blk_lock, flags);
list_add_tail(&req->queuelist, &dev->request_queue_send);
+ spin_unlock_irqrestore(&dev->blk_lock, flags);
spin_unlock_irq(q->queue_lock);
wake_up(&dev->process_queue_send);
spin_lock_irq(q->queue_lock);
@@ -276,7 +284,7 @@ void dnbd3_blk_fail_all_requests(dnbd3_device_t *dev)
struct list_head local_copy;
int dup;
INIT_LIST_HEAD(&local_copy);
- spin_lock_irq(&dev->blk_lock);
+ spin_lock_irqsave(&dev->blk_lock, flags);
while (!list_empty(&dev->request_queue_receive))
{
list_for_each_entry_safe(blk_request, tmp_request, &dev->request_queue_receive, queuelist)
@@ -313,7 +321,7 @@ void dnbd3_blk_fail_all_requests(dnbd3_device_t *dev)
if (!dup) list_add(&blk_request->queuelist, &local_copy);
}
}
- spin_unlock_irq(&dev->blk_lock);
+ spin_unlock_irqrestore(&dev->blk_lock, flags);
list_for_each_entry_safe(blk_request, tmp_request, &local_copy, queuelist)
{
list_del_init(&blk_request->queuelist);
diff --git a/src/kernel/net.c b/src/kernel/net.c
index 0217d26..24fc4d6 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -124,6 +124,11 @@ int dnbd3_net_connect(dnbd3_device_t *dev)
char get_servers = 0, set_client = 0;
+ while (dev->disconnecting)
+ {
+ if (dev->better_sock) schedule();
+ }
+
timeout.tv_sec = SOCKET_TIMEOUT_CLIENT_DATA;
timeout.tv_usec = 0;
@@ -313,14 +318,16 @@ error:
int dnbd3_net_disconnect(dnbd3_device_t *dev)
{
+ if (dev->disconnecting)
+ return 0;
+
if (dev->cur_server.host.port)
debug_dev("INFO: Disconnecting device.");
dev->disconnecting = 1;
// clear heartbeat timer
- if (&dev->hb_timer)
- del_timer(&dev->hb_timer);
+ del_timer(&dev->hb_timer);
dev->discover = 0;
@@ -455,9 +462,9 @@ int dnbd3_net_discover(void *data)
for (;;)
{
wait_event_interruptible(dev->process_queue_discover,
- kthread_should_stop() || dev->discover);
+ kthread_should_stop() || dev->discover || dev->thread_discover == NULL);
- if (kthread_should_stop() || dev->imgname == NULL)
+ if (kthread_should_stop() || dev->imgname == NULL || dev->thread_discover == NULL)
break;
if (!dev->discover)
@@ -467,7 +474,7 @@ int dnbd3_net_discover(void *data)
if (dev->reported_size < 4096)
continue;
- // Check if the list of alt servers needs to be updated and do so if neccessary
+ // Check if the list of alt servers needs to be updated and do so if necessary
if (dev->new_servers_num)
{
spin_lock_irqsave(&dev->blk_lock, irqflags);
@@ -555,10 +562,10 @@ int dnbd3_net_discover(void *data)
iov[0].iov_base = &dnbd3_request;
iov[0].iov_len = sizeof(dnbd3_request);
serializer_reset_write(payload);
- serializer_put_uint16(payload, PROTOCOL_VERSION);
- serializer_put_string(payload, dev->imgname);
- serializer_put_uint16(payload, dev->rid);
- serializer_put_uint8(payload, 1); // Pretend we're a proxy here to prevent the server from updating the atime TODO: Update status on server switch
+ serializer_put_uint16(payload, PROTOCOL_VERSION); // DNBD3 protocol version
+ serializer_put_string(payload, dev->imgname); // image name
+ serializer_put_uint16(payload, dev->rid); // revision id
+ serializer_put_uint8(payload, 0); // are we a server? (no!)
iov[1].iov_base = payload;
dnbd3_request.size = iov[1].iov_len = serializer_get_written_length(payload);
fixup_request(dnbd3_request);
@@ -604,6 +611,7 @@ int dnbd3_net_discover(void *data)
// panic mode, take first responding server
if (dev->panic)
{
+ dev->panic = 0;
debug_alt("WARN: Panic mode, changing server:");
if (best_sock != NULL) sock_release(best_sock);
dev->better_sock = sock; // Pass over socket to take a shortcut in *_connect();
@@ -717,7 +725,7 @@ error:
dnbd3_blk_fail_all_requests(dev);
}
- if (best_server == -1 || kthread_should_stop()) // No alt server could be reached at all or thread should stop
+ if (best_server == -1 || kthread_should_stop() || dev->thread_discover == NULL) // No alt server could be reached at all or thread should stop
{
if (best_sock != NULL) // Should never happen actually
{
diff --git a/src/server/locks.c b/src/server/locks.c
index 050fa4e..9e8d4ad 100644
--- a/src/server/locks.c
+++ b/src/server/locks.c
@@ -205,32 +205,45 @@ void debug_dump_lock_stats()
static void *debug_thread_watchdog(void *something)
{
- while (!_shutdown) {
- time_t now = time(NULL);
- pthread_spin_lock( &initdestory );
- for (int i = 0; i < MAXTHREADS; ++i) {
- if ( threads[i].tid == 0 ) continue;
- const int diff = now - threads[i].time;
- if ( diff > 6 && diff < 100000 ) {
- printf("\n\n +++++++++ DEADLOCK ++++++++++++\n\n");
- pthread_spin_unlock( &initdestory );
- debug_dump_lock_stats();
- exit(99);
+ while ( !_shutdown ) {
+ if (init_done) {
+ time_t now = time( NULL );
+ pthread_spin_lock( &initdestory );
+ for (int i = 0; i < MAXTHREADS; ++i) {
+ if ( threads[i].tid == 0 ) continue;
+ const int diff = now - threads[i].time;
+ if ( diff > 6 && diff < 100000 ) {
+ printf( "\n\n +++++++++ DEADLOCK ++++++++++++\n\n" );
+ pthread_spin_unlock( &initdestory );
+ debug_dump_lock_stats();
+ exit( 99 );
+ }
}
+ pthread_spin_unlock( &initdestory );
}
- pthread_spin_unlock( &initdestory );
- sleep(10);
+ sleep( 10 );
}
- return NULL;
+ return NULL ;
}
+#endif
+
void debug_locks_start_watchdog()
{
+#ifdef _DEBUG
if ( 0 != pthread_create( &watchdog, NULL, &debug_thread_watchdog, (void *)NULL ) ) {
memlogf( "[ERROR] Could not start debug-lock watchdog." );
return;
}
- pthread_detach( watchdog );
+#endif
}
+void debug_locks_stop_watchdog()
+{
+#ifdef _DEBUG
+ _shutdown = TRUE;
+ pthread_spin_lock( &initdestory );
+ pthread_spin_unlock( &initdestory );
+ pthread_join( watchdog, NULL );
#endif
+}
diff --git a/src/server/locks.h b/src/server/locks.h
index 6558558..5d4367b 100644
--- a/src/server/locks.h
+++ b/src/server/locks.h
@@ -15,7 +15,6 @@ int debug_spin_lock(const char *name, const char *file, int line, pthread_spinlo
int debug_spin_unlock(const char *name, const char *file, int line, pthread_spinlock_t *lock);
int debug_spin_destroy(const char *name, const char *file, int line, pthread_spinlock_t *lock);
-void debug_locks_start_watchdog();
void debug_dump_lock_stats();
#else
@@ -27,4 +26,7 @@ void debug_dump_lock_stats();
#endif
+void debug_locks_start_watchdog();
+void debug_locks_stop_watchdog();
+
#endif /* LOCKS_H_ */
diff --git a/src/server/server.c b/src/server/server.c
index 38635c9..6e49eb0 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -96,6 +96,7 @@ void dnbd3_cleanup()
{
int i;
+ _shutdown = TRUE;
memlogf( "INFO: Cleanup...\n" );
for (int i = 0; i < socket_count; ++i) {
@@ -108,6 +109,7 @@ void dnbd3_cleanup()
// Clean up clients
spin_lock( &_clients_lock );
for (i = 0; i < _num_clients; ++i) {
+ if ( _clients[i] == NULL ) continue;
dnbd3_client_t * const client = _clients[i];
spin_lock( &client->lock );
if ( client->sock >= 0 ) shutdown( client->sock, SHUT_RDWR );
@@ -122,11 +124,14 @@ void dnbd3_cleanup()
// Clean up images
spin_lock( &_images_lock );
for (i = 0; i < _num_images; ++i) {
+ if ( _images[i] == NULL ) continue;
_images[i] = image_free( _images[i] );
}
_num_images = 0;
spin_unlock( &_images_lock );
+ debug_locks_stop_watchdog();
+
exit( EXIT_SUCCESS );
}
@@ -335,11 +340,11 @@ dnbd3_client_t* dnbd3_free_client(dnbd3_client_t *client)
{
spin_lock( &client->lock );
/*
- for (it = client->sendqueue; it; it = it->next) {
- free( it->data );
- }
- g_slist_free( client->sendqueue );
- */
+ for (it = client->sendqueue; it; it = it->next) {
+ free( it->data );
+ }
+ g_slist_free( client->sendqueue );
+ */
if ( client->sock >= 0 ) close( client->sock );
client->sock = -1;
if ( client->image != NULL ) image_release( client->image );