git » libfiu » commit 6e63df0

preload/posix: Simulate incomplete reads and writes

author Alberto Bertogli
2009-07-15 17:11:59 UTC
committer Alberto Bertogli
2009-07-15 17:30:44 UTC
parent fef533cfe2c79314727fa3f48f6a10d21408cb04

preload/posix: Simulate incomplete reads and writes

This patch implements a generic way of adding a point of failure to reduce
a given parameter in a random amount, which is then used to add points of
failure to simulate incomplete reads and writes.

Note that it will never make it 0, as that usually has a special meaning
(EOF for reads).

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

preload/posix/codegen.h +8 -0
preload/posix/generate +17 -1
preload/posix/modules/posix.io.mod +7 -0

diff --git a/preload/posix/codegen.h b/preload/posix/codegen.h
index 66ece82..30541fa 100644
--- a/preload/posix/codegen.h
+++ b/preload/posix/codegen.h
@@ -132,6 +132,14 @@ extern int __thread _fiu_called;
 			goto exit;				\
 		}
 
+/* Generates a body part that will reduce the CNT parameter in a random
+ * amount when the given point of failure is enabled. Can be combined with the
+ * other body generators. */
+#define mkwrap_body_reduce(FIU_NAME, CNT)			\
+	fstatus = fiu_fail(FIU_NAME);				\
+	if (fstatus != 0) {					\
+		CNT -= random() % CNT;				\
+	}
 
 #define mkwrap_bottom(NAME, PARAMSN)				\
 								\
diff --git a/preload/posix/generate b/preload/posix/generate
index c61ddd2..0cc66e7 100755
--- a/preload/posix/generate
+++ b/preload/posix/generate
@@ -50,6 +50,9 @@ class Function:
 		self.use_errno = False
 		self.valid_errnos = []
 
+		# if the given parameter should be reduced by a random amount
+		self.reduce = None
+
 	def load_from_definition(self, definition):
 		m = func_def_re.match(definition)
 		self.name = m.group("name")
@@ -70,6 +73,8 @@ class Function:
 			elif k == 'valid errnos':
 				self.use_errno = True
 				self.valid_errnos = v.split()
+			elif k == 'reduce':
+				self.reduce = v
 			else:
 				raise SyntaxError, \
 					"Unknown information: " + k
@@ -99,6 +104,10 @@ class Function:
 				(self.ret_type, self.name, self.params,
 					paramsn, paramst) )
 
+		if self.reduce:
+			f.write('mkwrap_body_reduce("%s/reduce", %s)\n' % \
+					(self.fiu_name, self.reduce) )
+
 		if self.use_errno:
 			if self.on_error is None:
 				desc = "%s uses errno but has no on_error" % \
@@ -130,6 +139,12 @@ class Function:
 			f.write("\t  #endif\n")
 		f.write("\t};\n");
 
+	def fiu_names(self):
+		n = [self.fiu_name]
+		if self.reduce:
+			n.append(self.fiu_name + '/reduce')
+		return n
+
 
 class Include:
 	"Represents an include directive"
@@ -272,7 +287,8 @@ def write_function_list(directives, path):
 	f = open(path, 'a')
 	for d in directives:
 		if isinstance(d, Function):
-			f.write("%-32s%s\n" % (d.name, d.fiu_name))
+			f.write("%-32s%s\n" % (d.name, \
+				', '.join(d.fiu_names())) )
 
 
 def usage():
diff --git a/preload/posix/modules/posix.io.mod b/preload/posix/modules/posix.io.mod
index 62b918a..dd9bb2d 100644
--- a/preload/posix/modules/posix.io.mod
+++ b/preload/posix/modules/posix.io.mod
@@ -36,28 +36,35 @@ fiu name base: posix/io/rw/
 ssize_t read(int fd, void *buf, size_t count);
 	on error: -1
 	valid errnos: EBADFD EFAULT EINTR EINVAL EIO EISDIR EOVERFLOW
+	reduce: count
 
 ssize_t pread(int fd, void *buf, size_t count, off_t offset);
 	on error: -1
 	valid errnos: EBADFD EFAULT EINTR EINVAL EIO EISDIR EOVERFLOW
+	reduce: count
 
 ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
 	on error: -1
 	valid errnos: EBADFD EFAULT EINTR EINVAL EIO EISDIR EOVERFLOW
+	reduce: iovcnt
 
 
 ssize_t write(int fd, const void *buf, size_t count);
 	on error: -1
 	valid errnos: EBADFD EFAULT EFBIG EINTR EINVAL EIO ENOSPC
+	reduce: count
 
 ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
 	on error: -1
 	valid errnos: EBADFD EFAULT EFBIG EINTR EINVAL EIO ENOSPC \
 		EOVERFLOW
+	reduce: count
 
 ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
 	on error: -1
 	valid errnos: EBADFD EFAULT EFBIG EINTR EINVAL EIO ENOSPC
+	reduce: iovcnt
+
 
 int truncate(const char *path, off_t length);
 	on error: -1