Index: src/zabbix_server/poller/checks_ipmi.c
===================================================================
--- src/zabbix_server/poller/checks_ipmi.c	(revision 56383)
+++ src/zabbix_server/poller/checks_ipmi.c	(working copy)
@@ -32,9 +32,10 @@
 #include "log.h"
 
 #include <OpenIPMI/ipmiif.h>
+#include <OpenIPMI/ipmi_auth.h>
+#include <OpenIPMI/ipmi_err.h>
+#include <OpenIPMI/ipmi_lan.h>
 #include <OpenIPMI/ipmi_posix.h>
-#include <OpenIPMI/ipmi_lan.h>
-#include <OpenIPMI/ipmi_auth.h>
 
 typedef union
 {
@@ -90,6 +91,7 @@
 
 static zbx_ipmi_host_t	*hosts = NULL;
 static os_handler_t	*os_hnd;
+static char		last_err_info[MAX_STRING_LEN];
 
 static char	*sensor_id_to_str(char *str, size_t str_sz, const char *id, enum ipmi_str_type_e id_type, int id_sz)
 {
@@ -431,6 +433,20 @@
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
 }
 
+static void	handle_cb_error(zbx_ipmi_host_t *h, const int err, const char *prefix, const char *fname)
+{
+	char	buffer[MAX_STRING_LEN];
+	char	*str;
+
+	(void)ipmi_get_error_string(err, buffer, MAX_STRING_LEN);
+	zabbix_log(LOG_LEVEL_DEBUG, "%s() fail: %s", fname, buffer);
+
+	h->err = zbx_dsprintf(h->err, "%s: %s (%s)", prefix, buffer, last_err_info);
+	h->ret = NETWORK_ERROR;
+
+	last_err_info[0] = '\0';
+}
+
 /* callback function invoked from OpenIPMI */
 static void	got_thresh_reading(ipmi_sensor_t *sensor, int err, enum ipmi_value_present_e value_present,
 		unsigned int raw_value, double val, ipmi_states_t *states, void *cb_data)
@@ -447,10 +463,7 @@
 
 	if (0 != err)
 	{
-		zabbix_log(LOG_LEVEL_DEBUG, "%s() fail: %s", __function_name, zbx_strerror(err));
-
-		h->err = zbx_dsprintf(h->err, "error 0x%x while reading threshold sensor", err);
-		h->ret = NETWORK_ERROR;
+		handle_cb_error(h, err, "error while reading threshold sensor", __function_name);
 		goto out;
 	}
 
@@ -684,10 +697,7 @@
 
 	if (0 != err)
 	{
-		zabbix_log(LOG_LEVEL_DEBUG, "%s() fail: %s", __function_name, zbx_strerror(err));
-
-		h->err = zbx_dsprintf(h->err, "error 0x%x while reading control", err);
-		h->ret = NETWORK_ERROR;
+		handle_cb_error(h, err, "error while reading control", __function_name);
 		goto out;
 	}
 
@@ -737,10 +747,7 @@
 
 	if (0 != err)
 	{
-		zabbix_log(LOG_LEVEL_DEBUG, "%s() fail: %s", __function_name, zbx_strerror(err));
-
-		h->err = zbx_dsprintf(h->err, "error 0x%x while set control", err);
-		h->ret = NETWORK_ERROR;
+		handle_cb_error(h, err, "error while setting control", __function_name);
 		h->done = 1;
 		return;
 	}
@@ -943,11 +950,8 @@
 
 	if (0 != err)
 	{
-		zabbix_log(LOG_LEVEL_DEBUG, "%s() fail: %s", __function_name, zbx_strerror(err));
+		handle_cb_error(h, err, "cannot connect to IPMI host", __function_name);
 
-		h->err = zbx_dsprintf(h->err, "cannot connect to IPMI host: %s", zbx_strerror(err));
-		h->ret = NETWORK_ERROR;
-
 		if (0 != (ret = ipmi_domain_close(domain, domain_closed, h)))
 			zabbix_log(LOG_LEVEL_DEBUG, "cannot close IPMI domain: [0x%x]", ret);
 
@@ -977,23 +981,48 @@
 static void	my_vlog(os_handler_t *handler, const char *format, enum ipmi_log_type_e log_type, va_list ap)
 {
 	char	type[8], str[MAX_STRING_LEN];
+	int	level = LOG_LEVEL_DEBUG;
 
 	switch (log_type)
 	{
-		case IPMI_LOG_INFO		: zbx_strlcpy(type, "INFO: ", sizeof(type)); break;
-		case IPMI_LOG_WARNING		: zbx_strlcpy(type, "WARN: ", sizeof(type)); break;
-		case IPMI_LOG_SEVERE		: zbx_strlcpy(type, "SEVR: ", sizeof(type)); break;
-		case IPMI_LOG_FATAL		: zbx_strlcpy(type, "FATL: ", sizeof(type)); break;
-		case IPMI_LOG_ERR_INFO		: zbx_strlcpy(type, "EINF: ", sizeof(type)); break;
-		case IPMI_LOG_DEBUG_START	:
-		case IPMI_LOG_DEBUG		: zbx_strlcpy(type, "DEBG: ", sizeof(type)); break;
-		case IPMI_LOG_DEBUG_CONT	:
-		case IPMI_LOG_DEBUG_END		: *type = '\0'; break;
+		case IPMI_LOG_INFO:
+			zbx_strlcpy(type, "INFO: ", sizeof(type));
+			level = LOG_LEVEL_DEBUG;
+			break;
+		case IPMI_LOG_WARNING:
+			zbx_strlcpy(type, "WARN: ", sizeof(type));
+			level = LOG_LEVEL_WARNING;
+			break;
+		case IPMI_LOG_SEVERE:
+			zbx_strlcpy(type, "SEVR: ", sizeof(type));
+			level = LOG_LEVEL_ERR;
+			break;
+		case IPMI_LOG_FATAL:
+			zbx_strlcpy(type, "FATL: ", sizeof(type));
+			level = LOG_LEVEL_CRIT;
+			break;
+		case IPMI_LOG_ERR_INFO:
+			zbx_strlcpy(type, "EINF: ", sizeof(type));
+			level = LOG_LEVEL_DEBUG;
+			break;
+		case IPMI_LOG_DEBUG_START:
+		case IPMI_LOG_DEBUG:
+			zbx_strlcpy(type, "DEBG: ", sizeof(type));
+			level = LOG_LEVEL_DEBUG;
+			break;
+		case IPMI_LOG_DEBUG_CONT:
+		case IPMI_LOG_DEBUG_END:
+			*type = '\0';
+			level = LOG_LEVEL_DEBUG;
+			break;
 	}
 
 	zbx_vsnprintf(str, sizeof(str), format, ap);
 
-	zabbix_log(LOG_LEVEL_DEBUG, "%s%s", type, str);
+	if (IPMI_LOG_ERR_INFO == log_type)
+		zbx_strlcpy(last_err_info, str, sizeof(last_err_info));
+
+	zabbix_log(level, "%s%s", type, str);
 }
 
 int	init_ipmi_handler(void)
