summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2009-07-15 23:57:54 +0000
committerAlasdair Kergon <agk@redhat.com>2009-07-15 23:57:54 +0000
commitd614646157d51b6a396519b73ec99e112e6948de (patch)
tree65107ed1ba99a464fd3b3ad314ae0ddc7e7336e7
parentb8f47d5f69ca666623ac83e0aea986f582a3a0ae (diff)
downloadlvm2-d614646157d51b6a396519b73ec99e112e6948de.tar.gz
lvm2-d614646157d51b6a396519b73ec99e112e6948de.tar.xz
lvm2-d614646157d51b6a396519b73ec99e112e6948de.zip
Store any errno and error messages issued while processing each command.
(Enabled by default while we test it, but in due course we'll only store the error messages when we need to.)
-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;
}