[lvm-devel] [PATCH 1/2] Add cmd logging for liblvm error reporting: All logging functions have an additional argument: The error code

Thomas Woerner twoerner at redhat.com
Wed Jul 15 16:21:35 UTC 2009


Signed-off-by: Thomas Woerner <twoerner at redhat.com>
---
 daemons/clvmd/lvm-functions.c |    7 +++++-
 lib/commands/toolcontext.c    |   26 ++++++++++++---------
 lib/commands/toolcontext.h    |    6 +++++
 lib/log/log.c                 |   51 +++++++++++++++++++++++++++++++++++++----
 lib/log/log.h                 |   18 ++++++++------
 lib/log/lvm-logging.h         |   11 ++++++--
 libdm/misc/dm-logging.h       |    6 ++--
 libdm/mm/dbg_malloc.c         |    2 +-
 liblvm/lvm.h                  |    3 ++
 liblvm/lvm_base.c             |   17 ++++++++++++-
 tools/lvmcmdline.c            |    5 ++++
 11 files changed, 118 insertions(+), 34 deletions(-)

diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index d559b3a..028698c 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -788,7 +788,12 @@ void lvm_do_backup(const char *vgname)
 int init_lvm(int using_gulm)
 {
 	if (!(cmd = create_toolcontext(1, NULL))) {
-		log_error("Failed to allocate command context");
+		log_error(LVM_GEN_ERR, "Failed to allocate command context");
+		return 0;
+	}
+
+	if (lvm_error(cmd) != 0) {
+		log_error(LVM_GEN_ERR, "Failed to create command context");
 		return 0;
 	}
 
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 17b168a..bfe1ad5 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -190,7 +190,7 @@ static void _init_logging(struct cmd_context *cmd)
 
 	/* Tell device-mapper about our logging */
 #ifdef DEVMAPPER_SUPPORT
-	dm_log_init(print_log);
+	dm_log_with_errno_init(print_log);
 #endif
 }
 
@@ -1083,6 +1083,9 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
 	dm_list_init(&cmd->tags);
 	dm_list_init(&cmd->config_files);
 
+	/* Log to command */
+	init_log_cmd(cmd);
+
 	/*
 	 * Environment variable LVM_SYSTEM_DIR overrides this below.
 	 */
@@ -1164,16 +1167,7 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
 	return cmd;
 
       error:
-	_destroy_tag_configs(cmd);
-	dev_cache_exit();
-	if (cmd->filter)
-		cmd->filter->destroy(cmd->filter);
-	if (cmd->mem)
-		dm_pool_destroy(cmd->mem);
-	if (cmd->libmem)
-		dm_pool_destroy(cmd->libmem);
-	dm_free(cmd);
-	return NULL;
+	return cmd;
 }
 
 static void _destroy_formats(struct dm_list *formats)
@@ -1318,3 +1312,13 @@ void destroy_toolcontext(struct cmd_context *cmd)
 	fin_log();
 	fin_syslog();
 }
