summaryrefslogtreecommitdiffstats
path: root/src/server/image.c
diff options
context:
space:
mode:
authorSimon Rettberg2013-09-16 19:08:49 +0200
committerSimon Rettberg2013-09-16 19:08:49 +0200
commita0c5086ff2dc9e2b238d9800e1c97236ed545098 (patch)
treee5a720b153166281e2474d283e7e27d4eb20c4f7 /src/server/image.c
parentI'm stupid #62 (diff)
downloaddnbd3-a0c5086ff2dc9e2b238d9800e1c97236ed545098.tar.gz
dnbd3-a0c5086ff2dc9e2b238d9800e1c97236ed545098.tar.xz
dnbd3-a0c5086ff2dc9e2b238d9800e1c97236ed545098.zip
[SERVER] More debugging, more safety checks, disable alt servers that fail too often
Diffstat (limited to 'src/server/image.c')
-rw-r--r--src/server/image.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/server/image.c b/src/server/image.c
index b47be48..13e2e5b 100644
--- a/src/server/image.c
+++ b/src/server/image.c
@@ -142,7 +142,7 @@ void image_updateCachemap(dnbd3_image_t *image, uint64_t start, uint64_t end, co
/**
* Mark image as complete by freeing the cache_map and deleting the map file on disk
- * DOES NOT LOCK ON THE IMAGE
+ * DOES NOT LOCK ON THE IMAGE, DO SO BEFORE CALLING
*/
void image_markComplete(dnbd3_image_t *image)
{
@@ -235,6 +235,7 @@ dnbd3_image_t* image_get(char *name, uint16_t revision)
}
}
+ // Not found
if ( candidate == NULL ) {
spin_unlock( &_images_lock );
return NULL ;
@@ -254,6 +255,11 @@ dnbd3_image_t* image_get(char *name, uint16_t revision)
} else if ( !candidate->working && candidate->cache_map != NULL && candidate->uplink == NULL && file_isWritable( candidate->path ) ) {
// Not working and has file + cache-map, try to init uplink (uplink_init will check if proxy mode is enabled)
uplink_init( candidate, -1, NULL );
+ } else if ( candidate->working && candidate->uplink != NULL && candidate->uplink->queueLen > SERVER_UPLINK_QUEUELEN_THRES ) {
+ // To many pending uplink requests. We take that as a hint that the uplink is clogged or no working uplink server
+ // exists, so "working" is changed to FALSE for now. Should a new uplink server be found the uplink thread will
+ // set this back to TRUE some time.
+ candidate->working = FALSE;
}
return candidate; // Success :-)
}
@@ -1021,6 +1027,51 @@ int image_generateCrcFile(char *image)
return TRUE;
}
+void image_printAll()
+{
+ int i, percent, pending;
+ char buffer[100] = { 0 };
+ spin_lock( &_images_lock );
+ for (i = 0; i < _num_images; ++i) {
+ if ( _images[i] == NULL ) continue;
+ spin_lock( &_images[i]->lock );
+ printf( "Image: %s\n", _images[i]->lower_name );
+ percent = image_getCompletenessEstimate( _images[i] );
+ printf( " Complete: %d%%\n", percent );
+ if ( _images[i]->uplink != NULL ) {
+ host_to_string( &_images[i]->uplink->currentServer, buffer, sizeof(buffer) );
+ pending = _images[i]->uplink->queueLen;
+ printf( " Uplink: %s -- %d pending requests\n", buffer, pending );
+ }
+ printf( " Users: %d\n", _images[i]->users );
+ spin_unlock( &_images[i]->lock );
+ }
+ spin_unlock( &_images_lock );
+}
+
+/**
+ * Get completeness of an image in percent. Only estimated, not exact.
+ * Returns: 0-100
+ * DOES NOT LOCK, so make sure to do so before calling
+ */
+int image_getCompletenessEstimate(const dnbd3_image_t * const image)
+{
+ assert( image != NULL );
+ if ( image->cache_map == NULL ) return image->working ? 100 : 0;
+ int i;
+ int percent = 0;
+ const size_t len = IMGSIZE_TO_MAPBYTES(image->filesize);
+ if ( len == 0 ) return 0;
+ for (i = 0; i < len; ++i) {
+ if ( image->cache_map[i] == 0xff ) {
+ percent += 100;
+ } else if ( image->cache_map[i] > 0 ) {
+ percent += 50;
+ }
+ }
+ return percent / len;
+}
+
/**
* Check the CRC-32 of the given blocks. The array blocks is of variable length.
* !! pass -1 as the last block so the function knows when to stop !!