summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW1
-rw-r--r--daemons/clvmd/lvm-functions.c4
-rw-r--r--doc/example_cmdlib.c3
-rw-r--r--lib/commands/toolcontext.c6
-rw-r--r--lib/log/log.c50
-rw-r--r--lib/log/lvm-logging.h12
-rw-r--r--po/pogen.h6
-rw-r--r--tools/lvmcmdline.c2
8 files changed, 70 insertions, 14 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 3589ebbc..7fe3a5b0 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.50 -
================================
+ Store any errno and error messages issued while processing each command.
Use log_error macro consistently throughout in place of log_err.
Version 2.02.49 - 15th July 2009
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index d559b3a1..1be07813 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -714,7 +714,7 @@ static void *get_initial_state()
return NULL;
}
-static void lvm2_log_fn(int level, const char *file, int line,
+static void lvm2_log_fn(int level, const char *file, int line, int dm_errno,
const char *message)
{
@@ -723,7 +723,7 @@ static void lvm2_log_fn(int level, const char *file, int line,
We need to NULL the function ptr otherwise it will just call
back into here! */
init_log_fn(NULL);
- print_log(level, file, line, "%s", message);
+ print_log(level, file, line, dm_errno, "%s", message);
init_log_fn(lvm2_log_fn);
/*
diff --git a/doc/example_cmdlib.c b/doc/example_cmdlib.c
index d251fa92..1fff36e2 100644
--- a/doc/example_cmdlib.c
+++ b/doc/example_cmdlib.c
@@ -15,7 +15,8 @@
#include "lvm2cmd.h"
/* All output gets passed to this function line-by-line */
-void test_log_fn(int level, const char *file, int line, const char *format)
+void test_log_fn(int level, int dm_errno, const char *file, int line,
+ const char *format)
{
/* Extract and process output here rather than printing it */
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index c59ad55c..dc7aa406 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
}
@@ -1161,6 +1161,7 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
cmd->current_settings = cmd->default_settings;
cmd->config_valid = 1;
+ reset_lvm_errno(1); /* FIXME Move to top when cmd returned on error */
return cmd;
error:
@@ -1288,6 +1289,8 @@ int refresh_toolcontext(struct cmd_context *cmd)
persistent_filter_dump(cmd->filter);
cmd->config_valid = 1;
+
+ reset_lvm_errno(1);
return 1;
}
@@ -1317,4 +1320,5 @@ void destroy_toolcontext(struct cmd_context *cmd)
activation_exit();
fin_log();
fin_syslog();
+ reset_lvm_errno(0);
}
diff --git a/lib/log/log.c b/lib/log/log.c
index 1f67b3fe..21163f89 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -38,6 +38,10 @@ static int _already_logging = 0;
static lvm2_log_fn_t _lvm2_log_fn = NULL;
+static int _lvm_errno = 0;
+static int _store_errmsg = 0;
+static char *_lvm_errmsg = NULL;
+
void init_log_fn(lvm2_log_fn_t log_fn)
{
if (log_fn)
@@ -136,13 +140,37 @@ void init_indent(int indent)
_indent = indent;
}
-void print_log(int level, const char *file, int line, const char *format, ...)
+void reset_lvm_errno(int store_errmsg)
+{
+ _lvm_errno = 0;
+
+ if (_lvm_errmsg) {
+ dm_free(_lvm_errmsg);
+ _lvm_errmsg = NULL;
+ }
+
+ _store_errmsg = store_errmsg;
+}
+
+int lvm_errno(void)
+{
+ return _lvm_errno;
+}
+
+const char *lvm_errmsg(void)
+{
+ return _lvm_errmsg ? : "";
+}
+
+void print_log(int level, const char *file, int line, int dm_errno,
+ const char *format, ...)
{
va_list ap;
char buf[1024], buf2[4096], locn[4096];
int bufused, n;
const char *message;
const char *trformat; /* Translated format string */
+ char *newbuf;
int use_stderr = level & _LOG_STDERR;
level &= ~_LOG_STDERR;
@@ -155,7 +183,10 @@ void print_log(int level, const char *file, int line, const char *format, ...)
trformat = _(format);
- if (_lvm2_log_fn) {
+ if (dm_errno && !_lvm_errno)
+ _lvm_errno = dm_errno;
+
+ if (_lvm2_log_fn || (_store_errmsg && (level == _LOG_ERR))) {
va_start(ap, format);
n = vsnprintf(buf2, sizeof(buf2) - 1, trformat, ap);
va_end(ap);
@@ -168,8 +199,21 @@ 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);
+ if (_store_errmsg && (level == _LOG_ERR)) {
+ if (!_lvm_errmsg)
+ _lvm_errmsg = dm_strdup(message);
+ else if ((newbuf = dm_realloc(_lvm_errmsg,
+ strlen(_lvm_errmsg) +
+ strlen(message) + 2))) {
+ _lvm_errmsg = strcat(newbuf, "\n");
+ _lvm_errmsg = strcat(newbuf, message);
+ }
+ }
+
+ if (_lvm2_log_fn) {
+ _lvm2_log_fn(level, file, line, 0, message);
return;
}
diff --git a/lib/log/lvm-logging.h b/lib/log/lvm-logging.h
index d267e233..a0933dd1 100644
--- a/lib/log/lvm-logging.h
+++ b/lib/log/lvm-logging.h
@@ -16,15 +16,16 @@
#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 dm_errno,
+ const char *format, ...)
+ __attribute__ ((format(printf, 5, 6)));
-#define LOG_LINE(l, x...) print_log(l, __FILE__, __LINE__ , ## x)
+#define LOG_LINE(l, x...) print_log(l, __FILE__, __LINE__ , 0, ## x)
#include "log.h"
typedef void (*lvm2_log_fn_t) (int level, const char *file, int line,
- const char *message);
+ int dm_errno, const char *message);
void init_log_fn(lvm2_log_fn_t log_fn);
@@ -42,6 +43,9 @@ void init_syslog(int facility);
void fin_syslog(void);
int error_message_produced(void);
+void reset_lvm_errno(int store_errmsg);
+int lvm_errno(void);
+const char *lvm_errmsg(void);
/* Suppress messages to stdout/stderr (1) or everywhere (2) */
/* Returns previous setting */
diff --git a/po/pogen.h b/po/pogen.h
index 6ab81545..66940b97 100644
--- a/po/pogen.h
+++ b/po/pogen.h
@@ -19,8 +19,8 @@
* different architectures.
*/
-#define print_log(level, file, line, format, args...) print_log(format, args)
+#define print_log(level, dm_errno, file, line, format, args...) print_log(format, args)
#define dm_log(level, file, line, format, args...) dm_log(format, args)
-#define dm_log_with_errno(level, file, line, format, dm_errno, args...) \
- dm_log(format, args)
+#define dm_log_with_errno(level, dm_errno, file, line, format, args...) \
+ dm_log(level, file, line, format, args)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index efd996ae..33e549b1 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1054,6 +1054,8 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
*/
dm_pool_empty(cmd->mem);
+ reset_lvm_errno(1);
+
return ret;
}