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
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include "merger.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;
}
unsigned int version ;
read(fhCow,&version,sizeof(unsigned int));
read(fhCow,&size,sizeof(uint64_t));
int l;
read(fhCow,&l,sizeof(int));
char *buffer = malloc(sizeof(char)*(l+1));
read(fhCow,buffer,l*sizeof(char));
buffer[l]='\0';
int pageSize;
read(fhCow,&pageSize,sizeof(int));
printf("Version: %u\n",version);
printf("länge: %i \n",l);
printf("Image Name: %s\n",buffer);
printf("Size: %ld\n", (long)size);
printf("pageSize: %i\n", (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;
filePointers = mmap(NULL,imageBlockCount*sizeof(off_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 %llu of %llu 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,filePointers[i]+(4096*(j+1)),SEEK_SET);
char buff[4096] = {0};
if(read(fhCow, &buff, 4096) < 0){
printf("Error on reading Cow File. BigBlock: %llu\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: %llu\n",i);
return false;
}
}
}
mergedBlocks++;
}
}
printf("Merged %llu Blocks\n",mergedBlocks);
ftruncate(fhImage, size);
return true;
}
|