summaryrefslogtreecommitdiffstats
path: root/src/server/altservers.c
diff options
context:
space:
mode:
authorSimon Rettberg2013-08-15 20:49:06 +0200
committerSimon Rettberg2013-08-15 20:49:06 +0200
commit4209bbef4b1e1b6a6af28407552c8518f3f72125 (patch)
tree90b159c9355c5ae47494bccc08cfa41ae96cfd40 /src/server/altservers.c
parent[SERVER] Remove dead code (diff)
downloaddnbd3-4209bbef4b1e1b6a6af28407552c8518f3f72125.tar.gz
dnbd3-4209bbef4b1e1b6a6af28407552c8518f3f72125.tar.xz
dnbd3-4209bbef4b1e1b6a6af28407552c8518f3f72125.zip
[SERVER] (Hopefully) fix starving uplink requests
Diffstat (limited to 'src/server/altservers.c')
-rw-r--r--src/server/altservers.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/server/altservers.c b/src/server/altservers.c
index a98bedc..da41857 100644
--- a/src/server/altservers.c
+++ b/src/server/altservers.c
@@ -108,6 +108,7 @@ int altservers_add(dnbd3_host_t *host, const char *comment)
void altserver_find_uplink(dnbd3_connection_t *uplink)
{
int i;
+ assert( uplink->betterFd == -1 );
spin_lock( &pendingLock );
if ( uplink->rttTestResult == RTT_INPROGRESS ) {
for (i = 0; i < SERVER_MAX_PENDING_ALT_CHECKS; ++i) {
@@ -382,16 +383,18 @@ static void *altserver_main(void *data)
iov[0].iov_len = sizeof(request);
iov[1].iov_base = &serialized;
iov[1].iov_len = len;
- if ( writev( sock, iov, 2 ) != len + sizeof(request) ) goto server_failed;
+ if ( writev( sock, iov, 2 ) != len + sizeof(request) ) {
+ goto server_failed;
+ }
// See if selecting the image succeeded ++++++++++++++++++++++++++++++
if ( recv( sock, &reply, sizeof(reply), MSG_WAITALL ) != sizeof(reply) ) {
- //ERROR_GOTO_VA( server_failed, "[ERROR] Received corrupted reply header after CMD_SELECT_IMAGE (%s)",
- // uplink->image->lower_name );
goto server_failed;
}
// check reply header
fixup_reply( reply );
- if ( reply.cmd != CMD_SELECT_IMAGE || reply.size < 3 || reply.size > MAX_PAYLOAD || reply.magic != dnbd3_packet_magic ) goto server_failed;
+ if ( reply.cmd != CMD_SELECT_IMAGE || reply.size < 3 || reply.size > MAX_PAYLOAD || reply.magic != dnbd3_packet_magic ) {
+ goto server_failed;
+ }
// Not found
// receive reply payload
if ( recv( sock, &serialized, reply.size, MSG_WAITALL ) != reply.size ) {
@@ -402,19 +405,22 @@ static void *altserver_main(void *data)
const uint16_t protocol_version = serializer_get_uint16( &serialized );
if ( protocol_version < MIN_SUPPORTED_SERVER ) goto server_failed;
const char *name = serializer_get_string( &serialized );
- if ( strcmp( name, uplink->image->lower_name ) != 0 ) {
+ if ( name == NULL || strcmp( name, uplink->image->lower_name ) != 0 ) {
ERROR_GOTO_VA( server_failed, "[ERROR] Server offers image '%s', requested '%s'", name, uplink->image->lower_name );
}
const uint16_t rid = serializer_get_uint16( &serialized );
- if ( rid != uplink->image->rid ) ERROR_GOTO_VA( server_failed, "[ERROR] Server provides rid %d, requested was %d (%s)",
- (int)rid, (int)uplink->image->rid, uplink->image->lower_name );
+ if ( rid != uplink->image->rid ) {
+ ERROR_GOTO_VA( server_failed, "[ERROR] Server provides rid %d, requested was %d (%s)",
+ (int)rid, (int)uplink->image->rid, uplink->image->lower_name );
+ }
const uint64_t image_size = serializer_get_uint64( &serialized );
- if ( image_size != uplink->image->filesize ) ERROR_GOTO_VA( server_failed,
- "[ERROR] Remote size: %" PRIu64 ", expected: %" PRIu64 " (%s)",
- image_size, uplink->image->filesize, uplink->image->lower_name );
+ if ( image_size != uplink->image->filesize ) {
+ ERROR_GOTO_VA( server_failed, "[ERROR] Remote size: %" PRIu64 ", expected: %" PRIu64 " (%s)",
+ image_size, uplink->image->filesize, uplink->image->lower_name );
+ }
// Request random block ++++++++++++++++++++++++++++++
request.cmd = CMD_GET_BLOCK;
- request.offset = (uplink->image->filesize - 1) & ~(DNBD3_BLOCK_SIZE - 1);
+ request.offset = (((uint64_t)start.tv_nsec | (uint64_t)rand()) * DNBD3_BLOCK_SIZE ) % uplink->image->filesize;
request.size = DNBD3_BLOCK_SIZE;
fixup_request( request );
if ( send( sock, &request, sizeof(request), 0 ) != sizeof(request) ) ERROR_GOTO_VA( server_failed,
@@ -429,10 +435,13 @@ static void *altserver_main(void *data)
}
// check reply header
fixup_reply( reply );
- if ( reply.cmd != CMD_GET_BLOCK || reply.size != DNBD3_BLOCK_SIZE ) ERROR_GOTO_VA( server_failed,
- "[ERROR] Reply to random block request is %d bytes for %s", reply.size, uplink->image->lower_name );
- if ( recv( sock, buffer, DNBD3_BLOCK_SIZE, MSG_WAITALL ) != DNBD3_BLOCK_SIZE ) ERROR_GOTO_VA( server_failed,
- "[ERROR] Could not read random block from socket for %s", uplink->image->lower_name );
+ if ( reply.cmd != CMD_GET_BLOCK || reply.size != DNBD3_BLOCK_SIZE ) {
+ ERROR_GOTO_VA( server_failed, "[ERROR] Reply to random block request is %d bytes for %s",
+ reply.size, uplink->image->lower_name );
+ }
+ if ( recv( sock, buffer, DNBD3_BLOCK_SIZE, MSG_WAITALL ) != DNBD3_BLOCK_SIZE ) {
+ ERROR_GOTO_VA( server_failed, "[ERROR] Could not read random block from socket for %s", uplink->image->lower_name );
+ }
clock_gettime( CLOCK_MONOTONIC_RAW, &end );
// Measurement done - everything fine so far
const unsigned int rtt = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; // µs