#ifdef DEVMAPPER_SUPPORT
dm_log_with_errno_init(print_log);
#endif
+ reset_log_duplicated();
}
static int _process_config(struct cmd_context *cmd)
release_log_memory();
activation_exit();
+ reset_log_duplicated();
fin_log();
fin_syslog();
reset_lvm_errno(0);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n < 0)
- log_error("%s: %s failed after %" PRIu64 " of %" PRIu64
- " at %" PRIu64 ": %s", dev_name(where->dev),
- should_write ? "write" : "read",
- (uint64_t) total,
- (uint64_t) where->size,
- (uint64_t) where->start, strerror(errno));
+ log_error_once("%s: %s failed after %" PRIu64 " of %" PRIu64
+ " at %" PRIu64 ": %s", dev_name(where->dev),
+ should_write ? "write" : "read",
+ (uint64_t) total,
+ (uint64_t) where->size,
+ (uint64_t) where->start, strerror(errno));
if (n <= 0)
break;
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
buffer[0] = '\0';
if (report_missing_devices)
- log_error("Couldn't find device with uuid %s.", buffer);
+ log_error_once("Couldn't find device with uuid %s.", buffer);
else
log_very_verbose("Couldn't find device with uuid %s.", buffer);
}
return _lvm_errmsg ? : "";
}
+static struct dm_hash_table *_duplicated = NULL;
+
+void reset_log_duplicated(void) {
+ if (_duplicated)
+ dm_hash_destroy(_duplicated);
+ _duplicated = NULL;
+}
+
void print_log(int level, const char *file, int line, int dm_errno,
const char *format, ...)
{
const char *trformat; /* Translated format string */
char *newbuf;
int use_stderr = level & _LOG_STDERR;
+ int log_once = level & _LOG_ONCE;
int fatal_internal_error = 0;
- level &= ~_LOG_STDERR;
+ level &= ~(_LOG_STDERR|_LOG_ONCE);
if (_abort_on_internal_errors &&
!strncmp(format, INTERNAL_ERROR,
if (dm_errno && !_lvm_errno)
_lvm_errno = dm_errno;
- if (_lvm2_log_fn || (_store_errmsg && (level <= _LOG_ERR))) {
+ if (_lvm2_log_fn ||
+ (_store_errmsg && (level <= _LOG_ERR)) ||
+ log_once) {
va_start(ap, format);
n = vsnprintf(buf2, sizeof(buf2) - 1, trformat, ap);
va_end(ap);
}
}
+ if (log_once) {
+ if (!_duplicated)
+ _duplicated = dm_hash_create(128);
+ if (_duplicated) {
+ if (dm_hash_lookup(_duplicated, message))
+ level = _LOG_NOTICE;
+ dm_hash_insert(_duplicated, message, (void*)1);
+ }
+ }
+
if (_lvm2_log_fn) {
_lvm2_log_fn(level, file, line, 0, message);
if (fatal_internal_error)
#define _LOG_STDERR 128 /* force things to go to stderr, even if loglevel
would make them go to stdout */
+#define _LOG_ONCE 256 /* downgrade to NOTICE if this has been already logged */
#define _LOG_DEBUG 7
#define _LOG_INFO 6
#define _LOG_NOTICE 5
#define log_warn_suppress(s, x...) LOG_LINE(s ? _LOG_NOTICE : _LOG_WARN | _LOG_STDERR, x)
#define log_err(x...) LOG_LINE_WITH_ERRNO(_LOG_ERR, EUNCLASSIFIED, x)
#define log_err_suppress(s, x...) LOG_LINE_WITH_ERRNO(s ? _LOG_NOTICE : _LOG_ERR, EUNCLASSIFIED, x)
+#define log_err_once(x...) LOG_LINE_WITH_ERRNO(_LOG_ERR | _LOG_ONCE, EUNCLASSIFIED, x)
#define log_fatal(x...) LOG_LINE_WITH_ERRNO(_LOG_FATAL, EUNCLASSIFIED, x)
#define stack log_debug("<backtrace>") /* Backtrace on error */
#define log_print(args...) LOG_LINE(_LOG_WARN, args)
#define log_error(args...) log_err(args)
#define log_error_suppress(s, args...) log_err_suppress(s, args)
+#define log_error_once(args...) log_err_once(args)
#define log_errno(args...) LOG_LINE_WITH_ERRNO(_LOG_ERR, args)
/* System call equivalents */
void fin_log(void);
void release_log_memory(void);
+void reset_log_duplicated(void);
void init_syslog(int facility);
void fin_syslog(void);
dm_pool_empty(cmd->mem);
reset_lvm_errno(1);
+ reset_log_duplicated();
return ret;
}