d9e469
From c6ed1e1af9356cdce1eaa652061dd6e4eb32d283 Mon Sep 17 00:00:00 2001
d9e469
From: Junliang Li <lijunliang.dna@gmail.com>
d9e469
Date: Thu, 13 Feb 2014 10:39:53 +0800
d9e469
Subject: [PATCH 23/32] add abrt suppport for rasdaemon
d9e469
d9e469
Adds abrt as another error mechanism for the rasdaemon.
d9e469
This patch does:
d9e469
d9e469
1) read ras event (mc,mce and aer)
d9e469
d9e469
2) setup a abrt-server unix socket
d9e469
d9e469
3) write messages follow ABRT server protocol, set event
d9e469
   info into backtrace zone.
d9e469
d9e469
4) commit report.
d9e469
d9e469
For now, it depends on ABRT to limit flood reports.
d9e469
d9e469
Signed-off-by: Junliang Li <lijunliang.dna@gmail.com>
d9e469
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
d9e469
---
d9e469
 Makefile.am       |    5 +-
d9e469
 configure.ac      |    9 +
d9e469
 ras-aer-handler.c |    6 +
d9e469
 ras-events.h      |    3 +
d9e469
 ras-mc-handler.c  |    7 +
d9e469
 ras-mce-handler.c |    6 +
d9e469
 ras-report.c      |  429 +++++++++++++++++++++++++++++++++++++++++++++++++++++
d9e469
 ras-report.h      |   39 +++++
d9e469
 8 files changed, 503 insertions(+), 1 deletions(-)
d9e469
 create mode 100644 ras-report.c
d9e469
 create mode 100644 ras-report.h
d9e469
d9e469
diff --git a/Makefile.am b/Makefile.am
d9e469
index 473ce98..c1668b4 100644
d9e469
--- a/Makefile.am
d9e469
+++ b/Makefile.am
d9e469
@@ -17,10 +17,13 @@ if WITH_MCE
d9e469
 			mce-intel-dunnington.c mce-intel-tulsa.c \
d9e469
 			mce-intel-sb.c mce-intel-ivb.c
d9e469
 endif
d9e469
+if WITH_ABRT_REPORT
d9e469
+   rasdaemon_SOURCES += ras-report.c
d9e469
+endif
d9e469
 rasdaemon_LDADD = -lpthread $(SQLITE3_LIBS) libtrace/libtrace.a
d9e469
 
d9e469
 include_HEADERS = config.h  ras-events.h  ras-logger.h  ras-mc-handler.h \
d9e469
-		  ras-aer-handler.h ras-mce-handler.h ras-record.h bitfield.h
d9e469
+		  ras-aer-handler.h ras-mce-handler.h ras-record.h bitfield.h ras-report.h
d9e469
 
d9e469
 # This rule can't be called with more than one Makefile job (like make -j8)
d9e469
 # I can't figure out a way to fix that
d9e469
diff --git a/configure.ac b/configure.ac
d9e469
index 4fe6ef2..0ea962e 100644
d9e469
--- a/configure.ac
d9e469
+++ b/configure.ac
d9e469
@@ -53,6 +53,15 @@ AS_IF([test "x$enable_mce" = "xyes"], [
d9e469
 ])
d9e469
 AM_CONDITIONAL([WITH_MCE], [test x$enable_mce = xyes])
d9e469
 
d9e469
+AC_ARG_ENABLE([abrt_report],
d9e469
+    AS_HELP_STRING([--enable-abrt-report], [enable report event to ABRT (currently experimental)]))
d9e469
+
d9e469
+AS_IF([test "x$enable_abrt_report" = "xyes"], [
d9e469
+  AC_DEFINE(HAVE_ABRT_REPORT,1,"have report event to ABRT")
d9e469
+  AC_SUBST([WITH_ABRT_REPORT])
d9e469
+])
d9e469
+AM_CONDITIONAL([WITH_ABRT_REPORT], [test x$enable_abrt_report = xyes])
d9e469
+
d9e469
 test "$sysconfdir" = '${prefix}/etc' && sysconfdir=/etc
d9e469
 
