mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 08:26:52 +03:00
basic/log: add concept of "synthethic errnos"
Synthetic errnos are processed like normal, and may be used in %m and become the return value from log_*(), but they are not logged in the journal.
This commit is contained in:
parent
883eb9be98
commit
52d86690d6
@ -484,6 +484,8 @@ static int log_do_header(
|
|||||||
const char *extra_field, const char *extra) {
|
const char *extra_field, const char *extra) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
|
||||||
|
|
||||||
r = snprintf(header, size,
|
r = snprintf(header, size,
|
||||||
"PRIORITY=%i\n"
|
"PRIORITY=%i\n"
|
||||||
"SYSLOG_FACILITY=%i\n"
|
"SYSLOG_FACILITY=%i\n"
|
||||||
@ -569,15 +571,12 @@ int log_dispatch_internal(
|
|||||||
|
|
||||||
assert_raw(buffer);
|
assert_raw(buffer);
|
||||||
|
|
||||||
if (error < 0)
|
|
||||||
error = -error;
|
|
||||||
|
|
||||||
if (log_target == LOG_TARGET_NULL)
|
if (log_target == LOG_TARGET_NULL)
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
|
|
||||||
/* Patch in LOG_DAEMON facility if necessary */
|
/* Patch in LOG_DAEMON facility if necessary */
|
||||||
if ((level & LOG_FACMASK) == 0)
|
if ((level & LOG_FACMASK) == 0)
|
||||||
level = log_facility | LOG_PRI(level);
|
level |= log_facility;
|
||||||
|
|
||||||
if (open_when_needed)
|
if (open_when_needed)
|
||||||
log_open();
|
log_open();
|
||||||
@ -636,7 +635,7 @@ int log_dispatch_internal(
|
|||||||
if (open_when_needed)
|
if (open_when_needed)
|
||||||
log_close();
|
log_close();
|
||||||
|
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int log_dump_internal(
|
int log_dump_internal(
|
||||||
@ -652,11 +651,8 @@ int log_dump_internal(
|
|||||||
|
|
||||||
/* This modifies the buffer... */
|
/* This modifies the buffer... */
|
||||||
|
|
||||||
if (error < 0)
|
|
||||||
error = -error;
|
|
||||||
|
|
||||||
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
|
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
|
|
||||||
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
|
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
|
||||||
}
|
}
|
||||||
@ -674,14 +670,11 @@ int log_internalv_realm(
|
|||||||
char buffer[LINE_MAX];
|
char buffer[LINE_MAX];
|
||||||
PROTECT_ERRNO;
|
PROTECT_ERRNO;
|
||||||
|
|
||||||
if (error < 0)
|
|
||||||
error = -error;
|
|
||||||
|
|
||||||
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
|
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
|
|
||||||
/* Make sure that %m maps to the specified error (or "Success"). */
|
/* Make sure that %m maps to the specified error (or "Success"). */
|
||||||
errno = error;
|
errno = ERRNO_VALUE(error);
|
||||||
|
|
||||||
(void) vsnprintf(buffer, sizeof buffer, format, ap);
|
(void) vsnprintf(buffer, sizeof buffer, format, ap);
|
||||||
|
|
||||||
@ -723,14 +716,11 @@ static int log_object_internalv(
|
|||||||
PROTECT_ERRNO;
|
PROTECT_ERRNO;
|
||||||
char *buffer, *b;
|
char *buffer, *b;
|
||||||
|
|
||||||
if (error < 0)
|
|
||||||
error = -error;
|
|
||||||
|
|
||||||
if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
|
if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
|
|
||||||
/* Make sure that %m maps to the specified error (or "Success"). */
|
/* Make sure that %m maps to the specified error (or "Success"). */
|
||||||
errno = error;
|
errno = ERRNO_VALUE(error);
|
||||||
|
|
||||||
/* Prepend the object name before the message */
|
/* Prepend the object name before the message */
|
||||||
if (object) {
|
if (object) {
|
||||||
@ -853,7 +843,7 @@ int log_format_iovec(
|
|||||||
* since vasprintf() leaves it afterwards at
|
* since vasprintf() leaves it afterwards at
|
||||||
* an undefined location */
|
* an undefined location */
|
||||||
|
|
||||||
errno = error;
|
errno = ERRNO_VALUE(error);
|
||||||
|
|
||||||
va_copy(aq, ap);
|
va_copy(aq, ap);
|
||||||
r = vasprintf(&m, format, aq);
|
r = vasprintf(&m, format, aq);
|
||||||
@ -892,17 +882,12 @@ int log_struct_internal(
|
|||||||
PROTECT_ERRNO;
|
PROTECT_ERRNO;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if (error < 0)
|
if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
|
||||||
error = -error;
|
log_target == LOG_TARGET_NULL)
|
||||||
|
return -ERRNO_VALUE(error);
|
||||||
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
|
|
||||||
return -error;
|
|
||||||
|
|
||||||
if (log_target == LOG_TARGET_NULL)
|
|
||||||
return -error;
|
|
||||||
|
|
||||||
if ((level & LOG_FACMASK) == 0)
|
if ((level & LOG_FACMASK) == 0)
|
||||||
level = log_facility | LOG_PRI(level);
|
level |= log_facility;
|
||||||
|
|
||||||
if (IN_SET(log_target,
|
if (IN_SET(log_target,
|
||||||
LOG_TARGET_AUTO,
|
LOG_TARGET_AUTO,
|
||||||
@ -922,7 +907,8 @@ int log_struct_internal(
|
|||||||
};
|
};
|
||||||
bool fallback = false;
|
bool fallback = false;
|
||||||
|
|
||||||
/* If the journal is available do structured logging */
|
/* If the journal is available do structured logging.
|
||||||
|
* Do not report the errno if it is synthetic. */
|
||||||
log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
|
log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
|
||||||
iovec[n++] = IOVEC_MAKE_STRING(header);
|
iovec[n++] = IOVEC_MAKE_STRING(header);
|
||||||
|
|
||||||
@ -943,7 +929,7 @@ int log_struct_internal(
|
|||||||
if (open_when_needed)
|
if (open_when_needed)
|
||||||
log_close();
|
log_close();
|
||||||
|
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -954,7 +940,7 @@ int log_struct_internal(
|
|||||||
while (format) {
|
while (format) {
|
||||||
va_list aq;
|
va_list aq;
|
||||||
|
|
||||||
errno = error;
|
errno = ERRNO_VALUE(error);
|
||||||
|
|
||||||
va_copy(aq, ap);
|
va_copy(aq, ap);
|
||||||
(void) vsnprintf(buf, sizeof buf, format, aq);
|
(void) vsnprintf(buf, sizeof buf, format, aq);
|
||||||
@ -975,7 +961,7 @@ int log_struct_internal(
|
|||||||
if (open_when_needed)
|
if (open_when_needed)
|
||||||
log_close();
|
log_close();
|
||||||
|
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
|
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
|
||||||
@ -995,17 +981,12 @@ int log_struct_iovec_internal(
|
|||||||
size_t i;
|
size_t i;
|
||||||
char *m;
|
char *m;
|
||||||
|
|
||||||
if (error < 0)
|
if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
|
||||||
error = -error;
|
log_target == LOG_TARGET_NULL)
|
||||||
|
return -ERRNO_VALUE(error);
|
||||||
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
|
|
||||||
return -error;
|
|
||||||
|
|
||||||
if (log_target == LOG_TARGET_NULL)
|
|
||||||
return -error;
|
|
||||||
|
|
||||||
if ((level & LOG_FACMASK) == 0)
|
if ((level & LOG_FACMASK) == 0)
|
||||||
level = log_facility | LOG_PRI(level);
|
level |= log_facility;
|
||||||
|
|
||||||
if (IN_SET(log_target, LOG_TARGET_AUTO,
|
if (IN_SET(log_target, LOG_TARGET_AUTO,
|
||||||
LOG_TARGET_JOURNAL_OR_KMSG,
|
LOG_TARGET_JOURNAL_OR_KMSG,
|
||||||
@ -1028,7 +1009,7 @@ int log_struct_iovec_internal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
|
if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n_input_iovec; i++)
|
for (i = 0; i < n_input_iovec; i++)
|
||||||
@ -1036,7 +1017,7 @@ int log_struct_iovec_internal(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
|
if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
|
||||||
return -error;
|
return -ERRNO_VALUE(error);
|
||||||
|
|
||||||
m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
|
m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
|
||||||
input_iovec[i].iov_len - STRLEN("MESSAGE="));
|
input_iovec[i].iov_len - STRLEN("MESSAGE="));
|
||||||
@ -1239,14 +1220,9 @@ int log_syntax_internal(
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
const char *unit_fmt = NULL;
|
const char *unit_fmt = NULL;
|
||||||
|
|
||||||
if (error < 0)
|
if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]) ||
|
||||||
error = -error;
|
log_target == LOG_TARGET_NULL)
|
||||||
|
return -ERRNO_VALUE(error);
|
||||||
if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
|
|
||||||
return -error;
|
|
||||||
|
|
||||||
if (log_target == LOG_TARGET_NULL)
|
|
||||||
return -error;
|
|
||||||
|
|
||||||
errno = error;
|
errno = error;
|
||||||
|
|
||||||
|
@ -36,10 +36,11 @@ typedef enum LogTarget{
|
|||||||
_LOG_TARGET_INVALID = -1
|
_LOG_TARGET_INVALID = -1
|
||||||
} LogTarget;
|
} LogTarget;
|
||||||
|
|
||||||
#define LOG_REALM_PLUS_LEVEL(realm, level) \
|
#define LOG_REALM_PLUS_LEVEL(realm, level) ((realm) << 10 | (level))
|
||||||
((realm) << 10 | (level))
|
#define LOG_REALM_REMOVE_LEVEL(realm_level) ((realm_level) >> 10)
|
||||||
#define LOG_REALM_REMOVE_LEVEL(realm_level) \
|
#define SYNTHETIC_ERRNO(num) (1 << 30 | (num))
|
||||||
((realm_level >> 10))
|
#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1)
|
||||||
|
#define ERRNO_VALUE(val) (abs(val) & 255)
|
||||||
|
|
||||||
void log_set_target(LogTarget target);
|
void log_set_target(LogTarget target);
|
||||||
void log_set_max_level_realm(LogRealm realm, int level);
|
void log_set_max_level_realm(LogRealm realm, int level);
|
||||||
|
@ -17,20 +17,27 @@ assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_LOCAL3 | LOG_DEBUG) & LOG
|
|||||||
assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_USER | LOG_INFO) & LOG_PRIMASK)
|
assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_USER | LOG_INFO) & LOG_PRIMASK)
|
||||||
== LOG_INFO);
|
== LOG_INFO);
|
||||||
|
|
||||||
|
assert_cc(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(EINVAL)));
|
||||||
|
assert_cc(!IS_SYNTHETIC_ERRNO(EINVAL));
|
||||||
|
assert_cc(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(0)));
|
||||||
|
assert_cc(!IS_SYNTHETIC_ERRNO(0));
|
||||||
|
|
||||||
#define X10(x) x x x x x x x x x x
|
#define X10(x) x x x x x x x x x x
|
||||||
#define X100(x) X10(X10(x))
|
#define X100(x) X10(X10(x))
|
||||||
#define X1000(x) X100(X10(x))
|
#define X1000(x) X100(X10(x))
|
||||||
|
|
||||||
static void test_log_console(void) {
|
static void test_log_struct(void) {
|
||||||
log_struct(LOG_INFO,
|
log_struct(LOG_INFO,
|
||||||
"MESSAGE=Waldo PID="PID_FMT, getpid_cached(),
|
"MESSAGE=Waldo PID="PID_FMT" (no errno)", getpid_cached(),
|
||||||
"SERVICE=piepapo");
|
"SERVICE=piepapo");
|
||||||
}
|
|
||||||
|
|
||||||
static void test_log_journal(void) {
|
log_struct_errno(LOG_INFO, EILSEQ,
|
||||||
log_struct(LOG_INFO,
|
"MESSAGE=Waldo PID="PID_FMT": %m (normal)", getpid_cached(),
|
||||||
"MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
|
"SERVICE=piepapo");
|
||||||
"SERVICE=foobar");
|
|
||||||
|
log_struct_errno(LOG_INFO, SYNTHETIC_ERRNO(EILSEQ),
|
||||||
|
"MESSAGE=Waldo PID="PID_FMT": %m (synthetic)", getpid_cached(),
|
||||||
|
"SERVICE=piepapo");
|
||||||
|
|
||||||
log_struct(LOG_INFO,
|
log_struct(LOG_INFO,
|
||||||
"MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
|
"MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
|
||||||
@ -59,10 +66,11 @@ int main(int argc, char* argv[]) {
|
|||||||
log_set_target(target);
|
log_set_target(target);
|
||||||
log_open();
|
log_open();
|
||||||
|
|
||||||
test_log_console();
|
test_log_struct();
|
||||||
test_log_journal();
|
|
||||||
test_long_lines();
|
test_long_lines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_se(log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), "foo") == -EUCLEAN);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user