From: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
Date: Mon, 04 Feb 2013 12:39:50 +0530
Subject: [PATCH v4 2/9] makedumpfile and eppic interface layer
References: FATE 313980, bnc 801922

This patch extends the makedumpfile functionality to include eppic
language support. The patch dynamically loads the makedumpfile specific
shared object and calls the eppic_load function in shared object to
load/compile and execute the specified eppic macros.

This patch also includes "--eppic" option to makedumpfile command to
specify the eppic macro or the directory containing eppic macros. The
specified eppic macro will be executed to scrub the data in the
dumpfile. In case of a directory, all the eppic macros inside the
directory will be executed for scrubbing the data.

TODO
	- Support specifying eppic macros in the makedumpfile.conf file.
	  A new command should be added to makedumpfile.conf to identify
	  an eppic macro. This command could be used in any section of
	  the makedumpfile.conf, where the section name indicates the kernel
	  module name. makedumpfile will only search for symbols encountered
	  by eppic macro only in the specified module. Because, searching
	  these symbols in all the modules will cause huge performance
	  overhead.

Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.cz>

---
 erase_info.c   |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 makedumpfile.c |    7 ++++-
 makedumpfile.h |    6 ++++
 3 files changed, 79 insertions(+), 3 deletions(-)

--- a/erase_info.c
+++ b/erase_info.c
@@ -21,6 +21,8 @@
 #include "dwarf_info.h"
 #include "erase_info.h"
 
+#include <dlfcn.h>
+
 struct erase_info	*erase_info = NULL;
 unsigned long		num_erase_info = 1; /* Node 0 is unused. */
 
@@ -1811,6 +1813,59 @@ process_config_file(const char *name_con
 	return TRUE;
 }
 
+
+/* Process the eppic macro using eppic library */
+static int
+process_eppic_file(char *name_config)
+{
+	void *handle;
+	void (*eppic_load)(char *), (*eppic_unload)(char *);
+	int (*eppic_init)();
+
+	/*
+	 * Dynamically load the eppic_makedumpfile.so library.
+	 */
+	handle = dlopen("eppic_makedumpfile.so", RTLD_LAZY);
+	if (!handle) {
+		ERRMSG("dlopen failed: %s\n", dlerror());
+		return FALSE;
+	}
+
+	/* TODO
+	 * Support specifying eppic macros in makedumpfile.conf file
+	 */
+
+	eppic_init = dlsym(handle, "eppic_init");
+	if (!eppic_init) {
+		ERRMSG("Could not find eppic_init function\n");
+		return FALSE;
+	}
+
+	eppic_load = dlsym(handle, "eppic_load");
+	if (!eppic_load) {
+		ERRMSG("Could not find eppic_load function\n");
+		return FALSE;
+	}
+
+	eppic_unload = dlsym(handle, "eppic_unload");
+	if (!eppic_unload)
+		ERRMSG("Could not find eppic_unload function\n");
+
+	if (eppic_init()) {
+		ERRMSG("Init failed \n");
+		return FALSE;
+	}
+
+	/* Load/compile, execute and unload the eppic macro */
+	eppic_load(name_config);
+	eppic_unload(name_config);
+
+	if (dlclose(handle))
+		ERRMSG("dlclose failed: %s\n", dlerror());
+
+	return TRUE;
+}
+
 static void
 split_filter_info(struct filter_info *prev, unsigned long long next_paddr,
 						size_t size)
@@ -1904,7 +1959,7 @@ extract_filter_info(unsigned long long s
 int
 gather_filter_info(void)
 {
-	int ret;
+	int ret = TRUE;
 
 	/*
 	 * Before processing filter config file, load the symbol data of
@@ -1915,7 +1970,17 @@ gather_filter_info(void)
 	if (!load_module_symbols())
 		return FALSE;
 
-	ret = process_config_file(info->name_filterconfig);
+	/*
+	 * XXX: We support specifying both makedumpfile.conf and
+	 * eppic macro at the same time. Whether to retain or discard the
+	 * functionality provided by makedumpfile.conf is open for
+	 * discussion
+	 */
+	if (info->name_filterconfig)
+		ret = process_config_file(info->name_filterconfig);
+
+	if (info->name_eppic_config)
+		ret &= process_eppic_file(info->name_eppic_config);
 
 	/*
 	 * Remove modules symbol information, we dont need now.
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -7371,7 +7371,8 @@ retry:
 		}
 	}
 
-	if (info->name_filterconfig && !gather_filter_info())
+	if ((info->name_filterconfig || info->name_eppic_config)
+			&& !gather_filter_info())
 		return FALSE;
 
 	if (!create_dump_bitmap())
@@ -8269,6 +8270,7 @@ static struct option longopts[] = {
 	{"diskset", required_argument, NULL, 'k'},
 	{"non-cyclic", no_argument, NULL, 'Y'},
 	{"cyclic-buffer", required_argument, NULL, 'Z'},
+	{"eppic", required_argument, NULL, 'S'},
 	{0, 0, 0, 0}
 };
 
@@ -8367,6 +8369,9 @@ main(int argc, char *argv[])
 		case 's':
 			info->flag_split = 1;
 			break;
+		case 'S':
+			info->name_eppic_config = optarg;
+			break;
 		case 'r':
 			info->flag_reassemble = 1;
 			break;
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -910,6 +910,12 @@ struct DumpInfo {
 	FILE		*file_filterconfig;
 
 	/*
+	 * Filter config file containing eppic language filtering rules
+	 * to filter out kernel data from vmcore
+	 */
+	char		*name_eppic_config;
+
+	/*
 	 * diskdimp info:
 	 */
 	int		block_order;
