summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Scherle2022-06-07 20:14:54 +0200
committerMichael Scherle2022-06-07 20:14:54 +0200
commit7f7a532fedfabc87f00d9bc53c42f09a443c1e75 (patch)
tree2e4d6a8172c6f1ae87972899076c125430d91bde
parentadded parallel file upload (diff)
downloaddnbd3-7f7a532fedfabc87f00d9bc53c42f09a443c1e75.tar.gz
dnbd3-7f7a532fedfabc87f00d9bc53c42f09a443c1e75.tar.xz
dnbd3-7f7a532fedfabc87f00d9bc53c42f09a443c1e75.zip
fixed multiple compiler warnings
-rw-r--r--inc/dnbd3/config.h2
-rw-r--r--src/cowtest/main.c61
-rw-r--r--src/fuse/connection.c4
-rw-r--r--src/fuse/cowfile.c256
-rw-r--r--src/fuse/cowfile.h8
-rw-r--r--src/fuse/main.c8
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;
}
}