1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include "merger.h"
#include <inttypes.h>
#define TestBit(A,k) ( A[(k/32)] & (1 << (k%32)) )
int fhImage;
int fhCow;
off_t *filePointers;
uint64_t imageBlockCount;
uint64_t size;
bool merger( char *imageFilePath, char *cowFilePath )
{
if( !loadFiles( imageFilePath, cowFilePath ) ) {
return false;
}
if ( merge() ) {
printf("File Merged");
return true;
}
return false;
}
bool loadFiles(char *imageFilePath, char *cowFilePath)
{
if ( ( fhImage = open ( imageFilePath, O_RDWR ) ) == -1 ) {
printf( "Could not open Image.\n" );
return false;
}
if ( ( fhCow = open ( cowFilePath, O_RDONLY ) ) == -1 ) {
printf( "Could not open Cow File.\n" );
close( fhImage );
return false;
}
cow_metadata metadata;
read( fhCow, &metadata, sizeof( cow_metadata ) );
fixup_cow_metadata( metadata );
char *buffer = malloc(sizeof(char) * ( metadata.nameLenght + 1 ) );
read( fhCow, buffer, metadata.nameLenght * sizeof( char ) );
size = metadata.imageSize;
printf( "Version: %u\n",metadata.version );
printf( "Länge: %i \n", metadata.nameLenght );
printf( "Image Name: %s\n", buffer );
printf( "Size: %"PRIu64"\n", size );
printf( "pageSize: %i\n", metadata.pageSize );
free( buffer );
//TODO Image Validation
imageBlockCount = ( size + (4096*256)-1 ) / (4096*256);
off_t mmapStart = lseek( fhCow, 0L, SEEK_CUR );
int maxPageSize = 8192;
mmapStart = ( ( mmapStart + maxPageSize - 1) / maxPageSize ) * maxPageSize;
printf( "mmapStart: %"PRIu64"\n", mmapStart );
filePointers = mmap( NULL, imageBlockCount * sizeof(uint64_t), PROT_READ, MAP_SHARED, fhCow, mmapStart);
if(filePointers == MAP_FAILED ) {
printf("Error creating mmap in COW File.\n%s\nBye.\n ", strerror(errno) );
close( fhCow );
close( fhImage );
return false;
}
return true;
}
bool merge()
{
uint64_t mergedBlocks = 0;
for( uint64_t i = 0; i < imageBlockCount; i++ ) {
printf( "Merged %"PRIu64" of %"PRIu64" Blocks \n", i, imageBlockCount );
off_t pointer = (off_t) filePointers[i];
if( pointer != 0) {
int blockState[8];
lseek( fhCow, filePointers[i], SEEK_SET );
read( fhCow, &blockState, sizeof(int) * 8 );
for( int j = 0; j < 256; j++ ) {
if( TestBit( blockState, j ) ) {
lseek( fhCow, ((off_t) filePointers[i] + ( 4096 * ( j + 1) ) ), SEEK_SET );
char buff[4096] = {0};
if( read(fhCow, &buff, 4096) < 0) {
printf("Error on reading Cow File."
" BigBlock: %"PRIu64"n", i );
return false;
}
lseek( fhImage, ( i * 4096 * 256) + ( 4096 * j ), SEEK_SET );
if( write( fhImage, &buff, 4096 ) < 0) {
printf("Error on writing to File."
" BigBlock: %"PRIu64"\n", i );
return false;
}
mergedBlocks++;
}
}
}
}
printf( "Merged %"PRIu64" Blocks\n", mergedBlocks );
ftruncate( fhImage, size);
return true;
}
|