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
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)
{
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);
/*
#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 */
/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
- dm_log_init(print_log);
+ dm_log_with_errno_init(print_log);
#endif
}
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:
persistent_filter_dump(cmd->filter);
cmd->config_valid = 1;
+
+ reset_lvm_errno(1);
return 1;
}
activation_exit();
fin_log();
fin_syslog();
+ reset_lvm_errno(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)
_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;
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);
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;
}
#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);
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 */
* 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)
*/
dm_pool_empty(cmd->mem);
+ reset_lvm_errno(1);
+
return ret;
}