@@ -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)
@@ -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)
{
new file mode 100644
@@ -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
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