diff options
author | Michael Scherle | 2022-06-07 20:14:54 +0200 |
---|---|---|
committer | Michael Scherle | 2022-06-07 20:14:54 +0200 |
commit | 7f7a532fedfabc87f00d9bc53c42f09a443c1e75 (patch) | |
tree | 2e4d6a8172c6f1ae87972899076c125430d91bde | |
parent | added parallel file upload (diff) | |
download | dnbd3-7f7a532fedfabc87f00d9bc53c42f09a443c1e75.tar.gz dnbd3-7f7a532fedfabc87f00d9bc53c42f09a443c1e75.tar.xz dnbd3-7f7a532fedfabc87f00d9bc53c42f09a443c1e75.zip |
fixed multiple compiler warnings
-rw-r--r-- | inc/dnbd3/config.h | 2 | ||||
-rw-r--r-- | src/cowtest/main.c | 61 | ||||
-rw-r--r-- | src/fuse/connection.c | 4 | ||||
-rw-r--r-- | src/fuse/cowfile.c | 256 | ||||
-rw-r--r-- | src/fuse/cowfile.h | 8 | ||||
-rw-r--r-- | src/fuse/main.c | 8 |
6 files changed, 199 insertions, 140 deletions
diff --git a/inc/dnbd3/config.h b/inc/dnbd3/config.h index 3caa7af..0b0ee24 100644 --- a/inc/dnbd3/config.h +++ b/inc/dnbd3/config.h @@ -50,7 +50,7 @@ #define COW_URL_STRING_SIZE 500 // Max string size for an url // +++++ COW API Endpoints +++++ #define COW_API_CREATE "%s/api/File/Create" -#define COW_API_UPDATE "%s/api/File/Update?guid=%s&BlockNumber=%u" +#define COW_API_UPDATE "%s/api/File/Update?guid=%s&BlockNumber=%lu" #define COW_API_START_MERGE "%s/api/File/StartMerge" #endif /* CONFIG_H_ */ diff --git a/src/cowtest/main.c b/src/cowtest/main.c index e9f7e4c..80620b4 100644 --- a/src/cowtest/main.c +++ b/src/cowtest/main.c @@ -25,7 +25,7 @@ const size_t l2Size = 1024; const size_t bitfieldByteSize = 40; const size_t l2Capacity = l2Size * DNBD3_BLOCK_SIZE * bitfieldByteSize * 8; -const size_t testFileSize = l2Size * bitfieldByteSize * DNBD3_BLOCK_SIZE * 8L * 2.9L; +const size_t testFileSize = l2Capacity * 2.9L; static char filePath[400]; @@ -244,6 +244,56 @@ bool writeNotOnBlockBorder() return verifyWriteNotOnBlockBorder(); } +bool verifyLongNonAlignedPattern() +{ + int size = DNBD3_BLOCK_SIZE * 10; + char buffer[size]; + char expected[size]; + for ( int i = 0; i < size; i++ ) { + expected[i] = (char)( i % 255 ); + } + + off_t offset = l2Capacity * 3 - 1; + size_t totalSize = l2Capacity + 2; + off_t endOffset = offset + totalSize; + + while ( offset < endOffset ) { + size_t sizeToRead = MIN( size, endOffset - offset ); + if ( !readSizeTested( fh, buffer, sizeToRead, offset, "writeLongNonAlignedPattern test Failed: read failed" ) ) { + return false; + } + if ( !compare( buffer, expected, sizeToRead, "writeLongNonAlignedPattern test Failed: read failed" ) ) + return false; + offset += sizeToRead; + } + printf( "LongNonAlignedPattern successful!\n" ); + return true; +} + +bool writeLongNonAlignedPattern() +{ + int size = DNBD3_BLOCK_SIZE * 10; + char buffer[size]; + + for ( int i = 0; i < size; i++ ) { + buffer[i] = (char)( i % 255 ); + } + + off_t offset = l2Capacity * 3 - 1; + size_t totalSize = l2Capacity + 2; + off_t endOffset = offset + totalSize; + + while ( offset < endOffset ) { + size_t sizeToWrite = MIN( size, endOffset - offset ); + if ( !writeSizeTested( + fh, buffer, sizeToWrite, offset, "writeLongNonAlignedPattern test Failed: write failed" ) ) { + return false; + } + offset += sizeToWrite; + } + return verifyLongNonAlignedPattern(); +} + bool fileSizeChanges() { @@ -405,6 +455,9 @@ void runTest( char *path ) return; if ( !interleavedTest() ) return; + if ( !writeLongNonAlignedPattern() ) { + return; + } printf( "All test's successful.\n" ); } @@ -420,6 +473,7 @@ void verifyTests( verify_test_t *tests ) verifyWriteNotOnBlockBorder }; tests[3] = ( verify_test_t ){ 35 * DNBD3_BLOCK_SIZE, DNBD3_BLOCK_SIZE * 10, verifyInterleavedTest }; tests[4] = ( verify_test_t ){ l2Capacity * 2 - DNBD3_BLOCK_SIZE, DNBD3_BLOCK_SIZE * 2, verifyWriteOverL2 }; + tests[5] = ( verify_test_t ){ l2Capacity * 3 - 1, l2Capacity + 2, verifyLongNonAlignedPattern }; } void verifyFinalFile( char *path ) @@ -449,16 +503,15 @@ void verifyFinalFile( char *path ) size_t offset = 0; - int numberOfTests = 5; + int numberOfTests = 6; verify_test_t tests[numberOfTests]; verifyTests( tests ); int currentTest = 0; - while ( offset < fileSize ) { - size_t sizeToRead = MIN( maxReadSize, fileSize - offset ); + size_t sizeToRead = MIN( (size_t)maxReadSize, fileSize - offset ); if ( currentTest < numberOfTests ) { sizeToRead = MIN( sizeToRead, tests[currentTest].offset - offset ); } diff --git a/src/fuse/connection.c b/src/fuse/connection.c index 5a3c93b..2619d96 100644 --- a/src/fuse/connection.c +++ b/src/fuse/connection.c @@ -725,8 +725,8 @@ static void probeAltServers() goto fail; } // Success, reply to fuse - if(useCow){ - cowFile_handleCallback(request); + if( useCow ) { + cowFile_handleCallback( request ); } else { fuse_reply_buf( request->fuse_req, request->buffer, request->length ); diff --git a/src/fuse/cowfile.c b/src/fuse/cowfile.c index 6c23f28..8fe9e4c 100644 --- a/src/fuse/cowfile.c +++ b/src/fuse/cowfile.c @@ -3,6 +3,7 @@ extern void image_ll_getattr( fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi ); static int cowFileVersion = 1; +static int foreground; static pthread_t tidCowUploader; static char *cowServerAddress; static CURL *curl; @@ -10,7 +11,7 @@ static cowfile_metadata_header_t *metadata = NULL; atomic_bool uploadLoop = true; //both variables are only relevant for the upload after the image is dismounted -static uint32_t blocksForCompleteUpload = 0; +static uint32_t blocksForCompleteUpload = 0; static uint32_t blocksUploaded = 0; static struct cow @@ -57,7 +58,7 @@ static int getL2Offset( size_t offset ) */ static int getBitfieldOffset( size_t offset ) { - return (int)( offset / DNBD3_BLOCK_SIZE ) % (COW_BITFIELD_SIZE * 8); + return (int)( offset / DNBD3_BLOCK_SIZE ) % ( COW_BITFIELD_SIZE * 8 ); } /** @@ -69,7 +70,7 @@ static int getBitfieldOffset( size_t offset ) */ static void setBits( atomic_char *byte, int from, int to ) { - char mask = (char)( 255 >> ( 7 - ( to - from ) ) ) << from; + char mask = (char)( ( 255 >> ( 7 - ( to - from ) ) ) << from ); atomic_fetch_or( byte, ( *byte | mask ) ); } @@ -126,7 +127,7 @@ bool createSession( const char *imageName, uint16_t version ) { CURLcode res; char url[COW_URL_STRING_SIZE]; - snprintf ( url, COW_URL_STRING_SIZE, COW_API_CREATE, cowServerAddress ); + snprintf( url, COW_URL_STRING_SIZE, COW_API_CREATE, cowServerAddress ); logadd( LOG_INFO, "COW_API_CREATE URL: %s", url ); curl_easy_setopt( curl, CURLOPT_POST, 1L ); curl_easy_setopt( curl, CURLOPT_URL, url ); @@ -215,12 +216,12 @@ size_t curlReadCallbackUploadBlock( char *ptr, size_t size, size_t nmemb, void * len += lenCpy; } if ( uploadBlock->position >= (size_t)metadata->bitfieldSize ) { - size_t lenRead = MIN( COW_METADATA_STORAGE_CAPACITY - ( uploadBlock->position - ( metadata->bitfieldSize ) ), + size_t lenRead = MIN( COW_METADATA_STORAGE_CAPACITY - ( uploadBlock->position - ( metadata->bitfieldSize ) ), ( size * nmemb ) - len ); off_t inBlockOffset = uploadBlock->position - metadata->bitfieldSize; size_t lengthRead = pread( cow.fhd, ( ptr + len ), lenRead, uploadBlock->block->offset + inBlockOffset ); - if(lenRead != lengthRead){ + if ( lenRead != lengthRead ) { // temp fix, fill up non full blocks lengthRead = lenRead; } @@ -231,7 +232,6 @@ size_t curlReadCallbackUploadBlock( char *ptr, size_t size, size_t nmemb, void * } - /** * @brief requests the merging of the image on the cow server @@ -242,7 +242,7 @@ bool mergeRequest() curl_easy_setopt( curl, CURLOPT_POST, 1L ); char url[COW_URL_STRING_SIZE]; - snprintf( url, COW_URL_STRING_SIZE, COW_API_START_MERGE, cowServerAddress); + snprintf( url, COW_URL_STRING_SIZE, COW_API_START_MERGE, cowServerAddress ); curl_easy_setopt( curl, CURLOPT_URL, url ); @@ -250,14 +250,14 @@ bool mergeRequest() curl_mimepart *part; mime = curl_mime_init( curl ); part = curl_mime_addpart( mime ); - + curl_mime_name( part, "guid" ); curl_mime_data( part, metadata->uuid, CURL_ZERO_TERMINATED ); part = curl_mime_addpart( mime ); curl_mime_name( part, "fileSize" ); char buf[21]; - snprintf( buf, sizeof buf, "%" PRIu64, metadata->imageSize ); + snprintf( buf, sizeof buf, "%" PRIu64, metadata->imageSize ); curl_mime_data( part, buf, CURL_ZERO_TERMINATED ); curl_easy_setopt( curl, CURLOPT_MIMEPOST, mime ); @@ -295,17 +295,29 @@ void startMerge() } } -void updateCowStatsFile( uint blocks, uint totalBlocks, bool done ) { +void updateCowStatsFile( uint blocks, uint totalBlocks, bool done ) +{ char buffer[300]; - int len = snprintf( buffer, 100, "state: %s\nuploaded: %lu\ntotalBlocks: %lu\n", done?"done":"uploading" ,blocks, totalBlocks ); - pwrite( cow.fhs, buffer, len, 43 ); - ftruncate( cow.fhs, 43 + len ); -} + int len = snprintf( + buffer, 100, "state: %s\nuploaded: %u\ntotalBlocks: %u\n", done ? "done" : "uploading", blocks, totalBlocks ); + if ( foreground ) { + logadd( LOG_INFO, "%s", buffer ); + return; + } else { + if ( pwrite( cow.fhs, buffer, len, 43 ) != len ) { + logadd( LOG_WARNING, "Could not update cow status file" ); + } + } + if ( ftruncate( cow.fhs, 43 + len ) ) { + logadd( LOG_WARNING, "Could not truncate cow status file" ); + } +} -void addUpload( CURLM *cm, cow_curl_read_upload_t * curlUploadBlock ){ +bool addUpload( CURLM *cm, cow_curl_read_upload_t *curlUploadBlock ) +{ CURL *eh = curl_easy_init(); char url[COW_URL_STRING_SIZE]; @@ -323,25 +335,25 @@ void addUpload( CURLM *cm, cow_curl_read_upload_t * curlUploadBlock ){ struct curl_slist *headers = NULL; headers = curl_slist_append( headers, "Content-Type: application/octet-stream" ); curl_easy_setopt( eh, CURLOPT_HTTPHEADER, headers ); - curl_multi_add_handle(cm, eh); - + curl_multi_add_handle( cm, eh ); + return true; } -bool finishUpload( CURLM *cm, CURLMsg *msg ){ - /* Check for errors */ - +bool finishUpload( CURLM *cm, CURLMsg *msg ) +{ bool status = true; - cow_curl_read_upload_t * curlUploadBlock; + cow_curl_read_upload_t *curlUploadBlock; CURLcode res; - res = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &curlUploadBlock ); - if( res != CURLE_OK ) { + res = curl_easy_getinfo( msg->easy_handle, CURLINFO_PRIVATE, &curlUploadBlock ); + if ( res != CURLE_OK ) { logadd( LOG_ERROR, "ERROR" ); } - if( msg->msg != CURLMSG_DONE ) { - curlUploadBlock->fails ++; - logadd( LOG_ERROR, "COW_API_UPDATE failed %i/5: %s\n", curlUploadBlock->fails , curl_easy_strerror( msg->data.result ) ); - if( curlUploadBlock->fails <= 5 ) { + if ( msg->msg != CURLMSG_DONE ) { + curlUploadBlock->fails++; + logadd( LOG_ERROR, "COW_API_UPDATE failed %i/5: %s\n", curlUploadBlock->fails, + curl_easy_strerror( msg->data.result ) ); + if ( curlUploadBlock->fails <= 5 ) { addUpload( cm, curlUploadBlock ); goto CLEANUP; } @@ -349,18 +361,18 @@ bool finishUpload( CURLM *cm, CURLMsg *msg ){ status = false; goto CLEANUP; } - - + + ///////////////// TODO DEBUG REMOVE LATER double total; - res = curl_easy_getinfo(msg->easy_handle, CURLINFO_TOTAL_TIME, &total); - if(CURLE_OK == res) { + res = curl_easy_getinfo( msg->easy_handle, CURLINFO_TOTAL_TIME, &total ); + if ( CURLE_OK == res ) { curl_off_t ul; - res = curl_easy_getinfo(msg->easy_handle, CURLINFO_SIZE_UPLOAD_T, &ul); - if(CURLE_OK == res) { - logadd( LOG_INFO, "Speed: %f kb/s", (double) (((double)ul/total)/1000)); + res = curl_easy_getinfo( msg->easy_handle, CURLINFO_SIZE_UPLOAD_T, &ul ); + if ( CURLE_OK == res ) { + logadd( LOG_INFO, "Speed: %f kb/s", (double)( ( (double)ul / total ) / 1000 ) ); } - } + } //////////////////// @@ -373,35 +385,36 @@ bool finishUpload( CURLM *cm, CURLMsg *msg ){ } // everything went ok, update timeUploaded - curlUploadBlock->block->timeUploaded = ( atomic_uint_fast32_t )time; + curlUploadBlock->block->timeUploaded = (atomic_uint_fast32_t)time; blocksUploaded++; free( curlUploadBlock ); CLEANUP: curl_multi_remove_handle( cm, msg->easy_handle ); - curl_easy_cleanup(msg->easy_handle ); + curl_easy_cleanup( msg->easy_handle ); return status; } -bool MessageHandler(CURLM *cm, int * activeUploads, bool breakIfNotMax ) { +bool MessageHandler( CURLM *cm, int *activeUploads, bool breakIfNotMax ) +{ CURLMsg *msg; int msgsLeft = -1; bool status = true; do { - curl_multi_perform(cm, activeUploads); - - while((msg = curl_multi_info_read(cm, &msgsLeft))) { - if(!finishUpload( cm, msg )){ + curl_multi_perform( cm, activeUploads ); + + while ( ( msg = curl_multi_info_read( cm, &msgsLeft ) ) ) { + if ( !finishUpload( cm, msg ) ) { status = false; } } - if( breakIfNotMax && *activeUploads < COW_MAX_PARALLEL_UPLOADS ){ + if ( breakIfNotMax && *activeUploads < COW_MAX_PARALLEL_UPLOADS ) { break; } - if( *activeUploads ){ - curl_multi_wait(cm, NULL, 0, 1000, NULL); + if ( *activeUploads ) { + curl_multi_wait( cm, NULL, 0, 1000, NULL ); } - - } while( *activeUploads ); + + } while ( *activeUploads ); return status; } @@ -410,14 +423,13 @@ bool MessageHandler(CURLM *cm, int * activeUploads, bool breakIfNotMax ) { * * @param lastLoop if set to true, all blocks which are not uploaded will be uploaded, ignoring their timeChanged */ -bool uploaderLoop( bool lastLoop , CURLM *cm ) +bool uploaderLoop( bool lastLoop, CURLM *cm ) { bool success = true; int activeUploads = 0; - uint64_t lastUpdateTime = time( NULL ); - int l1MaxOffset = 1 + ((metadata->imageSize - 1) / COW_L2_STORAGE_CAPACITY); - int fails = 0; - for ( int l1Offset = 0; l1Offset < l1MaxOffset; l1Offset++ ) { + uint64_t lastUpdateTime = time( NULL ); + long unsigned int l1MaxOffset = 1 + ( ( metadata->imageSize - 1 ) / COW_L2_STORAGE_CAPACITY ); + for ( long unsigned int l1Offset = 0; l1Offset < l1MaxOffset; l1Offset++ ) { if ( cow.l1[l1Offset] == -1 ) { continue; } @@ -429,30 +441,29 @@ bool uploaderLoop( bool lastLoop , CURLM *cm ) if ( block->timeUploaded < block->timeChanged ) { uint32_t relativeTime = (uint32_t)( time( NULL ) - metadata->creationTime ); if ( ( ( relativeTime - block->timeChanged ) > COW_MIN_UPLOAD_DELAY ) || lastLoop ) { - do { - if( !MessageHandler(cm, &activeUploads, true ) ) { + if ( !MessageHandler( cm, &activeUploads, true ) ) { success = false; } - } while( !( activeUploads < COW_MAX_PARALLEL_UPLOADS ) && activeUploads ); - cow_curl_read_upload_t * b = malloc( sizeof(cow_curl_read_upload_t) ); + } while ( !( activeUploads < COW_MAX_PARALLEL_UPLOADS ) && activeUploads ); + cow_curl_read_upload_t *b = malloc( sizeof( cow_curl_read_upload_t ) ); b->block = block; b->blocknumber = ( l1Offset * COW_L2_SIZE + l2Offset ); b->fails = 0; b->position = 0; addUpload( cm, b ); - if( lastLoop ) { - if( time(NULL) - lastUpdateTime > COW_STATS_UPDATE_TIME ) { + if ( lastLoop ) { + if ( time( NULL ) - lastUpdateTime > COW_STATS_UPDATE_TIME ) { updateCowStatsFile( blocksUploaded, blocksForCompleteUpload, false ); - lastUpdateTime = time( NULL ); + lastUpdateTime = time( NULL ); } } } } } } - while( activeUploads > 0 ) { + while ( activeUploads > 0 ) { MessageHandler( cm, &activeUploads, false ); } return success; @@ -460,10 +471,11 @@ bool uploaderLoop( bool lastLoop , CURLM *cm ) /** Counts blocks that have changes that have not yet been uploaded */ -int countBlocksForUpload() { +int countBlocksForUpload() +{ int res = 0; - int l1MaxOffset = 1 + ((metadata->imageSize - 1) / COW_L2_STORAGE_CAPACITY); - for ( int l1Offset = 0; l1Offset < l1MaxOffset; l1Offset++ ) { + long unsigned int l1MaxOffset = 1 + ( ( metadata->imageSize - 1 ) / COW_L2_STORAGE_CAPACITY ); + for ( long unsigned int l1Offset = 0; l1Offset < l1MaxOffset; l1Offset++ ) { if ( cow.l1[l1Offset] == -1 ) { continue; } @@ -483,36 +495,60 @@ int countBlocksForUpload() { /** * @brief main loop for blockupload in the background */ -void cowfile_uploader( void *something ) +void *cowfile_uploader(__attribute__((unused)) void *something ) { - CURLM *cm; - cm = curl_multi_init(); - curl_multi_setopt( cm, CURLMOPT_MAXCONNECTS, (long) COW_MAX_PARALLEL_UPLOADS ); + cm = curl_multi_init(); + curl_multi_setopt( cm, CURLMOPT_MAXCONNECTS, (long)COW_MAX_PARALLEL_UPLOADS ); while ( uploadLoop ) { - uploaderLoop( false , cm ); + uploaderLoop( false, cm ); sleep( 2 ); } logadd( LOG_DEBUG1, "start uploading the remaining blocks." ); blocksForCompleteUpload = countBlocksForUpload(); - updateCowStatsFile( blocksUploaded,blocksForCompleteUpload , false ); + updateCowStatsFile( blocksUploaded, blocksForCompleteUpload, false ); // force the upload of all remaining blocks because the user dismounted the image if ( !uploaderLoop( true, cm ) ) { logadd( LOG_ERROR, "one or more blocks failed to upload" ); - curl_multi_cleanup( cm ); - return; + curl_multi_cleanup( cm ); + return NULL; } curl_multi_cleanup( cm ); - updateCowStatsFile( blocksUploaded,blocksForCompleteUpload , true ); + updateCowStatsFile( blocksUploaded, blocksForCompleteUpload, true ); logadd( LOG_DEBUG1, "all blocks uploaded" ); - if( cow_merge_after_upload ) { + if ( cow_merge_after_upload ) { startMerge(); logadd( LOG_DEBUG1, "Requesting merge." ); } + return NULL; +} + +bool createCowStatsFile( char *path ) +{ + char pathStatus[strlen( path ) + 12]; + + snprintf( pathStatus, strlen( path ) + 12, "%s%s", path, "/status.txt" ); + + char buffer[100]; + int len = snprintf( buffer, 100, "uuid: %s\nstate: active\n", metadata->uuid ); + if ( foreground ) { + logadd( LOG_INFO, "%s", buffer ); + return true; + } + if ( ( cow.fhs = open( pathStatus, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ) ) == -1 ) { + logadd( LOG_ERROR, "Could not create cow status file. Bye.\n" ); + return false; + } + + if ( pwrite( cow.fhs, buffer, len, 0 ) != len ) { + logadd( LOG_ERROR, "Could not write to cow status file. Bye.\n" ); + return false; + } + return true; } /** @@ -522,14 +558,15 @@ void cowfile_uploader( void *something ) * @param image_Name name of the original file/image * @param imageSizePtr */ -bool cowfile_init( - char *path, const char *image_Name, uint16_t imageVersion, size_t **imageSizePtr, char *serverAddress ) +bool cowfile_init( char *path, const char *image_Name, uint16_t imageVersion, atomic_uint_fast64_t **imageSizePtr, + char *serverAddress, int isForeground ) { + foreground = isForeground; char pathMeta[strlen( path ) + 6]; char pathData[strlen( path ) + 6]; - snprintf( pathMeta, strlen( path ) + 6, "%s%s", path, "/meta" ) ; - snprintf( pathData, strlen( path ) + 6, "%s%s", path, "/data" ) ; + snprintf( pathMeta, strlen( path ) + 6, "%s%s", path, "/meta" ); + snprintf( pathData, strlen( path ) + 6, "%s%s", path, "/data" ); if ( ( cow.fhm = open( pathMeta, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ) ) == -1 ) { logadd( LOG_ERROR, "Could not create cow meta file. Bye.\n %s \n", pathMeta ); @@ -627,14 +664,17 @@ bool cowfile_init( * @param imageSizePtr */ -bool cowfile_load( char *path, size_t **imageSizePtr, char *serverAddress ) +bool cowfile_load( char *path, atomic_uint_fast64_t **imageSizePtr, char *serverAddress, int isForeground ) { + foreground = isForeground; cowServerAddress = serverAddress; + curl_global_init( CURL_GLOBAL_ALL ); + curl = curl_easy_init(); char pathMeta[strlen( path ) + 6]; char pathData[strlen( path ) + 6]; - snprintf( pathMeta, strlen( path ) + 6, "%s%s", path, "/meta" ) ; - snprintf( pathData, strlen( path ) + 6, "%s%s", path, "/data" ) ; + snprintf( pathMeta, strlen( path ) + 6, "%s%s", path, "/meta" ); + snprintf( pathData, strlen( path ) + 6, "%s%s", path, "/data" ); if ( ( cow.fhm = open( pathMeta, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR ) ) == -1 ) { @@ -677,7 +717,10 @@ bool cowfile_load( char *path, size_t **imageSizePtr, char *serverAddress ) } { uint64_t magicValueDataFile; - pread( cow.fhd, &magicValueDataFile, sizeof( uint64_t ), 0 ); + if ( pread( cow.fhd, &magicValueDataFile, sizeof( uint64_t ), 0 ) != sizeof( uint64_t ) ) { + logadd( LOG_ERROR, "Error while reading cow data file, wrong file?. Bye.\n" ); + return false; + } if ( magicValueDataFile != COW_FILE_DATA_MAGIC_VALUE ) { if ( __builtin_bswap64( magicValueDataFile ) == COW_FILE_DATA_MAGIC_VALUE ) { @@ -715,10 +758,10 @@ bool cowfile_load( char *path, size_t **imageSizePtr, char *serverAddress ) cow.l1Size = ( ( cow.maxImageSize + COW_L2_STORAGE_CAPACITY - 1LL ) / COW_L2_STORAGE_CAPACITY ); cow.firstL2 = (l2 *)( ( (char *)cow.l1 ) + cow.l1Size ); - + pthread_mutex_init( &cow.l2CreateLock, NULL ); createCowStatsFile( path ); + pthread_create( &tidCowUploader, NULL, &cowfile_uploader, NULL ); - pthread_mutex_init( &cow.l2CreateLock, NULL ); return true; } @@ -850,12 +893,12 @@ static void writePaddedBlock( cow_sub_request_t *sRequest ) * @brief * */ -static void padBlockFromRemote( fuse_req_t req, off_t offset, cow_request_t *cowRequest, char *buffer, size_t size, +static void padBlockFromRemote( fuse_req_t req, off_t offset, cow_request_t *cowRequest, const char *buffer, size_t size, cow_block_metadata_t *block, off_t inBlockOffset ) { if ( offset > (off_t)metadata->originalImageSize ) { //pad 0 and done - //TODO + //TODO char buf[DNBD3_BLOCK_SIZE] = { 0 }; memcpy( buf, buffer, size ); @@ -961,7 +1004,7 @@ void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, siz && !checkBit( metaBlock->bitfield, (int)( inBlockOffset / DNBD3_BLOCK_SIZE ) ) ) { // write remote size_t padSize = MIN( sizeToWriteToBlock, DNBD3_BLOCK_SIZE - ( (size_t)currentOffset % DNBD3_BLOCK_SIZE ) ); - char *sbuf = cowRequest->writeBuffer + ( ( currentOffset - offset ) * !cowRequest->replyAttr ); + const char *sbuf = cowRequest->writeBuffer + ( ( currentOffset - offset ) * !cowRequest->replyAttr ); padBlockFromRemote( req, offset, cowRequest, sbuf, padSize, metaBlock, (off_t)inBlockOffset ); currentOffset += padSize; continue; @@ -973,7 +1016,7 @@ void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, siz off_t padStartOffset = currentEndOffset - ( currentEndOffset % 4096 ); off_t inBlockPadStartOffset = padStartOffset - metaBlockStartOffset; if ( !checkBit( metaBlock->bitfield, (int)( inBlockPadStartOffset / DNBD3_BLOCK_SIZE ) ) ) { - char *sbuf = cowRequest->writeBuffer + ( ( padStartOffset - offset ) * !cowRequest->replyAttr ); + const char *sbuf = cowRequest->writeBuffer + ( ( padStartOffset - offset ) * !cowRequest->replyAttr ); padBlockFromRemote( req, padStartOffset, cowRequest, sbuf, (currentEndOffset)-padStartOffset, metaBlock, inBlockPadStartOffset ); @@ -1065,7 +1108,6 @@ void cowfile_read( fuse_req_t req, size_t size, off_t offset ) off_t lastReadOffset = offset; off_t endOffset = offset + size; off_t searchOffset = offset; - off_t inBlockOffset; int l1Offset = getL1Offset( offset ); int l2Offset = getL2Offset( offset ); int bitfieldOffset = getBitfieldOffset( offset ); @@ -1157,42 +1199,6 @@ fail:; } -void createCowStatsFile( char* path ) { - char pathStatus[strlen( path ) + 12]; - - snprintf( pathStatus, strlen( path ) + 12, "%s%s", path, "/status.txt") ; - - if ( ( cow.fhs = open( pathStatus, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ) ) == -1 ) { - logadd( LOG_ERROR, "Could not create cow status file. Bye.\n" ); - return false; - } - char buffer[100]; - int len = snprintf( buffer, 100, "uuid: %s\nstate: active\n",metadata->uuid ); - pwrite(cow.fhs, buffer, len, 0); -} - - - - -int cow_printStats( char *buffer, const size_t len ) { - - int ret = 0; - if(uploadLoop){ - ret = snprintf( buffer, len, "uuid: %s\nstate: %s\ntotalBlocks: \n", - metadata->uuid, "active"); - } - - if(!uploadLoop){ - ret = snprintf( buffer, len, "uuidS %s\nstate: %s\ntotalBlocks: \nuploading: %lu/%lu\n", - metadata->uuid, "uploading", blocksUploaded, blocksForCompleteUpload ); - } - if ( ret < 0 ) { - ret = 0; - } - - return ret; -} - void cowfile_close() { uploadLoop = false; diff --git a/src/fuse/cowfile.h b/src/fuse/cowfile.h index 477f966..205a1b3 100644 --- a/src/fuse/cowfile.h +++ b/src/fuse/cowfile.h @@ -82,17 +82,17 @@ typedef struct cow_curl_read_upload { cow_block_metadata_t *block; size_t position; - int blocknumber; + long unsigned int blocknumber; int fails; } cow_curl_read_upload_t; typedef int32_t l1; typedef cow_block_metadata_t l2[COW_L2_SIZE]; -bool cowfile_init( - char *path, const char *image_Name, uint16_t imageVersion, size_t **imageSizePtr, char *serverAdress ); +bool cowfile_init( char *path, const char *image_Name, uint16_t imageVersion, atomic_uint_fast64_t **imageSizePtr, char *serverAdress, + int isForeground ); -bool cowfile_load( char *path, size_t **imageSizePtr, char *serverAdress ); +bool cowfile_load( char *path, atomic_uint_fast64_t **imageSizePtr, char *serverAdress, int isForeground ); void cowfile_read( fuse_req_t req, size_t size, off_t offset ); diff --git a/src/fuse/main.c b/src/fuse/main.c index 936c779..8ee8221 100644 --- a/src/fuse/main.c +++ b/src/fuse/main.c @@ -18,8 +18,8 @@ static const char *STATS_NAME = "status"; static struct fuse_session *_fuseSession = NULL; bool useCow = false; bool cow_merge_after_upload = false; -static uint64_t imageSize; -static uint64_t *imageSizePtr =&imageSize; +static atomic_uint_fast64_t imageSize; +static atomic_uint_fast64_t *imageSizePtr =&imageSize; /* Debug/Benchmark variables */ static bool useDebug = false; @@ -505,7 +505,7 @@ int main( int argc, char *argv[] ) printUsage( argv[0], EXIT_FAILURE ); } if ( loadCow ) { - if ( !cowfile_load( cow_file_path, &imageSizePtr, cow_server_address ) ) { + if ( !cowfile_load( cow_file_path, &imageSizePtr, cow_server_address, foreground ) ) { return EXIT_FAILURE; } } @@ -554,7 +554,7 @@ int main( int argc, char *argv[] ) owner = getuid(); if ( useCow & !loadCow) { - if( !cowfile_init( cow_file_path, connection_getImageName(), connection_getImageRID(), &imageSizePtr, cow_server_address ) ) { + if( !cowfile_init( cow_file_path, connection_getImageName(), connection_getImageRID(), &imageSizePtr, cow_server_address, foreground ) ) { return EXIT_FAILURE; } } |