git » libjio » commit 0e02368

Add support for libfiu, a library for fault injection

author Alberto Bertogli
2009-03-02 05:54:34 UTC
committer Alberto Bertogli
2009-03-26 22:40:36 UTC
parent a49c332cb2d493ef61ba662fcdcfab06abaee39c

Add support for libfiu, a library for fault injection

This patch implements support for libfiu, which is a library for fault
injection. It adds several "failure points" inside the code, that can (and
will) be used, in the future, for testing purposes.

In order to avoid a build-time dependency on libfiu, it also adds a
special libfiu local header to the tree.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

Makefile +8 -2
common.h +1 -0
fiu-local.h +37 -0
trans.c +19 -0

diff --git a/Makefile b/Makefile
index fa64b5f..b2bb56e 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,8 @@ MANDATORY_CFLAGS := \
 
 ALL_CFLAGS += $(CFLAGS) $(MANDATORY_CFLAGS) -fPIC
 
+LIBS = -lpthread
+
 ifdef DEBUG
 ALL_CFLAGS += -g
 endif
@@ -19,6 +21,10 @@ ifdef PROFILE
 ALL_CFLAGS += -g -pg -fprofile-arcs -ftest-coverage
 endif
 
+ifdef FIU
+ALL_CFLAGS += -DFIU_ENABLE=1
+LIBS += -lfiu
+endif
 
 # prefix for installing the binaries
 PREFIX=/usr/local
@@ -42,7 +48,7 @@ default: all
 all: libjio.so libjio.a libjio.pc jiofsck
 
 libjio.so: $(OBJS)
-	$(NICE_CC) -shared $(ALL_CFLAGS) $(OBJS) -lpthread -o libjio.so
+	$(NICE_CC) -shared $(ALL_CFLAGS) $(LIBS) $(OBJS) -o libjio.so
 
 libjio.a: $(OBJS)
 	$(NICE_AR) cr libjio.a $(OBJS)
@@ -55,7 +61,7 @@ libjio.pc: libjio.skel.pc
 		> libjio.pc
 
 jiofsck: jiofsck.o libjio.a
-	$(NICE_CC) $(ALL_CFLAGS) jiofsck.o libjio.a -lpthread -o jiofsck
+	$(NICE_CC) $(ALL_CFLAGS) jiofsck.o libjio.a $(LIBS) -lpthread -o jiofsck
 
 install: all
 	install -d $(PREFIX)/lib
diff --git a/common.h b/common.h
index b25ec26..c946591 100644
--- a/common.h
+++ b/common.h
@@ -13,6 +13,7 @@
 #include <stdint.h>	/* for uint*_t */
 
 #include "libjio.h"	/* for struct jfs */
+#include "fiu-local.h"	/* for fault injection functions */
 
 #define _F_READ		0x00001
 #define _F_WRITE	0x00010
diff --git a/fiu-local.h b/fiu-local.h
new file mode 100644
index 0000000..b68327b
--- /dev/null
+++ b/fiu-local.h
@@ -0,0 +1,37 @@
+
+/* libfiu - Fault Injection in Userspace
+ *
+ * This header, part of libfiu, is meant to be included in your project to
+ * avoid having libfiu as a mandatory build-time dependency.
+ *
+ * You can add it to your project, and #include it instead of fiu.h.
+ * The real fiu.h will be used only when FIU_ENABLE is defined.
+ *
+ * This header, as the rest of libfiu, is in the public domain.
+ *
+ * You can find more information about libfiu at
+ * http://blitiri.com.ar/p/libfiu.
+ */
+
+#ifndef _FIU_LOCAL_H
+#define _FIU_LOCAL_H
+
+/* Only define the stubs when fiu is disabled, otherwise use the real fiu.h
+ * header */
+#ifndef FIU_ENABLE
+
+#define fiu_init(flags) 0
+#define fiu_fail(name) 0
+#define fiu_failinfo() NULL
+#define fiu_do_on(name, action)
+#define fiu_exit_on(name)
+#define fiu_return_on(name, retval)
+
+#else
+
+#include <fiu.h>
+
+#endif /* FIU_ENABLE */
+
+#endif /* _FIU_LOCAL_H */
+
diff --git a/trans.c b/trans.c
index 6ff54c2..bd0eab5 100644
--- a/trans.c
+++ b/trans.c
@@ -38,6 +38,8 @@ static unsigned int get_tid(struct jfs *fs)
 	/* read the current max. curid */
 	curid = *(fs->jmap);
 
+	fiu_do_on("jio/get_tid/overflow", curid = -1);
+
 	/* increment it and handle overflows */
 	rv = curid + 1;
 	if (rv == 0)
@@ -241,6 +243,8 @@ ssize_t jtrans_commit(struct jtrans *ts)
 	if (fd < 0)
 		goto exit;
 
+	fiu_exit_on("jio/commit/created_tf");
+
 	/* and lock it */
 	plockf(fd, F_LOCKW, 0, 0);
 
@@ -269,6 +273,8 @@ ssize_t jtrans_commit(struct jtrans *ts)
 		goto unlink_exit;
 	}
 
+	fiu_exit_on("jio/commit/tf_header");
+
 	free(buf_init);
 
 	curpos = J_DISKHEADSIZE;
@@ -334,6 +340,8 @@ ssize_t jtrans_commit(struct jtrans *ts)
 			goto unlink_exit;
 		}
 
+		fiu_exit_on("jio/commit/tf_ophdr");
+
 		free(buf_init);
 
 		curpos += J_DISKOPHEADSIZE;
@@ -344,8 +352,12 @@ ssize_t jtrans_commit(struct jtrans *ts)
 			goto unlink_exit;
 
 		curpos += op->len;
+
+		fiu_exit_on("jio/commit/tf_opdata");
 	}
 
+	fiu_exit_on("jio/commit/tf_data");
+
 	/* compute and save the checksum (curpos is always small, so there's
 	 * no overflow possibility when we convert to size_t) */
 	if (!checksum(fd, curpos, &csum))
@@ -376,6 +388,8 @@ ssize_t jtrans_commit(struct jtrans *ts)
 		}
 	}
 
+	fiu_exit_on("jio/commit/tf_sync");
+
 	/* now that we have a safe transaction file, let's apply it */
 	written = 0;
 	for (op = ts->op; op != NULL; op = op->next) {
@@ -384,8 +398,11 @@ ssize_t jtrans_commit(struct jtrans *ts)
 			goto rollback_exit;
 
 		written += rv;
+		fiu_exit_on("jio/commit/wrote_op");
 	}
 
+	fiu_exit_on("jio/commit/wrote_all_ops");
+
 	if (ts->flags & J_LINGER) {
 		linger = malloc(sizeof(struct jlinger));
 		if (linger == NULL)
@@ -402,6 +419,7 @@ ssize_t jtrans_commit(struct jtrans *ts)
 		/* the transaction has been applied, so we cleanup and remove
 		 * it from the disk */
 		unlink(name);
+		fiu_exit_on("jio/commit/pre_ok_free_tid");
 		free_tid(ts->fs, ts->id);
 	}
 
@@ -673,6 +691,7 @@ int jsync(struct jfs *fs)
 	pthread_mutex_lock(&(fs->ltlock));
 	while (fs->ltrans != NULL) {
 		free_tid(fs, fs->ltrans->id);
+		fiu_exit_on("jio/jsync/pre_unlink");
 		unlink(fs->ltrans->name);
 		free(fs->ltrans->name);