All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akinobu Mita <akinobu.mita@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: ak@suse.de, akpm@osdl.org, Don Mullis <dwm@meer.net>, okuji@enbug.org
Subject: [patch 2/7] fault-injection capabilities infrastructure
Date: Thu, 09 Nov 2006 02:45:43 +0900	[thread overview]
Message-ID: <45521806.269d1f82.2fc8.5124@mx.google.com> (raw)
In-Reply-To: 20061108174540.976625689@gmail.com

[-- Attachment #1: should-fail.patch --]
[-- Type: text/plain, Size: 7850 bytes --]

From: Akinobu Mita <akinobu.mita@gmail.com>

This patch provides base functions implement to fault-injection
capabilities.

- The function should_fail() is taken from failmalloc-1.0
  (http://www.nongnu.org/failmalloc/)

Cc: okuji@enbug.org
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Don Mullis <dwm@meer.net>

 include/linux/fault-inject.h |   69 ++++++++++++++++
 lib/Kconfig.debug            |   12 ++
 lib/Makefile                 |    1 
 lib/fault-inject.c           |  179 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 261 insertions(+)

Index: 2.6-rc/lib/Kconfig.debug
===================================================================
--- 2.6-rc.orig/lib/Kconfig.debug
+++ 2.6-rc/lib/Kconfig.debug
@@ -412,3 +412,15 @@ config LKDTM
 
 	Documentation on how to use the module can be found in
 	drivers/misc/lkdtm.c
+
+config FAULT_INJECTION
+	bool
+
+config FAULT_INJECTION_DEBUG_FS
+	bool "Debugfs entries for fault-injection capabilities"
+	depends on FAULT_INJECTION && SYSFS
+	select DEBUG_FS
+	help
+	  This option enables to configure fault-injection capabilities via
+	  debugfs entries.
+
Index: 2.6-rc/lib/Makefile
===================================================================
--- 2.6-rc.orig/lib/Makefile
+++ 2.6-rc/lib/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_SMP) += percpu_counter.o
 obj-$(CONFIG_AUDIT_GENERIC) += audit.o
 
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
+obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
 
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
Index: 2.6-rc/include/linux/fault-inject.h
===================================================================
--- /dev/null
+++ 2.6-rc/include/linux/fault-inject.h
@@ -0,0 +1,69 @@
+#ifndef _LINUX_FAULT_INJECT_H
+#define _LINUX_FAULT_INJECT_H
+
+#ifdef CONFIG_FAULT_INJECTION
+
+#include <linux/types.h>
+#include <linux/debugfs.h>
+#include <asm/atomic.h>
+
+/*
+ * For explanation of the elements of this struct, see
+ * Documentation/fault-injection/fault-injection.txt
+ */
+struct fault_attr {
+	unsigned long probability;
+	unsigned long interval;
+	atomic_t times;
+	atomic_t space;
+	unsigned long verbose;
+
+	unsigned long count;
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+
+	struct {
+		struct dentry *dir;
+
+		struct dentry *probability_file;
+		struct dentry *interval_file;
+		struct dentry *times_file;
+		struct dentry *space_file;
+		struct dentry *verbose_file;
+	} dentries;
+
+#endif
+};
+
+#define FAULT_ATTR_INITIALIZER {				\
+		.interval = 1,					\
+		.times = ATOMIC_INIT(1),			\
+	}
+
+#define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER	
+int setup_fault_attr(struct fault_attr *attr, char *str);
+void should_fail_srandom(unsigned long entropy);
+int should_fail(struct fault_attr *attr, ssize_t size);
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+
+int init_fault_attr_dentries(struct fault_attr *attr, const char *name);
+void cleanup_fault_attr_dentries(struct fault_attr *attr);
+
+#else /* CONFIG_FAULT_INJECTION_DEBUG_FS */
+
+static inline int init_fault_attr_dentries(struct fault_attr *attr,
+					  const char *name)
+{
+	return -ENODEV;
+}
+
+static inline void cleanup_fault_attr_dentries(struct fault_attr *attr)
+{
+}
+
+#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
+
+#endif /* CONFIG_FAULT_INJECTION */
+
+#endif /* _LINUX_FAULT_INJECT_H */
Index: 2.6-rc/lib/fault-inject.c
===================================================================
--- /dev/null
+++ 2.6-rc/lib/fault-inject.c
@@ -0,0 +1,179 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/stat.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/fault-inject.h>
+
+int setup_fault_attr(struct fault_attr *attr, char *str)
+{
+	unsigned long probability;
+	unsigned long interval;
+	int times;
+	int space;
+
+	/* "<interval>,<probability>,<space>,<times>" */
+	if (sscanf(str, "%lu,%lu,%d,%d",
+			&interval, &probability, &space, &times) < 4) {
+		printk(KERN_WARNING
+			"FAULT_INJECTION: failed to parse arguments\n");
+		return 0;
+	}
+
+	attr->probability = probability;
+	attr->interval = interval;
+	atomic_set(&attr->times, times);
+	atomic_set(&attr->space, space);
+
+	return 1;
+}
+
+static void fail_dump(struct fault_attr *attr)
+{
+	if (attr->verbose > 0)
+		printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure\n");
+	if (attr->verbose > 1)
+		dump_stack();
+}
+
+#define atomic_dec_not_zero(v)		atomic_add_unless((v), -1, 0)
+
+/*
+ * This code is stolen from failmalloc-1.0
+ * http://www.nongnu.org/failmalloc/
+ */
+
+int should_fail(struct fault_attr *attr, ssize_t size)
+{
+	if (atomic_read(&attr->times) == 0)
+		return 0;
+
+	if (atomic_read(&attr->space) > size) {
+		atomic_sub(size, &attr->space);
+		return 0;
+	}
+
+	if (attr->interval > 1) {
+		attr->count++;
+		if (attr->count % attr->interval)
+			return 0;
+	}
+
+	if (attr->probability > random32() % 100)
+		goto fail;
+
+	return 0;
+
+fail:
+	fail_dump(attr);
+
+	if (atomic_read(&attr->times) != -1)
+		atomic_dec_not_zero(&attr->times);
+
+	return 1;
+}
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+
+static void debugfs_ul_set(void *data, u64 val)
+{
+	*(unsigned long *)data = val;
+}
+
+static u64 debugfs_ul_get(void *data)
+{
+	return *(unsigned long *)data;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_ul, debugfs_ul_get, debugfs_ul_set, "%llu\n");
+
+static struct dentry *debugfs_create_ul(const char *name, mode_t mode,
+				struct dentry *parent, unsigned long *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_ul);
+}
+
+static void debugfs_atomic_t_set(void *data, u64 val)
+{
+	atomic_set((atomic_t *)data, val);
+}
+
+static u64 debugfs_atomic_t_get(void *data)
+{
+	return atomic_read((atomic_t *)data);
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
+			debugfs_atomic_t_set, "%lld\n");
+
+static struct dentry *debugfs_create_atomic_t(const char *name, mode_t mode,
+				struct dentry *parent, atomic_t *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_atomic_t);
+}
+
+void cleanup_fault_attr_dentries(struct fault_attr *attr)
+{
+	debugfs_remove(attr->dentries.probability_file);
+	attr->dentries.probability_file = NULL;
+
+	debugfs_remove(attr->dentries.interval_file);
+	attr->dentries.interval_file = NULL;
+
+	debugfs_remove(attr->dentries.times_file);
+	attr->dentries.times_file = NULL;
+
+	debugfs_remove(attr->dentries.space_file);
+	attr->dentries.space_file = NULL;
+
+	debugfs_remove(attr->dentries.verbose_file);
+	attr->dentries.verbose_file = NULL;
+
+	if (attr->dentries.dir)
+		WARN_ON(!simple_empty(attr->dentries.dir));
+
+	debugfs_remove(attr->dentries.dir);
+	attr->dentries.dir = NULL;
+}
+
+int init_fault_attr_dentries(struct fault_attr *attr, const char *name)
+{
+	mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+	struct dentry *dir;
+
+	memset(&attr->dentries, 0, sizeof(attr->dentries));
+
+	dir = debugfs_create_dir(name, NULL);
+	if (!dir)
+		goto fail;
+	attr->dentries.dir = dir;
+
+	attr->dentries.probability_file =
+		debugfs_create_ul("probability", mode, dir, &attr->probability);
+
+	attr->dentries.interval_file =
+		debugfs_create_ul("interval", mode, dir, &attr->interval);
+
+	attr->dentries.times_file =
+		debugfs_create_atomic_t("times", mode, dir, &attr->times);
+
+	attr->dentries.space_file =
+		debugfs_create_atomic_t("space", mode, dir, &attr->space);
+
+	attr->dentries.verbose_file =
+		debugfs_create_ul("verbose", mode, dir, &attr->verbose);
+
+	if (!attr->dentries.probability_file || !attr->dentries.interval_file
+	    || !attr->dentries.times_file || !attr->dentries.space_file
+	    || !attr->dentries.verbose_file)
+		goto fail;
+
+	return 0;
+fail:
+	cleanup_fault_attr_dentries(attr);
+	return -ENOMEM;
+}
+
+#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */

--

  parent reply	other threads:[~2006-11-08 17:46 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20061108174540.976625689@gmail.com>
2006-11-08 17:45 ` [patch 1/7] documentation and scripts Akinobu Mita
2006-11-08 17:45 ` Akinobu Mita [this message]
2006-11-08 17:45 ` [patch 3/7] fault-injection capability for kmalloc Akinobu Mita
2006-11-08 17:45 ` [patch 4/7] fault-injection capability for alloc_pages() Akinobu Mita
2006-11-08 17:45 ` [patch 5/7] fault-injection capability for disk IO Akinobu Mita
2006-11-08 17:45 ` [patch 6/7] process filtering for fault-injection capabilities Akinobu Mita
2006-11-08 17:45 ` [patch 7/7] stacktrace filtering Akinobu Mita
     [not found] <20061012074305.047696736@gmail.com>
2006-10-12  7:43 ` [patch 2/7] fault-injection capabilities infrastructure Akinobu Mita
2006-10-12 21:03   ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45521806.269d1f82.2fc8.5124@mx.google.com \
    --to=akinobu.mita@gmail.com \
    --cc=ak@suse.de \
    --cc=akpm@osdl.org \
    --cc=dwm@meer.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=okuji@enbug.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.