@@ -985,12 +985,12 @@ test_misc_flags(void)
/* With -v */
const char *argv2[] = {prgname, prefix, mp_flag, "-v"};
/* With valid --syslog */
- const char *argv3[] = {prgname, prefix, mp_flag,
- "--syslog", "syslog"};
- /* With empty --syslog (should fail) */
+ const char *argv3[] = {prgname, prefix, mp_flag, "--syslog=user"};
+ /* With empty --syslog (now defaults) */
const char *argv4[] = {prgname, prefix, mp_flag, "--syslog"};
/* With invalid --syslog */
- const char *argv5[] = {prgname, prefix, mp_flag, "--syslog", "error"};
+ const char *argv5[] = {prgname, prefix, mp_flag, "--syslog=invalid"};
+
/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
const char *argv6[] = {prgname, "-m", DEFAULT_MEM_SIZE,
no_shconf, nosh_prefix, no_huge};
@@ -1080,15 +1080,15 @@ test_misc_flags(void)
#endif
if (launch_proc(argv3) != 0) {
- printf("Error - process did not run ok with --syslog flag\n");
+ printf("Error - process did not run ok with --syslog=user flag\n");
goto fail;
}
- if (launch_proc(argv4) == 0) {
- printf("Error - process run ok with empty --syslog flag\n");
+ if (launch_proc(argv4) != 0) {
+ printf("Error - process did not run ok with --syslog flag\n");
goto fail;
}
if (launch_proc(argv5) == 0) {
- printf("Error - process run ok with invalid --syslog flag\n");
+ printf("Error - process run ok with --syslog=invalid flag\n");
goto fail;
}
if (launch_proc(argv7) != 0) {
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters
-------------------------------
There are currently no FreeBSD-specific EAL command-line parameters available.
+
+Other options
+~~~~~~~~~~~~~
+
+* ``--syslog <syslog facility>``
+
+ Set syslog facility. Valid syslog facilities are::
+
+ auth
+ cron
+ daemon
+ ftp
+ kern
+ lpr
+ mail
+ news
+ syslog
+ user
+ uucp
+ local0
+ local1
+ local2
+ local3
+ local4
+ local5
+ local6
+ local7
@@ -884,9 +884,9 @@ Signal Safety
Other functions are not signal safe because they use one or more
library routines that are not themselves signal safe.
For example, calling ``rte_panic()`` is not safe in a signal handler
- because it uses ``rte_log()`` and ``rte_log()`` calls the
- ``syslog()`` library function which is in the list of
- signal safe functions in
+ because it uses ``rte_log()`` and ``rte_log()`` may call ``vfprintf()`` or
+ ``syslog()`` library functions which are not in the list of
+ signal safe functions
`Signal-Safety manual page <https://man7.org/linux/man-pages/man7/signal-safety.7.html>`_.
The set of functions that are expected to be async-signal-safe in DPDK
@@ -5,9 +5,9 @@ Log Library
===========
The DPDK Log library provides the logging functionality for other DPDK libraries and drivers.
-By default, in a Linux application, logs are sent to syslog and also to the console.
-On FreeBSD and Windows applications, logs are sent only to the console.
-However, the log function can be overridden by the user to use a different logging mechanism.
+By default, logs are sent only to standard error output of the process.
+The syslog EAL option can be used to redirect to the stystem logger on Linux and FreeBSD.
+In addition, the log can be redirected to a different stdio file stream.
Log Levels
----------
@@ -114,6 +114,12 @@ New Features
(and vice versa); freeing the same pointer twice in the same routine;
freeing an object that was not created by allocation; etc.
+* **Updated logging library**
+
+ * The syslog option has changed.
+ By default, messages are no longer sent to syslog unless the ``--syslog`` option is specified.
+ Syslog is also supported on FreeBSD (but not on Windows).
+
* **Updated Marvell cnxk mempool driver.**
* Added mempool driver support for CN20K SoC.
@@ -6,9 +6,6 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
-#ifndef RTE_EXEC_ENV_WINDOWS
-#include <syslog.h>
-#endif
#include <ctype.h>
#include <limits.h>
#include <errno.h>
@@ -93,7 +90,9 @@ eal_long_options[] = {
{OPT_PROC_TYPE, 1, NULL, OPT_PROC_TYPE_NUM },
{OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM },
{OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM },
- {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM },
+#ifndef RTE_EXEC_ENV_WINDOWS
+ {OPT_SYSLOG, 2, NULL, OPT_SYSLOG_NUM },
+#endif
{OPT_VDEV, 1, NULL, OPT_VDEV_NUM },
{OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
{OPT_VFIO_VF_TOKEN, 1, NULL, OPT_VFIO_VF_TOKEN_NUM },
@@ -349,10 +348,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
}
internal_cfg->base_virtaddr = 0;
-#ifdef LOG_DAEMON
- internal_cfg->syslog_facility = LOG_DAEMON;
-#endif
-
/* if set to NONE, interrupt mode is determined automatically */
internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
memset(internal_cfg->vfio_vf_token, 0,
@@ -1297,47 +1292,6 @@ eal_parse_lcores(const char *lcores)
return ret;
}
-#ifndef RTE_EXEC_ENV_WINDOWS
-static int
-eal_parse_syslog(const char *facility, struct internal_config *conf)
-{
- int i;
- static const struct {
- const char *name;
- int value;
- } map[] = {
- { "auth", LOG_AUTH },
- { "cron", LOG_CRON },
- { "daemon", LOG_DAEMON },
- { "ftp", LOG_FTP },
- { "kern", LOG_KERN },
- { "lpr", LOG_LPR },
- { "mail", LOG_MAIL },
- { "news", LOG_NEWS },
- { "syslog", LOG_SYSLOG },
- { "user", LOG_USER },
- { "uucp", LOG_UUCP },
- { "local0", LOG_LOCAL0 },
- { "local1", LOG_LOCAL1 },
- { "local2", LOG_LOCAL2 },
- { "local3", LOG_LOCAL3 },
- { "local4", LOG_LOCAL4 },
- { "local5", LOG_LOCAL5 },
- { "local6", LOG_LOCAL6 },
- { "local7", LOG_LOCAL7 },
- { NULL, 0 }
- };
-
- for (i = 0; map[i].name; i++) {
- if (!strcmp(facility, map[i].name)) {
- conf->syslog_facility = map[i].value;
- return 0;
- }
- }
- return -1;
-}
-#endif
-
static void
eal_log_usage(void)
{
@@ -1645,6 +1599,7 @@ eal_option_is_log(int opt)
{
switch (opt) {
case OPT_LOG_LEVEL_NUM:
+ case OPT_SYSLOG_NUM:
return true;
default:
return false;
@@ -1887,7 +1842,7 @@ eal_parse_common_option(int opt, const char *optarg,
#ifndef RTE_EXEC_ENV_WINDOWS
case OPT_SYSLOG_NUM:
- if (eal_parse_syslog(optarg, conf) < 0) {
+ if (eal_log_syslog(optarg) < 0) {
EAL_LOG(ERR, "invalid parameters for --"
OPT_SYSLOG);
return -1;
@@ -2264,7 +2219,7 @@ eal_common_usage(void)
" --"OPT_VMWARE_TSC_MAP" Use VMware TSC map instead of native RDTSC\n"
" --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n"
#ifndef RTE_EXEC_ENV_WINDOWS
- " --"OPT_SYSLOG" Set syslog facility\n"
+ " --"OPT_SYSLOG"[=<facility>] Enable use of syslog (and optionally set facility)\n"
#endif
" --"OPT_LOG_LEVEL"=<level> Set global log level\n"
" --"OPT_LOG_LEVEL"=<type-match>:<level>\n"
@@ -84,7 +84,6 @@ struct internal_config {
/**< true if storing all pages within single files (per-page-size,
* per-node) non-legacy mode only.
*/
- volatile int syslog_facility; /**< facility passed to openlog() */
/** default interrupt mode for VFIO */
volatile enum rte_intr_mode vfio_intr_mode;
/** the shared VF token for VFIO-PCI bound PF and VFs devices */
@@ -11,7 +11,6 @@
#include <stdarg.h>
#include <unistd.h>
#include <pthread.h>
-#include <syslog.h>
#include <getopt.h>
#include <sys/file.h>
#include <stddef.h>
@@ -1104,13 +1104,7 @@ rte_eal_init(int argc, char **argv)
#endif
}
- if (eal_log_init(program_invocation_short_name,
- internal_conf->syslog_facility) < 0) {
- rte_eal_init_alert("Cannot init logging.");
- rte_errno = ENOMEM;
- rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
- return -1;
- }
+ eal_log_init(program_invocation_short_name);
#ifdef VFIO_PRESENT
if (rte_vfio_enable("vfio")) {
@@ -251,7 +251,7 @@ rte_eal_init(int argc, char **argv)
char cpuset[RTE_CPU_AFFINITY_STR_LEN];
char thread_name[RTE_THREAD_NAME_SIZE];
- eal_log_init(NULL, 0);
+ eal_log_init(NULL);
/* parse log options as early as possible */
eal_parse_log_options(argc, argv);
@@ -2,6 +2,7 @@
* Copyright(c) 2010-2014 Intel Corporation
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
@@ -12,10 +13,12 @@
#include <fnmatch.h>
#include <sys/queue.h>
+#include <rte_common.h>
#include <rte_log.h>
#include <rte_per_lcore.h>
#include "log_internal.h"
+#include "log_private.h"
#ifdef RTE_EXEC_ENV_WINDOWS
#define strdup _strdup
@@ -55,9 +58,6 @@ TAILQ_HEAD(rte_eal_opt_loglevel_list, rte_eal_opt_loglevel);
static struct rte_eal_opt_loglevel_list opt_loglevel_list =
TAILQ_HEAD_INITIALIZER(opt_loglevel_list);
-/* Stream to use for logging if rte_logs.file is NULL */
-static FILE *default_log_stream;
-
/**
* This global structure stores some information about the message
* that is currently being processed by one lcore
@@ -70,8 +70,6 @@ struct log_cur_msg {
/* per core log */
static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
-/* default logs */
-
/* Change the stream that will be used by logging system */
int
rte_openlog_stream(FILE *f)
@@ -85,17 +83,7 @@ rte_log_get_stream(void)
{
FILE *f = rte_logs.file;
- if (f == NULL) {
- /*
- * Grab the current value of stderr here, rather than
- * just initializing default_log_stream to stderr. This
- * ensures that we will always use the current value
- * of stderr, even if the application closes and
- * reopens it.
- */
- return default_log_stream != NULL ? default_log_stream : stderr;
- }
- return f;
+ return (f == NULL) ? stderr : f;
}
/* Set global log level */
@@ -506,12 +494,18 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
}
/*
- * Called by environment-specific initialization functions.
+ * Called by rte_eal_init
*/
void
-eal_log_set_default(FILE *default_log)
+eal_log_init(const char *id)
{
- default_log_stream = default_log;
+ FILE *logf = NULL;
+
+ if (log_syslog_enabled())
+ logf = log_syslog_open(id);
+
+ if (logf)
+ rte_openlog_stream(logf);
#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
RTE_LOG(NOTICE, EAL,
@@ -525,8 +519,11 @@ eal_log_set_default(FILE *default_log)
void
rte_eal_log_cleanup(void)
{
- if (default_log_stream) {
- fclose(default_log_stream);
- default_log_stream = NULL;
- }
+ FILE *log_stream = rte_logs.file;
+
+ /* don't close stderr on the application */
+ if (log_stream != NULL)
+ fclose(log_stream);
+
+ rte_logs.file = NULL;
}
deleted file mode 100644
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2023 Intel Corporation
- */
-
-#include <rte_common.h>
-#include "log_internal.h"
-
-int
-eal_log_init(__rte_unused const char *id, __rte_unused int facility)
-{
- return 0;
-}
@@ -14,13 +14,7 @@
* Initialize the default log stream.
*/
__rte_internal
-int eal_log_init(const char *id, int facility);
-
-/*
- * Determine where log data is written when no call to rte_openlog_stream.
- */
-__rte_internal
-void eal_log_set_default(FILE *default_log);
+void eal_log_init(const char *id);
/*
* Save a log option for later.
@@ -30,6 +24,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);
__rte_internal
int eal_log_save_pattern(const char *pattern, uint32_t level);
+__rte_internal
+int eal_log_syslog(const char *name);
+
/*
* Convert log level to string.
*/
deleted file mode 100644
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <syslog.h>
-
-#include <rte_log.h>
-
-#include "log_internal.h"
-
-/*
- * default log function
- */
-static ssize_t
-console_log_write(__rte_unused void *c, const char *buf, size_t size)
-{
- ssize_t ret;
-
- /* write on stderr */
- ret = fwrite(buf, 1, size, stderr);
- fflush(stderr);
-
- /* Syslog error levels are from 0 to 7, so subtract 1 to convert */
- syslog(rte_log_cur_msg_loglevel() - 1, "%.*s", (int)size, buf);
-
- return ret;
-}
-
-static int
-console_log_close(__rte_unused void *c)
-{
- closelog();
- return 0;
-}
-
-static cookie_io_functions_t console_log_func = {
- .write = console_log_write,
- .close = console_log_close,
-};
-
-/*
- * set the log to default function, called during eal init process,
- * once memzones are available.
- */
-int
-eal_log_init(const char *id, int facility)
-{
- FILE *log_stream;
-
- log_stream = fopencookie(NULL, "w+", console_log_func);
- if (log_stream == NULL)
- return -1;
-
- openlog(id, LOG_NDELAY | LOG_PID, facility);
-
- eal_log_set_default(log_stream);
-
- return 0;
-}
new file mode 100644
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#ifndef LOG_PRIVATE_H
+#define LOG_PRIVATE_H
+
+/* Defined in limits.h on Linux */
+#ifndef LINE_MAX
+#define LINE_MAX 2048 /* _POSIX2_LINE_MAX */
+#endif
+
+#ifdef RTE_EXEC_ENV_WINDOWS
+static inline bool
+log_syslog_enabled(void)
+{
+ return false;
+}
+static inline FILE *
+log_syslog_open(const char *id __rte_unused)
+{
+ return NULL;
+}
+#else
+bool log_syslog_enabled(void);
+FILE *log_syslog_open(const char *id);
+#endif
+
+#endif /* LOG_PRIVATE_H */
new file mode 100644
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <syslog.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include "log_internal.h"
+#include "log_private.h"
+
+static int log_facility;
+
+/*
+ * Usable list of facilities
+ * Skip kern, mark, and security
+ */
+static const struct {
+ const char *name;
+ int value;
+} facilitys[] = {
+ { "auth", LOG_AUTH },
+ { "cron", LOG_CRON },
+ { "daemon", LOG_DAEMON },
+ { "ftp", LOG_FTP },
+ { "kern", LOG_KERN },
+ { "lpr", LOG_LPR },
+ { "mail", LOG_MAIL },
+ { "news", LOG_NEWS },
+ { "syslog", LOG_SYSLOG },
+ { "user", LOG_USER },
+ { "uucp", LOG_UUCP },
+ { "local0", LOG_LOCAL0 },
+ { "local1", LOG_LOCAL1 },
+ { "local2", LOG_LOCAL2 },
+ { "local3", LOG_LOCAL3 },
+ { "local4", LOG_LOCAL4 },
+ { "local5", LOG_LOCAL5 },
+ { "local6", LOG_LOCAL6 },
+ { "local7", LOG_LOCAL7 },
+};
+
+int
+eal_log_syslog(const char *name)
+{
+ unsigned int i;
+
+ if (name == NULL) {
+ log_facility = LOG_DAEMON;
+ return 0;
+ }
+
+ for (i = 0; i < RTE_DIM(facilitys); i++) {
+ if (!strcmp(name, facilitys[i].name)) {
+ log_facility = facilitys[i].value;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/* syslog is enabled if facility is set */
+bool
+log_syslog_enabled(void)
+{
+ return log_facility != 0; /* LOG_KERN is 0 */
+}
+
+/*
+ * default log function
+ */
+static ssize_t
+log_syslog_write(__rte_unused void *c, const char *buf, size_t size)
+{
+ /* Syslog error levels are from 0 to 7, so subtract 1 to convert */
+ syslog(rte_log_cur_msg_loglevel() - 1, "%.*s", (int)size, buf);
+
+ return size;
+}
+
+static int
+log_syslog_close(__rte_unused void *c)
+{
+ closelog();
+ return 0;
+}
+
+static cookie_io_functions_t log_syslog_func = {
+ .write = log_syslog_write,
+ .close = log_syslog_close,
+};
+
+
+FILE *
+log_syslog_open(const char *id)
+{
+ int option = LOG_CONS | LOG_NDELAY | LOG_PID | LOG_PERROR;
+
+ openlog(id, option, log_facility);
+
+ /* redirect other log messages to syslog as well */
+ return fopencookie(NULL, "w", log_syslog_func);
+}
deleted file mode 100644
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017-2018 Intel Corporation
- */
-
-#include <rte_common.h>
-#include <rte_log.h>
-#include "log_internal.h"
-
-/* set the log to default function, called during eal init process. */
-int
-eal_log_init(__rte_unused const char *id, __rte_unused int facility)
-{
- rte_openlog_stream(stderr);
-
- eal_log_set_default(stderr);
-
- return 0;
-}
@@ -4,6 +4,10 @@
includes += global_inc
sources = files(
'log.c',
- 'log_' + exec_env + '.c',
)
+
+if not is_windows
+ sources += files('log_syslog.c')
+endif
+
headers = files('rte_log.h')
@@ -29,6 +29,6 @@ INTERNAL {
eal_log_level2str;
eal_log_save_pattern;
eal_log_save_regexp;
- eal_log_set_default;
+ eal_log_syslog; # WINDOWS_NO_EXPORT
rte_eal_log_cleanup;
};