+
+int cmd_error(struct cmd_context *cmd)
+{
+	return cmd->error;
+}
+
+const char *cmd_strerror(struct cmd_context *cmd)
+{
+	return cmd->err_string;
+}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 374b38f..41f947a 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -92,6 +92,9 @@ struct cmd_context {
 	char dev_dir[PATH_MAX];
 	char proc_dir[PATH_MAX];
 	char sysfs_dir[PATH_MAX];
+
+	int error;
+	char err_string[8192]; /* fixed size error srting */
 };
 
 /*
@@ -105,4 +108,7 @@ int refresh_toolcontext(struct cmd_context *cmd);
 int config_files_changed(struct cmd_context *cmd);
 int init_lvmcache_orphans(struct cmd_context *cmd);
 
+int cmd_error(struct cmd_context *cmd);
+const char *cmd_strerror(struct cmd_context *cmd);
+
 #endif
diff --git a/lib/log/log.c b/lib/log/log.c
index 1f67b3f..9b692d6 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -19,6 +19,7 @@
 #include "lvm-string.h"
 #include "lvm-file.h"
 #include "defaults.h"
+#include "toolcontext.h"
 
 #include <stdarg.h>
 #include <syslog.h>
@@ -37,6 +38,7 @@ static char _msg_prefix[30] = "  ";
 static int _already_logging = 0;
 
 static lvm2_log_fn_t _lvm2_log_fn = NULL;
+static struct cmd_context *_lvm_log_cmd = NULL;
 
 void init_log_fn(lvm2_log_fn_t log_fn)
 {
@@ -69,6 +71,31 @@ void init_log_direct(const char *log_file, int append)
 	_log_direct = 1;
 }
 
+void init_log_cmd(struct cmd_context *cmd)
+{
+	if (_lvm_log_cmd != NULL) {
+		fprintf(stderr, "Already logging to a context.\n");
+		return;
+	}
+
+	_lvm_log_cmd = cmd;
+}
+
+void release_log_cmd(struct cmd_context *cmd)
+{
+	if (cmd == _lvm_log_cmd)
+		_lvm_log_cmd = NULL;
+}
+
+void reset_log_cmd(struct cmd_context *cmd)
+{
+	if (_lvm_log_cmd == NULL)
+		return;
+
+	_lvm_log_cmd->error = 0;
+	memset(_lvm_log_cmd->err_string, 0, sizeof(_lvm_log_cmd->err_string));
+}
+
 void init_log_while_suspended(int log_while_suspended)
 {
 	_log_while_suspended = log_while_suspended;
@@ -136,7 +163,7 @@ void init_indent(int indent)
 	_indent = indent;
 }
 
-void print_log(int level, const char *file, int line, const char *format, ...)
+void print_log(int level, const char *file, int line, int code, const char *format, ...)
 {
 	va_list ap;
 	char buf[1024], buf2[4096], locn[4096];
@@ -155,7 +182,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
 
 	trformat = _(format);
 
-	if (_lvm2_log_fn) {
+	if (_lvm2_log_fn || (_lvm_log_cmd && level == _LOG_ERR)) {
 		va_start(ap, format);
 		n = vsnprintf(buf2, sizeof(buf2) - 1, trformat, ap);
 		va_end(ap);
@@ -169,9 +196,23 @@ void print_log(int level, const char *file, int line, const char *format, ...)
 		buf2[sizeof(buf2) - 1] = '\0';
 		message = &buf2[0];
 
-		_lvm2_log_fn(level, file, line, message);
-
-		return;
+		if (_lvm_log_cmd && level == _LOG_ERR) {
+			if (_lvm_log_cmd->error == 0) {
+				_lvm_log_cmd->error = code;
+				_lvm_log_cmd->err_string[0] = '\0';
+				strncpy(_lvm_log_cmd->err_string, message,
+					sizeof(_lvm_log_cmd->err_string));
+			} else {
+				int l = strlen(_lvm_log_cmd->err_string);
+				strncat(_lvm_log_cmd->err_string + l, message,
+					sizeof(_lvm_log_cmd->err_string) - l);
+			}
+			_lvm_log_cmd->err_string[sizeof(_lvm_log_cmd->err_string) - 1] = '\0';			
+		}
+		if (_lvm2_log_fn) {
+			_lvm2_log_fn(level, file, line, message);
+			return;
+		}
 	}
 
       log_it:
diff --git a/lib/log/log.h b/lib/log/log.h
index 110f1b0..e0dcd26 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -50,22 +50,24 @@
 #define _LOG_ERR 3
 #define _LOG_FATAL 2
 
-#define log_debug(x...) LOG_LINE(_LOG_DEBUG, x)
-#define log_info(x...) LOG_LINE(_LOG_INFO, x)
-#define log_notice(x...) LOG_LINE(_LOG_NOTICE, x)
-#define log_warn(x...) LOG_LINE(_LOG_WARN | _LOG_STDERR, x)
-#define log_err(x...) LOG_LINE(_LOG_ERR, x)
-#define log_fatal(x...) LOG_LINE(_LOG_FATAL, x)
+#define LVM_GEN_ERR -1
+
+#define log_debug(x...) LOG_LINE(_LOG_DEBUG, 0, x)
+#define log_info(x...) LOG_LINE(_LOG_INFO, 0, x)
+#define log_notice(x...) LOG_LINE(_LOG_NOTICE, 0, x)
+#define log_warn(x...) LOG_LINE(_LOG_WARN | _LOG_STDERR, 0, x)
+#define log_err(c, x...) LOG_LINE(_LOG_ERR, c, x)
+#define log_fatal(x...) LOG_LINE(_LOG_FATAL, 0, x)
 
 #define stack log_debug("<backtrace>")	/* Backtrace on error */
 #define log_very_verbose(args...) log_info(args)
 #define log_verbose(args...) log_notice(args)
-#define log_print(args...) LOG_LINE(_LOG_WARN, args)
+#define log_print(args...) LOG_LINE(_LOG_WARN, 0, args)
 #define log_error(args...) log_err(args)
 
 /* System call equivalents */
 #define log_sys_error(x, y) \
-		log_err("%s: %s failed: %s", y, x, strerror(errno))
+		log_err(errno, "%s: %s failed: %s", y, x, strerror(errno))
 #define log_sys_very_verbose(x, y) \
 		log_info("%s: %s failed: %s", y, x, strerror(errno))
 #define log_sys_debug(x, y) \
diff --git a/lib/log/lvm-logging.h b/lib/log/lvm-logging.h
index d267e23..3b67813 100644
--- a/lib/log/lvm-logging.h
+++ b/lib/log/lvm-logging.h
@@ -16,13 +16,15 @@
 #ifndef _LVM_LOGGING_H
 #define _LVM_LOGGING_H
 
-void print_log(int level, const char *file, int line, const char *format, ...)
-    __attribute__ ((format(printf, 4, 5)));
+void print_log(int level, const char *file, int line, int code, const char *format, ...)
+    __attribute__ ((format(printf, 5, 6)));
 