d9e469
 CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -Wstrict-prototypes"
d9e469
diff --git a/ras-aer-handler.c b/ras-aer-handler.c
d9e469
index e5abaca..50526af 100644
d9e469
--- a/ras-aer-handler.c
d9e469
+++ b/ras-aer-handler.c
d9e469
@@ -24,6 +24,7 @@
d9e469
 #include "ras-record.h"
d9e469
 #include "ras-logger.h"
d9e469
 #include "bitfield.h"
d9e469
+#include "ras-report.h"
d9e469
 
d9e469
 static const char *aer_errors[32] = {
d9e469
 	/* Correctable errors */
d9e469
@@ -115,5 +116,10 @@ int ras_aer_event_handler(struct trace_seq *s,
d9e469
 	ras_store_aer_event(ras, &ev;;
d9e469
 #endif
d9e469
 
d9e469
+#ifdef HAVE_ABRT_REPORT
d9e469
+	/* Report event to ABRT */
d9e469
+	ras_report_aer_event(ras, &ev;;
d9e469
+#endif
d9e469
+
d9e469
 	return 0;
d9e469
 }
d9e469
diff --git a/ras-events.h b/ras-events.h
d9e469
index 554a95e..64e045a 100644
d9e469
--- a/ras-events.h
d9e469
+++ b/ras-events.h
d9e469
@@ -47,6 +47,9 @@ struct ras_events {
d9e469
 
d9e469
 	/* For the mce handler */
d9e469
 	struct mce_priv	*mce_priv;
d9e469
+
d9e469
+	/* For ABRT socket*/
d9e469
+	int socketfd;
d9e469
 };
d9e469
 
d9e469
 struct pthread_data {
d9e469
diff --git a/ras-mc-handler.c b/ras-mc-handler.c
d9e469
index 5c24f65..ffb3805 100644
d9e469
--- a/ras-mc-handler.c
d9e469
+++ b/ras-mc-handler.c
d9e469
@@ -23,6 +23,7 @@
d9e469
 #include "ras-mc-handler.h"
d9e469
 #include "ras-record.h"
d9e469
 #include "ras-logger.h"
d9e469
+#include "ras-report.h"
d9e469
 
d9e469
 int ras_mc_event_handler(struct trace_seq *s,
d9e469
 			 struct pevent_record *record,
d9e469
@@ -189,6 +190,12 @@ int ras_mc_event_handler(struct trace_seq *s,
d9e469
 	/* Insert data into the SGBD */
d9e469
 
d9e469
 	ras_store_mc_event(ras, &ev;;
d9e469
+
d9e469
+#ifdef HAVE_ABRT_REPORT
d9e469
+	/* Report event to ABRT */
d9e469
+	ras_report_mc_event(ras, &ev;;
d9e469
+#endif
d9e469
+
d9e469
 	return 0;
d9e469
 
d9e469
 parse_error:
d9e469
diff --git a/ras-mce-handler.c b/ras-mce-handler.c
d9e469
index 59e8d05..1431049 100644
d9e469
--- a/ras-mce-handler.c
d9e469
+++ b/ras-mce-handler.c
d9e469
@@ -26,6 +26,7 @@
d9e469
 #include "ras-mce-handler.h"
d9e469
 #include "ras-record.h"
d9e469
 #include "ras-logger.h"
d9e469
+#include "ras-report.h"
d9e469
 
d9e469
 /*
d9e469
  * The code below were adapted from Andi Kleen/Intel/SuSe mcelog code,
d9e469
@@ -401,5 +402,10 @@ int ras_mce_event_handler(struct trace_seq *s,
d9e469
 	ras_store_mce_record(ras, &e);
d9e469
 #endif
d9e469
 
d9e469
+#ifdef HAVE_ABRT_REPORT
d9e469
+	/* Report event to ABRT */
d9e469
+	ras_report_mce_event(ras, &e);
d9e469
+#endif
d9e469
+
d9e469
 	return 0;
d9e469
 }
d9e469
diff --git a/ras-report.c b/ras-report.c
d9e469
new file mode 100644
d9e469
index 0000000..d3e4a79
d9e469
--- /dev/null
d9e469
+++ b/ras-report.c
d9e469
@@ -0,0 +1,429 @@
d9e469
+#include <stdio.h>
d9e469
+#include <string.h>
d9e469
+#include <unistd.h>
d9e469
+#include <sys/types.h>
d9e469
+#include <sys/utsname.h>
d9e469
+#include <sys/socket.h>
d9e469
+#include <sys/un.h>
d9e469
+
d9e469
+#include "ras-report.h"
d9e469
+
d9e469
+static int setup_report_socket(void){
d9e469
+	int sockfd = -1;
d9e469
+	int rc = -1;
d9e469
+	struct sockaddr_un addr;
d9e469
+
d9e469
+	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
d9e469
+	if (sockfd < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	memset(&addr, 0, sizeof(struct sockaddr_un));
d9e469
+	addr.sun_family = AF_UNIX;
d9e469
+	strncpy(addr.sun_path, ABRT_SOCKET, strlen(ABRT_SOCKET));
d9e469
+
d9e469
+	rc = connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un));
d9e469
+	if (rc < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	return sockfd;
d9e469
+}
d9e469
+
d9e469
+static int commit_report_basic(int sockfd){
d9e469
+	char buf[INPUT_BUFFER_SIZE];
d9e469
+	struct utsname un;
d9e469
+	int rc = -1;
d9e469
+
d9e469
+	if(sockfd < 0){
d9e469
+		return rc;
d9e469
+	}
d9e469
+
d9e469
+	memset(buf, 0, INPUT_BUFFER_SIZE);
d9e469
+	memset(&un, 0, sizeof(struct utsname));
d9e469
+
d9e469
+	rc = uname(&un;;
d9e469
+	if(rc < 0){
d9e469
+		return rc;
d9e469
+	}
d9e469
+
d9e469
+	/*
d9e469
+	 * ABRT server protocol
d9e469
+	 */
d9e469
+	sprintf(buf, "PUT / HTTP/1.1\r\n\r\n");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "PID=%d", (int)getpid());
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "EXECUTABLE=/boot/vmlinuz-%s", un.release);
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "BASENAME=%s", "rasdaemon");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	return 0;
d9e469
+}
d9e469
+
d9e469
+/*
d9e469
+ *  add "DONE" string to finish message.
d9e469
+ */
d9e469
+static int commit_report_done(int sockfd){
d9e469
+	int rc = -1;
d9e469
+
d9e469
+	if(sockfd < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	rc = write(sockfd, "DONE\0", strlen("DONE\0"));
d9e469
+	if(rc < strlen("DONE\0")){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	return 0;
d9e469
+}
d9e469
+
d9e469
+static int set_mc_event_backtrace(char *buf, struct ras_mc_event *ev){
d9e469
+	char bt_buf[MAX_BACKTRACE_SIZE];
d9e469
+
d9e469
+	if(!buf || !ev)
d9e469
+		return -1;
d9e469
+
d9e469
+	sprintf(bt_buf, "BACKTRACE= "	\
d9e469
+						"timestamp=%s\n"	\
d9e469
+						"error_count=%d\n"	\
d9e469
+						"error_type=%s\n"	\
d9e469
+						"msg=%s\n"	\
d9e469
+						"label=%s\n"	\
d9e469
+						"mc_index=%c\n"	\
d9e469
+						"top_layer=%c\n"	\
d9e469
+						"middle_layer=%c\n"	\
d9e469
+						"lower_layer=%c\n"	\
d9e469
+						"address=%llu\n"	\
d9e469
+						"grain=%llu\n"	\
d9e469
+						"syndrome=%llu\n"	\
d9e469
+						"driver_detail=%s\n",	\
d9e469
+						ev->timestamp,	\
d9e469
+						ev->error_count,	\
d9e469
+						ev->error_type,	\
d9e469
+						ev->msg,	\
d9e469
+						ev->label,	\
d9e469
+						ev->mc_index,	\
d9e469
+						ev->top_layer,	\
d9e469
+						ev->middle_layer,	\
d9e469
+						ev->lower_layer,	\
d9e469
+						ev->address,	\
d9e469
+						ev->grain,	\
d9e469
+						ev->syndrome,	\
d9e469
+						ev->driver_detail);
d9e469
+
d9e469
+	strcat(buf, bt_buf);
d9e469
+
d9e469
+	return 0;
d9e469
+}
d9e469
+
d9e469
+static int set_mce_event_backtrace(char *buf, struct mce_event *ev){
d9e469
+	char bt_buf[MAX_BACKTRACE_SIZE];
d9e469
+
d9e469
+	if(!buf || !ev)
d9e469
+		return -1;
d9e469
+
d9e469
+	sprintf(bt_buf, "BACKTRACE="	\
d9e469
+						"timestamp=%s\n"	\
d9e469
+						"bank_name=%s\n"	\
d9e469
+						"error_msg=%s\n"	\
d9e469
+						"mcgstatus_msg=%s\n"	\
d9e469
+						"mcistatus_msg=%s\n"	\
d9e469
+						"mcastatus_msg=%s\n"	\
d9e469
+						"user_action=%s\n"	\
d9e469
+						"mc_location=%s\n"	\
d9e469
+						"mcgcap=%lu\n"	\
d9e469
+						"mcgstatus=%lu\n"	\
d9e469
+						"status=%lu\n"	\
d9e469
+						"addr=%lu\n"	\
d9e469
+						"misc=%lu\n"	\
d9e469
+						"ip=%lu\n"	\
d9e469
+						"tsc=%lu\n"	\
d9e469
+						"walltime=%lu\n"	\
d9e469
+						"cpu=%u\n"	\
d9e469
+						"cpuid=%u\n"	\
d9e469
+						"apicid=%u\n"	\
d9e469
+						"socketid=%u\n"	\
d9e469
+						"cs=%d\n"	\
d9e469
+						"bank=%d\n"	\
d9e469
+						"cpuvendor=%d\n",	\
d9e469
+						ev->timestamp,	\
d9e469
+						ev->bank_name,	\
d9e469
+						ev->error_msg,	\
d9e469
+						ev->mcgstatus_msg,	\
d9e469
+						ev->mcistatus_msg,	\
d9e469
+						ev->mcastatus_msg,	\
d9e469
+						ev->user_action,	\
d9e469
+						ev->mc_location,	\
d9e469
+						ev->mcgcap,	\
d9e469
+						ev->mcgstatus,	\
d9e469
+						ev->status,	\
d9e469
+						ev->addr,	\
d9e469
+						ev->misc,	\
d9e469
+						ev->ip,	\
d9e469
+						ev->tsc,	\
d9e469
+						ev->walltime,	\
d9e469
+						ev->cpu,	\
d9e469
+						ev->cpuid,	\
d9e469
+						ev->apicid,	\
d9e469
+						ev->socketid,	\
d9e469
+						ev->cs,	\
d9e469
+						ev->bank,	\
d9e469
+						ev->cpuvendor);
d9e469
+
d9e469
+	strcat(buf, bt_buf);
d9e469
+
d9e469
+	return 0;
d9e469
+}
d9e469
+
d9e469
+static int set_aer_event_backtrace(char *buf, struct ras_aer_event *ev){
d9e469
+	char bt_buf[MAX_BACKTRACE_SIZE];
d9e469
+
d9e469
+	if(!buf || !ev)
d9e469
+		return -1;
d9e469
+
d9e469
+	sprintf(bt_buf, "BACKTRACE="	\
d9e469
+						"timestamp=%s\n"	\
d9e469
+						"error_type=%s\n"	\
d9e469
+						"dev_name=%s\n"	\
d9e469
+						"msg=%s\n",	\
d9e469
+						ev->timestamp,	\
d9e469
+						ev->error_type,	\
d9e469
+						ev->dev_name,	\
d9e469
+						ev->msg);
d9e469
+
d9e469
+	strcat(buf, bt_buf);
d9e469
+
d9e469
+	return 0;
d9e469
+}
d9e469
+
d9e469
+static int commit_report_backtrace(int sockfd, int type, void *ev){
d9e469
+	char buf[MAX_BACKTRACE_SIZE];
d9e469
+	char *pbuf = buf;
d9e469
+	int rc = -1;
d9e469
+	int buf_len = 0;
d9e469
+
d9e469
+	if(sockfd < 0 || !ev){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	memset(buf, 0, MAX_BACKTRACE_SIZE);
d9e469
+
d9e469
+	switch(type){
d9e469
+	case MC_EVENT:
d9e469
+		rc = set_mc_event_backtrace(buf, (struct ras_mc_event *)ev);
d9e469
+		break;
d9e469
+	case AER_EVENT:
d9e469
+		rc = set_aer_event_backtrace(buf, (struct ras_aer_event *)ev);
d9e469
+		break;
d9e469
+	case MCE_EVENT:
d9e469
+		rc = set_mce_event_backtrace(buf, (struct mce_event *)ev);
d9e469
+		break;
d9e469
+	default:
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	if(rc < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	buf_len = strlen(buf);
d9e469
+
d9e469
+	for(;buf_len > INPUT_BUFFER_SIZE - 1; buf_len -= (INPUT_BUFFER_SIZE - 1)){
d9e469
+		rc = write(sockfd, pbuf, INPUT_BUFFER_SIZE - 1);
d9e469
+		if(rc < INPUT_BUFFER_SIZE - 1){
d9e469
+			return -1;
d9e469
+		}
d9e469
+
d9e469
+		pbuf = pbuf + INPUT_BUFFER_SIZE - 1;
d9e469
+	}
d9e469
+
d9e469
+	rc = write(sockfd, pbuf, buf_len + 1);
d9e469
+	if(rc < buf_len){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	return 0;
d9e469
+}
d9e469
+
d9e469
+int ras_report_mc_event(struct ras_events *ras, struct ras_mc_event *ev){
d9e469
+	char buf[MAX_MESSAGE_SIZE];
d9e469
+	int sockfd = -1;
d9e469
+	int done = 0;
d9e469
+	int rc = -1;
d9e469
+
d9e469
+	memset(buf, 0, sizeof(buf));
d9e469
+
d9e469
+	sockfd = setup_report_socket();
d9e469
+	if(sockfd < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_basic(sockfd);
d9e469
+	if(rc < 0){
d9e469
+		goto mc_fail;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_backtrace(sockfd, MC_EVENT, ev);
d9e469
+	if(rc < 0){
d9e469
+		goto mc_fail;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "ANALYZER=%s", "rasdaemon-mc");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		goto mc_fail;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "REASON=%s", "EDAC driver report problem");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		goto mc_fail;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_done(sockfd);
d9e469
+	if(rc < 0){
d9e469
+		goto mc_fail;
d9e469
+	}
d9e469
+
d9e469
+	done = 1;
d9e469
+
d9e469
+mc_fail:
d9e469
+
d9e469
+	if(sockfd > 0){
d9e469
+		close(sockfd);
d9e469
+	}
d9e469
+
d9e469
+	if(done){
d9e469
+		return 0;
d9e469
+	}else{
d9e469
+		return -1;
d9e469
+	}
d9e469
+}
d9e469
+
d9e469
+int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev){
d9e469
+	char buf[MAX_MESSAGE_SIZE];
d9e469
+	int sockfd = 0;
d9e469
+	int done = 0;
d9e469
+	int rc = -1;
d9e469
+
d9e469
+	memset(buf, 0, sizeof(buf));
d9e469
+
d9e469
+	sockfd = setup_report_socket();
d9e469
+	if(sockfd < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_basic(sockfd);
d9e469
+	if(rc < 0){
d9e469
+		goto aer_fail;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_backtrace(sockfd, AER_EVENT, ev);
d9e469
+	if(rc < 0){
d9e469
+		goto aer_fail;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "ANALYZER=%s", "rasdaemon-aer");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		goto aer_fail;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "REASON=%s", "PCIe AER driver report problem");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		goto aer_fail;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_done(sockfd);
d9e469
+	if(rc < 0){
d9e469
+		goto aer_fail;
d9e469
+	}
d9e469
+
d9e469
+	done = 1;
d9e469
+
d9e469
+aer_fail:
d9e469
+
d9e469
+	if(sockfd > 0){
d9e469
+		close(sockfd);
d9e469
+	}
d9e469
+
d9e469
+	if(done){
d9e469
+		return 0;
d9e469
+	}else{
d9e469
+		return -1;
d9e469
+	}
d9e469
+}
d9e469
+
d9e469
+int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev){
d9e469
+	char buf[MAX_MESSAGE_SIZE];
d9e469
+	int sockfd = 0;
d9e469
+	int done = 0;
d9e469
+	int rc = -1;
d9e469
+
d9e469
+	memset(buf, 0, sizeof(buf));
d9e469
+
d9e469
+	sockfd = setup_report_socket();
d9e469
+	if(sockfd < 0){
d9e469
+		return -1;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_basic(sockfd);
d9e469
+	if(rc < 0){
d9e469
+		goto mce_fail;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_backtrace(sockfd, MCE_EVENT, ev);
d9e469
+	if(rc < 0){
d9e469
+		goto mce_fail;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "ANALYZER=%s", "rasdaemon-mce");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		goto mce_fail;
d9e469
+	}
d9e469
+
d9e469
+	sprintf(buf, "REASON=%s", "Machine Check driver report problem");
d9e469
+	rc = write(sockfd, buf, strlen(buf) + 1);
d9e469
+	if(rc < strlen(buf) + 1){
d9e469
+		goto mce_fail;
d9e469
+	}
d9e469
+
d9e469
+	rc = commit_report_done(sockfd);
d9e469
+	if(rc < 0){
d9e469
+		goto mce_fail;
d9e469
+	}
d9e469
+
d9e469
+	done = 1;
d9e469
+
d9e469
+mce_fail:
d9e469
+
d9e469
+	if(sockfd > 0){
d9e469
+		close(sockfd);
d9e469
+	}
d9e469
+
d9e469
+	if(done){
d9e469
+		return 0;
d9e469
+	}else{
d9e469
+		return -1;
d9e469
+	}
d9e469
+}
d9e469
diff --git a/ras-report.h b/ras-report.h
d9e469
new file mode 100644
d9e469
index 0000000..7920cdf
d9e469
--- /dev/null
d9e469
+++ b/ras-report.h
d9e469
@@ -0,0 +1,39 @@
d9e469
+#ifndef __RAS_REPORT_H
d9e469
+#define __RAS_REPORT_H
d9e469
+
d9e469
+#include "ras-record.h"
d9e469
+#include "ras-events.h"
d9e469
+#include "ras-mc-handler.h"
d9e469
+#include "ras-mce-handler.h"
d9e469
+#include "ras-aer-handler.h"
d9e469
+
d9e469
+/* Maximal length of backtrace. */
d9e469
+#define MAX_BACKTRACE_SIZE (1024*1024)
d9e469
+/* Amount of data received from one client for a message before reporting error. */
d9e469
+#define MAX_MESSAGE_SIZE (4*MAX_BACKTRACE_SIZE)
d9e469
+/* Maximal number of characters read from socket at once. */
d9e469
+#define INPUT_BUFFER_SIZE (8*1024)
d9e469
+/* ABRT socket file */
d9e469
+#define ABRT_SOCKET "/var/run/abrt/abrt.socket"
d9e469
+
d9e469
+enum {
d9e469
+	MC_EVENT,
d9e469
+	MCE_EVENT,
d9e469
+	AER_EVENT
d9e469
+};
d9e469
+
d9e469
+#ifdef HAVE_ABRT_REPORT
d9e469
+
d9e469
+int ras_report_mc_event(struct ras_events *ras, struct ras_mc_event *ev);
d9e469
+int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev);
d9e469
+int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev);
d9e469
+
d9e469
+#else
d9e469
+
d9e469
+static inline int ras_report_mc_event(struct ras_events *ras, struct ras_mc_event *ev) { return 0; };
d9e469
+static inline int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev) { return 0; };
d9e469
+static inline int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev) { return 0; };
d9e469
+
d9e469
+#endif
d9e469
+
d9e469
+#endif
d9e469
-- 
d9e469
1.7.1
d9e469