summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2011-03-06 20:46:29 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2011-03-06 20:46:29 +0000
commit6c701b58a24d96e37c323412f3d2aa334cd2ded1 (patch)
treea959865f001c94ce70bd94b5cd0f09c725f28fc4
parent8d663918601896f6f5759a0f0b86a0131201dcfb (diff)
download2011-ddhardrescue-6c701b58a24d96e37c323412f3d2aa334cd2ded1.tar.gz
2011-ddhardrescue-6c701b58a24d96e37c323412f3d2aa334cd2ded1.tar.bz2
2011-ddhardrescue-6c701b58a24d96e37c323412f3d2aa334cd2ded1.zip
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 git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@11 d3078510-dda0-49f1-841c-895ef4b7ec81
-rwxr-xr-xinc/recover.h4
-rw-r--r--inc/slices_evt.h17
-rwxr-xr-xsrc/ddhardrescue.c32
-rwxr-xr-xsrc/recover.c19
-rwxr-xr-xsrc/slices.c2
-rw-r--r--src/slices_evt.c22
6 files changed, 71 insertions, 25 deletions
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 <string.h>
#include <pthread.h>
-#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;
+}