From 78725557a028004d6e03a6ce82856eae282a1a8f Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Fri, 18 Feb 2011 17:06:00 +0000 Subject: Iport initial du projet. Compile presque, reste beaucoup de fonctions utilisataires pour les slices à coder (notamment slicesDump()) et manque une gestion multi-thread pour aficher pendant le recovery. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@2 d3078510-dda0-49f1-841c-895ef4b7ec81 --- src/ddhardrescue.c | 35 ++++++++++++++++++++++++++++ src/recover.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/recover.h | 11 +++++++++ src/slices.c | 53 ++++++++++++++++++++++++++++++++++++++++++ src/slices.h | 29 +++++++++++++++++++++++ 5 files changed, 196 insertions(+) create mode 100755 src/ddhardrescue.c create mode 100755 src/recover.c create mode 100755 src/recover.h create mode 100755 src/slices.c create mode 100755 src/slices.h diff --git a/src/ddhardrescue.c b/src/ddhardrescue.c new file mode 100755 index 0000000..56cc5bf --- /dev/null +++ b/src/ddhardrescue.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#include "slices.h" +#include "recover.h" + +int end=0; + +void sigHookAbrt() { + end=1; +} + +int main() { + char *src, *dst, *ddOpts; + address_t beginSector, endSector; + int depth; + slices_t *slices; + + //TODO Parse args + src="/dev/sdb"; + dst="./test.img"; + ddOpts=""; + beginSector=0; + endSector=100; + depth=10; + + //TODO signal... + + slices=recover(src,dst,ddOpts,beginSector,endSector,depth); + + //TODO final reporting + + return 0; +} diff --git a/src/recover.c b/src/recover.c new file mode 100755 index 0000000..c2c2eff --- /dev/null +++ b/src/recover.c @@ -0,0 +1,68 @@ +#include +#include "recover.h" + +slices_t *recover(char *src, char *dst, char*ddOpts, address_t beginSector, address_t endSector, int depth) { + slices_t *slices; + slice_t *sliceToRead; + address_t firstError=0, median; + int res; + + // Initialization : we want to try to recover the beginning of the whole zone + slices=slicesNew(); + sliceToRead=sliceNew(beginSector, endSector, S_UNKNOWN, NULL); + if (sliceToRead==NULL) { + exit(1);//TODO + } + slicesAppend(slices, sliceToRead); + + // Main loop + while (!end && slices->count < (endSector-beginSector)/depth) { + // try to recover sliceToRead and split it if read error + switch ( tryRecoverUntilError(sliceToRead, &firstError) ) { + case 0: + // slice recovery has been executed without read error + sliceToRead->status=S_RECOVERED; + break; + case EIO: + // slice recovery has encuontered a readerror + res=sliceSplit(sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN); + if (res!=0) { exit(5); } //TODO + break; + default: + exit(2); //TODO + } + + /* Now, search the largest S_UNKNOWN zone + split it in two parts */ + sliceToRead=slicesFindLargest(slices, S_UNKNOWN); + if ( sliceToRead == NULL ) { exit(3); } //TODO + + median=(sliceToRead->begin+sliceToRead->end)/2; + res=sliceSplit(sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN); + if (res!=0) { exit(4); } //TODO + + /* After splitting an S_UNKNOWN zone in two parts + take the second for further analysis. + We already now that this first one is just preceded by + a read error, and errors are frequently grouped in zones, + so trying to read a sector just after a faulty sector is + most likely a waste of time. + */ + sliceToRead=sliceToRead->next; + } + return slices; +} + +int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError) { + //TODO : implement realy that + int res; + + if ( sliceToRead->begin == sliceToRead->end ) { + res=0; + } else { + *firstError=(sliceToRead->begin + sliceToRead->end)/2; + res=EIO; + } + return res; +} + diff --git a/src/recover.h b/src/recover.h new file mode 100755 index 0000000..d8b1409 --- /dev/null +++ b/src/recover.h @@ -0,0 +1,11 @@ +#ifndef RECOVER_H +#define RECOVER_H + +#include "slices.h" + +extern int end; + +slices_t *recover(char *src, char *dst, char*ddOpts, address_t beginSector, address_t endSector, int depth); +int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError); + +#endif /*RECOVER_H*/ diff --git a/src/slices.c b/src/slices.c new file mode 100755 index 0000000..edae571 --- /dev/null +++ b/src/slices.c @@ -0,0 +1,53 @@ +#include +#include "slices.h" + +slice_t *sliceNew(address_t begin, address_t end, sliceStatus_t status, slice_t *next) { + slice_t *s = malloc(1*sizeof(slice_t)); + if (s!=NULL) { + s->begin=begin; + s->end=end; + s->status=status; + s->next=next; + } + + return s; +} + +int sliceSplit(slice_t *slice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter) { + return 1; +} + +slices_t *slicesNew() { + slices_t *ss = malloc(1*sizeof(slices_t)); + if (ss!=NULL) { + ss->count=0; + ss->first=NULL; + ss->last=NULL; + } + + return ss; +} + +void slicesAppend(slices_t *slices, slice_t *slice) { + +} + +slice_t *slicesFindLargest(slices_t *slices, sliceStatus_t status) { + return NULL; +} + +char *slicesDump(slices_t *slices, int charCount, address_t begin, address_t end) { + slice_t *curr = slices->first; + address_t sb,se, blockSize=(end-begin)/(charCount+1); + char *dump=malloc(1*charCount+1); + memset(dump, ' ', charCount); + + while (curr != NULL) { + sb=curr->begin; + // TODO : boucle pour dessiner les caractères correspondant selon le type de zone. Attention aux cas ou 1 caractère contient la frontière de plusieurs zones (ne pas toujours écraser avec la dernière valeur) + + curr=curr->next; + } + + return dump; +} diff --git a/src/slices.h b/src/slices.h new file mode 100755 index 0000000..062c4f4 --- /dev/null +++ b/src/slices.h @@ -0,0 +1,29 @@ +#ifndef SLICES_H +#define SLICES_H + +#include +#include + +typedef enum { S_UNKNOWN, S_RECOVERED, S_UNREADABLE } sliceStatus_t; +typedef uint32_t address_t; + +typedef struct _slice { + uint32_t begin, end; + sliceStatus_t status; + struct _slice *next; +} slice_t; + +typedef struct { + int count; + slice_t *first, *last; +} slices_t; + +slice_t *sliceNew(address_t begin, address_t end, sliceStatus_t status, slice_t *next); +int sliceSplit(slice_t *slice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter); + +slices_t *slicesNew(); +void slicesAppend(slices_t *slices, slice_t *slice); +slice_t *slicesFindLargest(slices_t *slices, sliceStatus_t status); +char *slicesDump(slices_t *slices, int charCount, address_t begin, address_t end); + +#endif /*SLICES_H*/ -- cgit v1.2.3