diff mbox series

[RFC,2/4] pdbg: Introduce a error registration framework.

Message ID 158918649143.16822.6515319767989338898.stgit@jupiter
State New
Headers show
Series [RFC,1/4] pdbg: Add support for error injection framework. | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (6c10b68bf774a9fe21affd5ef0b40084cd49800d)
snowpatch_ozlabs/build-multiarch success Test build-multiarch on branch master

Commit Message

Mahesh J Salgaonkar May 11, 2020, 8:41 a.m. UTC
Add an interface to register error injections that can be used through pdbg
inject command. Error injection can be split component wise. This interface
will allow one to introduce multiple error injections per component.
e.g. A timer facility components could be "tb" and "tod".

And each component will define multiple error injections under it.
e.g. "tb" component will have below error injections and so on...
	tfmr_parity
	hdec_parity
	dec_parity
	...

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
---
 Makefile.am      |    3 +
 src/err_inject.c |  128 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/err_inject.h |   20 ++++++++
 3 files changed, 146 insertions(+), 5 deletions(-)
 create mode 100644 src/err_inject.h
diff mbox series

Patch

diff --git a/Makefile.am b/Makefile.am
index 1e444ba..05522cf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -121,7 +121,8 @@  pdbg_SOURCES = \
 	src/thread.c \
 	src/util.c \
 	src/util.h \
-	src/err_inject.c
+	src/err_inject.c \
+	src/err_inject.h
 
 pdbg_CFLAGS = -I$(top_srcdir)/libpdbg -Wall -Werror -DGIT_SHA1=\"${GIT_SHA1}\" \
 	      $(ARCH_FLAGS)
diff --git a/src/err_inject.c b/src/err_inject.c
index 23463e7..ef6bc97 100644
--- a/src/err_inject.c
+++ b/src/err_inject.c
@@ -21,26 +21,146 @@ 
 #include <assert.h>
 
 #include <libpdbg.h>
+#include <ccan/list/list.h>
 
 #include "main.h"
 #include "optcmd.h"
 #include "path.h"
+#include "err_inject.h"
+
+struct list_head error_comp_list = LIST_HEAD_INIT(error_comp_list);
+
+struct error_type {
+	char *name;
+	char *desc;
+	inject_error_t inject_error;
+	void *data;
+	struct list_node error_link;
+};
+
+struct error_comp {
+	char *name;
+	struct list_head err_type_list;
+	struct list_node comp_link;
+};
+
+static struct error_comp *get_error_component(char *component)
+{
+	struct error_comp *err_comp = NULL;
+
+	list_for_each(&error_comp_list, err_comp, comp_link)
+		if (!strcmp(err_comp->name, component))
+			return err_comp;
+	return NULL;
+}
+
+static struct error_comp *create_error_component(char *component)
+{
+	struct error_comp *err_comp = NULL;
+
+	err_comp = malloc(sizeof(*err_comp));
+	if (!err_comp)
+		return NULL;
+
+	err_comp->name = strdup(component);
+	list_head_init(&err_comp->err_type_list);
+	list_add_tail(&error_comp_list, &err_comp->comp_link);
+
+	return err_comp;
+}
+
+static struct error_type *get_error_type(struct error_comp *err_comp,
+							char *error)
+{
+	struct error_type *err_type = NULL;
+
+	list_for_each(&err_comp->err_type_list, err_type, error_link)
+		if (!strcmp(err_type->name, error))
+			return err_type;
+	return NULL;
+}
+
+int register_error_inject(char *component, char *error, char *error_desc,
+				inject_error_t func, void *data)
+{
+	struct error_comp *err_comp = NULL;
+	struct error_type *err_type = NULL;
+
+	err_comp = get_error_component(component);
+	if (!err_comp) {
+		err_comp = create_error_component(component);
+		if (!err_comp)
+			return -ENOMEM;
+	}
+
+	err_type = malloc(sizeof(*err_type));
+	if (!err_type)
+		return -ENOMEM;
+
+	err_type->name = strdup(error);
+	err_type->inject_error = func;
+	err_type->data = data;
+	if (error_desc)
+		err_type->desc = strdup(error_desc);
+	list_add_tail(&err_comp->err_type_list, &err_type->error_link);
+
+	return 0;
+}
 
 static void list_error_components(void)
 {
-	/* TODO: List error components */
+	struct error_comp *err_comp = NULL;
+
+	printf("Usage: pdbg inject <component> <error>\n");
+	printf(" <component>:\n");
+	printf("  %-15s %s\n", "?", "Show component list");
+	list_for_each(&error_comp_list, err_comp, comp_link)
+		printf("  %-15s\n", err_comp->name);
 }
 
 static void list_err_type(char *component)
 {
-	/* TODO: List error type for a give component */
+	struct error_comp *err_comp = NULL;
+	struct error_type *err_type = NULL;
+
+	err_comp = get_error_component(component);
+	if (!err_comp) {
+		printf("Invalid error component: %s\n", component);
+		return;
+	}
+
+	printf("Usage: pdbg inject %s <error>:\n", err_comp->name);
+	printf(" <error>:\n");
+	printf("  %-15s %s\n", "?", "Show error list");
+	list_for_each(&err_comp->err_type_list, err_type, error_link)
+		printf("  %-15s %s\n", err_type->name, err_type->desc);
 }
 
 static void inject_errors(char *component, char *error)
 {
-	/* TODO: Inject errors */
-}
+	struct error_comp *err_comp = NULL;
+	struct error_type *err_type = NULL;
+	struct pdbg_target *target;
 
+	err_comp = get_error_component(component);
+	if (!err_comp) {
+		printf("Invalid error component: %s\n", component);
+		return;
+	}
+
+	err_type = get_error_type(err_comp, error);
+	if (!err_type) {
+		printf("Invalid error type %s for %s\n", error, component);
+		return;
+	}
+
+	for_each_path_target(target) {
+		if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
+			continue;
+
+		err_type->inject_error(target, err_type->data);
+	}
+}
 
 static void error_inject_init(void)
 {
diff --git a/src/err_inject.h b/src/err_inject.h
new file mode 100644
index 0000000..76acee7
--- /dev/null
+++ b/src/err_inject.h
@@ -0,0 +1,20 @@ 
+#ifndef __ERR_INJECT_H
+#define __ERR_INJECT_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef int (*inject_error_t)(struct pdbg_target *target, void *data);
+
+/**
+ * @brief Register error injections that can be used through pdbg inject
+ *        command
+ * @param[in] component  Name of error component.
+ * @param[in] error      Name of error type under given component.
+ * @param[in] error_desc Description of error to be injected.
+ * @param[in] func       Error injection routine
+ * @param[in] data       Opaque data pointer passed to func.
+ */
+extern int register_error_inject(char *component, char *error,
+			char *error_desc, inject_error_t func, void *data);
+#endif