From 6c701b58a24d96e37c323412f3d2aa334cd2ded1 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 6 Mar 2011 20:46:29 +0000 Subject: La gestion minimaliste des évènements de modification des slices est faite. Un dump à chaque event a été codé dans le main pour tester cet aspect. C'est ok. Go go go ncurses :D MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@11 d3078510-dda0-49f1-841c-895ef4b7ec81 --- inc/recover.h | 4 ++-- inc/slices_evt.h | 17 +++++++++++++++++ src/ddhardrescue.c | 32 +++++++++++++++++++------------- src/recover.c | 19 ++++++++++--------- src/slices.c | 2 +- src/slices_evt.c | 22 ++++++++++++++++++++++ 6 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 inc/slices_evt.h create mode 100644 src/slices_evt.c diff --git a/inc/recover.h b/inc/recover.h index 2af7f3f..eee8141 100755 --- a/inc/recover.h +++ b/inc/recover.h @@ -1,11 +1,11 @@ #ifndef RECOVER_H #define RECOVER_H -#include "slices.h" +#include "slices_evt.h" extern int end; -void recover(slices_t *slices, char *src, char *dst, char*ddOpts); +void recover(slices_evt_t *slicesEvt, char *src, char *dst, char*ddOpts); int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src, char *dst, char *ddOpts); #endif /*RECOVER_H*/ diff --git a/inc/slices_evt.h b/inc/slices_evt.h new file mode 100644 index 0000000..e7d44fe --- /dev/null +++ b/inc/slices_evt.h @@ -0,0 +1,17 @@ +#ifndef SLICES_EVT_H +#define SLICES_EVT_H + +#include "slices.h" + +//typedef enum { EV_BOUNDARY, EV_TYPE } sliceEvtKind_t; + +typedef struct _slices_evt_t { + slices_t *data; + pthread_mutex_t mutex; + void (*eventListener)(/*sliceEvtKind_t evtKind,*/ struct _slices_evt_t *slicesEvt, slice_t *slice); +} slices_evt_t; + +int sliceSplitEvt(slices_evt_t *slicesEvt, slice_t *initialSlice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter); + +#endif /*SLICES_EVT_H */ + diff --git a/src/ddhardrescue.c b/src/ddhardrescue.c index afad903..9f355b3 100755 --- a/src/ddhardrescue.c +++ b/src/ddhardrescue.c @@ -5,7 +5,7 @@ #include #include -#include "slices.h" +#include "slices_evt.h" #include "recover.h" #include "utils.h" @@ -14,17 +14,9 @@ int end=0; //FIXME remove me, only for tests unsigned long c=0; -typedef enum { E_BOUND, E_TYPE } sliceEventKind_t; - -typedef struct { - slices_t *data; - pthread_mutex_t mutex; - void (*slices_listener)(sliceEventKind_t eventKind, slices_t *slices, slice_t *slice); -} slices_manage_t; - struct threadArgs { struct progArgs *progArgs; - slices_manage_t *slices; + slices_evt_t *slices; }; @@ -32,6 +24,16 @@ void sigHookAbrt() { end=1; } +//TODO : remove that when procViewer is done +void dumper(slices_evt_t *slicesEvt, slice_t *modifiedSlice) { + address_t blockSize=0; + char *dump; + dump=slicesDump(slicesEvt->data, &blockSize, 1000, 0, 21474836480ULL); + puts(dump); + free(dump); + +} + void *procWorker(void *a); void *procViewer(void *a); @@ -41,7 +43,7 @@ int main(int argc, char **argv) { pthread_t tWorker, tViewer; // Main data structures - slices_manage_t slices; + slices_evt_t slices; // Progam and threads arguments struct progArgs args; @@ -72,6 +74,7 @@ int main(int argc, char **argv) { // Data structure initialization memset(&slices, 0, sizeof(slices)); slices.data=slicesNewSingleton(args.beginSector, args.endSector, S_UNKNOWN); + slices.eventListener=dumper; res=pthread_mutex_init(&(slices.mutex), NULL); if (res!=0) { return 3; @@ -96,7 +99,7 @@ int main(int argc, char **argv) { (void) pthread_join(tWorker, NULL); (void) pthread_join(tViewer, NULL); - //Final dump of datas + /*Final dump of datas address_t blockSize=0; char *dump; dump=slicesDump(slices.data, &blockSize, 1000, args.beginSector, args.endSector); @@ -104,6 +107,7 @@ int main(int argc, char **argv) { free(dump); printf("blockSize==%lld\n", blockSize); printf("slices->count==%d\n", slices.data->count); + */ //Resources desallocation (void) pthread_mutex_destroy(&(slices.mutex)); @@ -125,7 +129,7 @@ void * procWorker(void *a) { struct threadArgs *tArgs = (struct threadArgs *)a; recover( - tArgs->slices->data, + tArgs->slices, tArgs->progArgs->src, tArgs->progArgs->dst, tArgs->progArgs->ddOpts @@ -138,3 +142,5 @@ void *procViewer(void *a) { return a; } + + diff --git a/src/recover.c b/src/recover.c index 309ebfb..b4f0da7 100755 --- a/src/recover.c +++ b/src/recover.c @@ -5,12 +5,12 @@ extern unsigned long c; -void recover(slices_t *slices, char *src, char *dst, char *ddOpts) { +void recover(slices_evt_t *slicesEvt, char *src, char *dst, char *ddOpts) { slice_t *sliceToRead; address_t firstError=0, median, foundMax=0; int res; - sliceToRead=slices->first; + sliceToRead=slicesEvt->data->first; while (!end) { // try to recover sliceToRead and split it if read error switch ( tryRecoverUntilError(sliceToRead, &firstError, src, dst, ddOpts) ) { @@ -20,7 +20,7 @@ void recover(slices_t *slices, char *src, char *dst, char *ddOpts) { break; case EIO: // slice recovery has encountered a readerror - res=sliceSplit(slices, sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN); + res=sliceSplitEvt(slicesEvt, sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN); if (res<1) { //TODO printf("sliceSplit return %d\n", res); @@ -34,7 +34,7 @@ void recover(slices_t *slices, char *src, char *dst, char *ddOpts) { /* Now, search the largest S_UNKNOWN zone split it in two parts */ //sliceToRead=slicesFindLargest(slices, S_UNKNOWN); - sliceToRead=slicesFindLargestFast(slices, &foundMax, S_UNKNOWN, foundMax, sliceToRead->next); + sliceToRead=slicesFindLargestFast(slicesEvt->data, &foundMax, S_UNKNOWN, foundMax, sliceToRead->next); if ( sliceToRead == NULL ) { // There is nothing more to recover, bailout end=1; @@ -43,7 +43,7 @@ void recover(slices_t *slices, char *src, char *dst, char *ddOpts) { median=(sliceToRead->begin+sliceToRead->end)/2; - res=sliceSplit(slices, sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN); + res=sliceSplitEvt(slicesEvt, sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN); switch (res) { case 1: // No split, try analyse this zone @@ -92,10 +92,11 @@ int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src, *firstError=sliceToRead->begin; res=EIO; */ +/* // Simulate that we have systematically a read error at last sector *firstError=sliceToRead->end; res=EIO; - +*/ /* // Simulate that we have systematically a read error at first sector // Simulate for each read, tha we have an error just in the middle if read for mor than one sector @@ -106,16 +107,16 @@ int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src, res=EIO; } */ -/* + // Simulate for each read a pseudo random error position and generate some cases of full read without error - int error=sliceToRead->begin + rand()%count; + address_t error=sliceToRead->begin + rand()%count; if ( error % 42 == 0 ) { res=0; } else { res=EIO; *firstError=error; } -*/ + return res; } diff --git a/src/slices.c b/src/slices.c index 9f40b9e..21fdd3b 100755 --- a/src/slices.c +++ b/src/slices.c @@ -36,7 +36,7 @@ int sliceSplit(slices_t *slices, slice_t *initialSlice, address_t splitAt, slice and then between he first and second if needed. */ - if ( splitAt < initialSlice->begin || splitAt > initialSlice->end ) return 2; + if ( splitAt < initialSlice->begin || splitAt > initialSlice->end ) return -2; // Test before act because we'll change values of the initialSlice because // it would become the firstSlice or even the second one if the first is zero-lenght diff --git a/src/slices_evt.c b/src/slices_evt.c new file mode 100644 index 0000000..43cb568 --- /dev/null +++ b/src/slices_evt.c @@ -0,0 +1,22 @@ +#include "slices_evt.h" + +int sliceSplitEvt(slices_evt_t *slicesEvt, slice_t *initialSlice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter) { + int res; + res=sliceSplit(slicesEvt->data, initialSlice, splitAt, statusBefore, statusAt, statusAfter); + if ( slicesEvt->eventListener != NULL ) { + //FIXME : this could be dereference a NULL pointer. Implement a real listener system with a thread-safe FIFO + switch(res) { + case 3: + slicesEvt->eventListener(slicesEvt, initialSlice->next->next); + case 2: + slicesEvt->eventListener(slicesEvt, initialSlice->next); + case 1: + slicesEvt->eventListener(slicesEvt, initialSlice); + break; + default: + // No events on split errors + break; + } + } + return res; +} -- cgit v1.2.3