From 35ae7af4c8f541785699ad7ca1ad64d2413a88ec Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 2 Jan 2015 15:06:58 +0100 Subject: [SERVER] Dead code removal, minor performance tweaks, refactoring, etc. --- src/server/helper.h | 50 -------------------------------------------------- src/server/image.c | 4 ++-- src/server/locks.c | 18 +++++++++--------- src/server/net.c | 24 ++++-------------------- src/server/uplink.c | 27 +++++++++------------------ 5 files changed, 24 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/server/helper.h b/src/server/helper.h index 0ecbdfd..7c962d7 100644 --- a/src/server/helper.h +++ b/src/server/helper.h @@ -29,56 +29,6 @@ static inline bool isSameAddressPort(const dnbd3_host_t * const a, const dnbd3_h return (a->type == b->type) && (a->port == b->port) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); } -/** - * Send message to client. - * @return true on success, false on failure - */ -static inline int send_data(int client_sock, void *data_in, int len) -{ - if ( len <= 0 ) return true; // Nothing to send - char *data = data_in; // Needed for pointer arithmetic - int ret, i; - for (i = 0; i < 3; ++i) // Retry at most 3 times, each try takes at most 0.5 seconds (socket timeout) - { - ret = send( client_sock, data, len, 0 ); - if ( ret == 0 ) return false; // Connection closed - if ( ret < 0 ) { - if ( errno != EAGAIN ) return false; // Some unexpected error - usleep( 1000 ); // 1ms - continue; - } - len -= ret; - if ( len <= 0 ) return true; // Sent everything - data += ret; // move target buffer pointer - } - return false; -} - -/** - * Receive data from client. - * @return true on success, false otherwise - */ -static inline bool recv_data(int client_sock, void *buffer_out, int len) -{ - if ( len <= 0 ) return true; // Nothing to receive - char *data = buffer_out; // Needed for pointer arithmetic - int ret, i; - for (i = 0; i < 3; ++i) // Retry at most 3 times, each try takes at most 0.5 seconds (socket timeout) - { - ret = recv( client_sock, data, len, MSG_WAITALL ); - if ( ret == 0 ) return false; // Connection closed - if ( ret < 0 ) { - if ( errno != EAGAIN ) return false; // Some unexpected error - usleep( 1000 ); // 1ms - continue; - } - len -= ret; - if ( len <= 0 ) return true; // Received everything - data += ret; // move target buffer pointer - } - return false; -} - /** * Test whether string ends in suffix. * @return true if string =~ /suffix$/ diff --git a/src/server/image.c b/src/server/image.c index e6a763b..ae7b942 100644 --- a/src/server/image.c +++ b/src/server/image.c @@ -212,9 +212,9 @@ bool image_saveCacheMap(dnbd3_image_t *image) write( fd, map, size ); if ( image->cacheFd != -1 ) { - fsync( image->cacheFd ); + fdatasync( image->cacheFd ); } - fsync( fd ); + fdatasync( fd ); close( fd ); free( map ); diff --git a/src/server/locks.c b/src/server/locks.c index 48f67a9..d779e6f 100644 --- a/src/server/locks.c +++ b/src/server/locks.c @@ -66,7 +66,7 @@ int debug_spin_init(const char *name, const char *file, int line, pthread_spinlo pthread_spin_lock( &initdestory ); for (int i = 0; i < MAXLOCKS; ++i) { if ( locks[i].lock == lock ) { - printf( "[ERROR] Lock %p (%s) already initialized (%s:%d)\n", lock, name, file, line ); + printf( "[ERROR] Lock %p (%s) already initialized (%s:%d)\n", (void*)lock, name, file, line ); exit( 4 ); } if ( first == -1 && locks[i].lock == NULL ) first = i; @@ -97,7 +97,7 @@ int debug_spin_lock(const char *name, const char *file, int line, pthread_spinlo } pthread_spin_unlock( &initdestory ); if ( l == NULL ) { - printf( "[ERROR] Tried to lock uninitialized lock %p (%s) at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Tried to lock uninitialized lock %p (%s) at %s:%d\n", (void*)lock, name, file, line ); debug_dump_lock_stats(); exit( 4 ); } @@ -119,7 +119,7 @@ int debug_spin_lock(const char *name, const char *file, int line, pthread_spinlo t->time = 0; pthread_spin_unlock( &initdestory ); if ( l->locked ) { - printf( "[ERROR] Lock sanity check: lock %p (%s) already locked at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Lock sanity check: lock %p (%s) already locked at %s:%d\n", (void*)lock, name, file, line ); exit( 4 ); } l->locked = 1; @@ -144,7 +144,7 @@ int debug_spin_trylock(const char *name, const char *file, int line, pthread_spi } pthread_spin_unlock( &initdestory ); if ( l == NULL ) { - printf( "[ERROR] Tried to lock uninitialized lock %p (%s) at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Tried to lock uninitialized lock %p (%s) at %s:%d\n", (void*)lock, name, file, line ); debug_dump_lock_stats(); exit( 4 ); } @@ -167,7 +167,7 @@ int debug_spin_trylock(const char *name, const char *file, int line, pthread_spi pthread_spin_unlock( &initdestory ); if ( retval == 0 ) { if ( l->locked ) { - printf( "[ERROR] Lock sanity check: lock %p (%s) already locked at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Lock sanity check: lock %p (%s) already locked at %s:%d\n", (void*)lock, name, file, line ); exit( 4 ); } l->locked = 1; @@ -193,11 +193,11 @@ int debug_spin_unlock(const char *name, const char *file, int line, pthread_spin } pthread_spin_unlock( &initdestory ); if ( l == NULL ) { - printf( "[ERROR] Tried to unlock uninitialized lock %p (%s) at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Tried to unlock uninitialized lock %p (%s) at %s:%d\n", (void*)lock, name, file, line ); exit( 4 ); } if ( !l->locked ) { - printf( "[ERROR] Unlock sanity check: lock %p (%s) not locked at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Unlock sanity check: lock %p (%s) not locked at %s:%d\n", (void*)lock, name, file, line ); exit( 4 ); } l->locked = 0; @@ -214,7 +214,7 @@ int debug_spin_destroy(const char *name, const char *file, int line, pthread_spi for (int i = 0; i < MAXLOCKS; ++i) { if ( locks[i].lock == lock ) { if ( locks[i].locked ) { - printf( "[ERROR] Tried to destroy lock %p (%s) at %s:%d when it is still locked\n", lock, name, file, line ); + printf( "[ERROR] Tried to destroy lock %p (%s) at %s:%d when it is still locked\n", (void*)lock, name, file, line ); exit( 4 ); } locks[i].lock = NULL; @@ -223,7 +223,7 @@ int debug_spin_destroy(const char *name, const char *file, int line, pthread_spi return pthread_spin_destroy( lock ); } } - printf( "[ERROR] Tried to destroy non-existent lock %p (%s) at %s:%d\n", lock, name, file, line ); + printf( "[ERROR] Tried to destroy non-existent lock %p (%s) at %s:%d\n", (void*)lock, name, file, line ); exit( 4 ); } diff --git a/src/server/net.c b/src/server/net.c index 3dc1f63..8e5189f 100644 --- a/src/server/net.c +++ b/src/server/net.c @@ -50,10 +50,10 @@ static inline bool recv_request_header(int sock, dnbd3_request_t *request) int ret, fails = 0; // Read request header from socket while ( (ret = recv( sock, request, sizeof(*request), MSG_WAITALL )) != sizeof(*request) ) { + if ( errno == EINTR ) continue; if ( ret >= 0 || ++fails > SOCKET_TIMEOUT_SERVER_RETRIES ) return false; - const int err = errno; - if ( err == EAGAIN || err == EINTR ) continue; - printf( "[DEBUG] Error receiving request: Could not read message header (%d/%d, e=%d)\n", ret, (int)sizeof(*request), err ); + if ( errno == EAGAIN ) continue; + printf( "[DEBUG] Error receiving request: Could not read message header (%d/%d, e=%d)\n", ret, (int)sizeof(*request), errno ); return false; } // Make sure all bytes are in the right order (endianness) @@ -98,7 +98,7 @@ static inline bool send_reply(int sock, dnbd3_reply_t *reply, void *payload) const unsigned int size = reply->size; fixup_reply( *reply ); if ( !payload || size == 0 ) { - if ( send( sock, reply, sizeof(dnbd3_reply_t), MSG_WAITALL ) != sizeof(dnbd3_reply_t) ) { + if ( send( sock, reply, sizeof(dnbd3_reply_t), 0 ) != sizeof(dnbd3_reply_t) ) { printf( "[DEBUG] Send failed (header-only)\n" ); return false; } @@ -354,22 +354,6 @@ void *net_client_handler(void *dnbd3_client) break; } - - /* - // Check for messages that have been queued from another thread - while ( client->sendqueue != NULL ) { - dnbd3_binstring_t *message = NULL; - spin_lock( &client->lock ); - if ( client->sendqueue != NULL ) { - message = client->sendqueue->data; - client->sendqueue = g_slist_remove( client->sendqueue, message ); - } - spin_unlock( &client->lock ); - send_data( client->sock, message->data, message->len ); - free( message ); - } - */ - } } exit_client_cleanup: ; diff --git a/src/server/uplink.c b/src/server/uplink.c index 6c00bbf..5819ed1 100644 --- a/src/server/uplink.c +++ b/src/server/uplink.c @@ -459,9 +459,8 @@ static void uplink_sendReplicationRequest(dnbd3_connection_t *link) spin_unlock( &image->lock ); return; } - dnbd3_request_t request; - request.magic = dnbd3_packet_magic; const size_t len = IMGSIZE_TO_MAPBYTES( image->filesize ) - 1; + const uint32_t requestBlockSize = DNBD3_BLOCK_SIZE * 8; for (int i = 0; i <= len; ++i) { if ( image->cache_map == NULL || link->fd == -1 ) break; if ( image->cache_map[i] == 0xff || (i == len && link->replicatedLastBlock) ) continue; @@ -469,16 +468,10 @@ static void uplink_sendReplicationRequest(dnbd3_connection_t *link) link->replicationHandle = 1; // Prevent race condition spin_unlock( &image->lock ); // Unlocked - do not break or continue here... - request.cmd = CMD_GET_BLOCK; // Needs to be 8 (bit->byte, bitmap) - link->replicationHandle = request.offset = request.handle = (uint64_t)i * DNBD3_BLOCK_SIZE * (uint64_t)8; - request.size = DNBD3_BLOCK_SIZE * (uint64_t)8; - if ( request.offset + request.size > image->filesize ) { - request.size = image->filesize - request.offset; - } - fixup_request( request ); - const int ret = send( link->fd, &request, sizeof request, MSG_NOSIGNAL ); - if ( ret != sizeof(request) ) { + const uint64_t offset = link->replicationHandle = (uint64_t)i * DNBD3_BLOCK_SIZE * (uint64_t)requestBlockSize; + const uint32_t size = MIN( image->filesize - offset, requestBlockSize ); + if ( !dnbd3_get_block( link->fd, offset, size, link->replicationHandle ) ) { printf( "[DEBUG] Error sending background replication request to uplink server!\n" ); return; } @@ -541,18 +534,16 @@ static void uplink_handleReceive(dnbd3_connection_t *link) // Bail out if we're not interested if ( inReply.cmd != CMD_GET_BLOCK ) continue; // Is a legit block reply + struct iovec iov[2]; const uint64_t start = inReply.handle; const uint64_t end = inReply.handle + inReply.size; // 1) Write to cache file assert( link->image->cacheFd != -1 ); - if ( lseek( link->image->cacheFd, start, SEEK_SET ) != start ) { - memlogf( "[ERROR] lseek() failed when writing to cache for %s", link->image->path ); - } else { - ret = (int)write( link->image->cacheFd, link->recvBuffer, inReply.size ); - if ( ret > 0 ) image_updateCachemap( link->image, start, start + ret, true ); - } + iov[0].iov_base = link->recvBuffer; + iov[0].iov_len = inReply.size; + ret = (int)pwritev( link->image->cacheFd, iov, 1, start ); + if ( ret > 0 ) image_updateCachemap( link->image, start, start + ret, true ); // 2) Figure out which clients are interested in it - struct iovec iov[2]; spin_lock( &link->queueLock ); for (i = 0; i < link->queueLen; ++i) { dnbd3_queued_request_t * const req = &link->queue[i]; -- cgit v1.2.3-55-g7522