-#define LOG_LINE(l, x...) print_log(l, __FILE__, __LINE__ , ## x)
+#define LOG_LINE(l, c, x...) print_log(l, __FILE__, __LINE__ , c, ## x)
 
 #include "log.h"
 
+struct cmd_context;
+
 typedef void (*lvm2_log_fn_t) (int level, const char *file, int line,
 			       const char *message);
 
@@ -34,14 +36,17 @@ void init_msg_prefix(const char *prefix);
 void init_log_file(const char *log_file, int append);
 void init_log_direct(const char *log_file, int append);
 void init_log_while_suspended(int log_while_suspended);
+void init_log_cmd(struct cmd_context *cmd);
 
 void fin_log(void);
 void release_log_memory(void);
+void release_log_cmd(struct cmd_context *cmd);
 
 void init_syslog(int facility);
 void fin_syslog(void);
 
 int error_message_produced(void);
+void reset_log_cmd(struct cmd_context *cmd);
 
 /* Suppress messages to stdout/stderr (1) or everywhere (2) */
 /* Returns previous setting */
diff --git a/libdm/misc/dm-logging.h b/libdm/misc/dm-logging.h
index ee3ed34..d3d2094 100644
--- a/libdm/misc/dm-logging.h
+++ b/libdm/misc/dm-logging.h
@@ -21,15 +21,15 @@
 extern dm_log_fn dm_log;
 extern dm_log_with_errno_fn dm_log_with_errno;
 
-#define LOG_MESG(l, f, ln, x...) \
+#define LOG_MESG(l, f, ln, c, x...)		\
 	do { \
 		if (dm_log_is_non_default()) \
 			dm_log(l, f, ln, ## x); \
 		else \
-			dm_log_with_errno(l, f, ln, 0, ## x); \
+			dm_log_with_errno(l, f, ln, c, ## x); \
 	} while (0)
 
-#define LOG_LINE(l, x...) LOG_MESG(l, __FILE__, __LINE__, ## x)
+#define LOG_LINE(l, c, x...) LOG_MESG(l, __FILE__, __LINE__, c, ## x)
 
 #include "log.h"
 
diff --git a/libdm/mm/dbg_malloc.c b/libdm/mm/dbg_malloc.c
index ea97208..3c51b61 100644
--- a/libdm/mm/dbg_malloc.c
+++ b/libdm/mm/dbg_malloc.c
@@ -205,7 +205,7 @@ int dm_dump_memory_debug(void)
 		}
 		str[sizeof(str) - 1] = '\0';
 
-		LOG_MESG(_LOG_INFO, mb->file, mb->line,
+		LOG_MESG(_LOG_INFO, mb->file, mb->line, LVM_GEN_ERR,
 			 "block %d at %p, size %" PRIsize_t "\t [%s]",
 			 mb->id, mb->magic, mb->length, str);
 		tot += mb->length;
diff --git a/liblvm/lvm.h b/liblvm/lvm.h
index 19ab5dd..83a85de 100644
--- a/liblvm/lvm.h
+++ b/liblvm/lvm.h
@@ -71,6 +71,9 @@ void lvm_destroy(lvm_t libh);
  */
 int lvm_reload_config(lvm_t libh);
 
+int lvm_error(lvm_t libh);
+const char *lvm_strerror(lvm_t libh);
+
 /**
  * Create a VG with default parameters.
  *
diff --git a/liblvm/lvm_base.c b/liblvm/lvm_base.c
index 4fa8541..2bf72d6 100644
--- a/liblvm/lvm_base.c
+++ b/liblvm/lvm_base.c
@@ -30,6 +30,9 @@ lvm_t lvm_create(const char *system_dir)
 	if (!cmd)
 		return NULL;
 	/*
+	if (cmd_error(cmd) != 0)
+		return (lvm_t) cmd;
+
 	 * FIXME: if an non memory error occured, return the cmd (maybe some
 	 * cleanup needed).
 	 */
@@ -58,11 +61,21 @@ lvm_t lvm_create(const char *system_dir)
 void lvm_destroy(lvm_t libh)
 {
 	/* FIXME: error handling */
-	destroy_toolcontext((struct cmd_context *)libh);
+	destroy_toolcontext((struct cmd_context *) libh);
 }
 
 int lvm_reload_config(lvm_t libh)
 {
 	/* FIXME: re-init locking needed here? */
-	return refresh_toolcontext((struct cmd_context *)libh);
+	return refresh_toolcontext((struct cmd_context *) libh);
+}
+
+int lvm_error(lvm_t libh)
+{
+	return cmd_error((struct cmd_context *) libh);
+}
+
+const char *lvm_strerror(lvm_t libh)
+{
+	return cmd_strerror((struct cmd_context *) libh);
 }
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 10cbb12..283d139 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1179,6 +1179,11 @@ struct cmd_context *init_lvm(void)
 	if (!(cmd = create_toolcontext(0, NULL)))
 		return_NULL;
 
+	if (cmd_error(cmd) != 0) {
+		destroy_toolcontext(cmd);
+		return_NULL;
+	}
+
 	return cmd;
 }
 
-- 
1.6.2.5




More information about the lvm-devel mailing list