aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-04-16 13:45:03 -0400
committerTom Rini <trini@konsulko.com>2020-04-16 13:45:03 -0400
commitf51b4bcf61c9aa7994138a4a417488c1fbdb47cd (patch)
tree4f536d0892be1359f2cf02bfe366b56bef83bf28 /common
parentdba0a6ae1907bbff3ebda06e4874d006f10db1bb (diff)
parentb0dcc87106464c3fc019e3771378a092fd32ebdb (diff)
Merge tag 'dm-pull-10apr20-take2' of git://git.denx.de/u-boot-dm
Functions for reading indexed values from device tree Enhancements to 'dm' command Log test enhancements and syslog driver DM change to read parent ofdata before children Minor fixes
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig9
-rw-r--r--common/Makefile1
-rw-r--r--common/log_syslog.c117
3 files changed, 126 insertions, 1 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 3072651082..ee4f748c32 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -775,9 +775,16 @@ config TPL_LOG_CONSOLE
log message is shown - other details like level, category, file and
line number are omitted.
+config LOG_SYSLOG
+ bool "Log output to syslog server"
+ depends on LOG && NET
+ help
+ Enables a log driver which broadcasts log records via UDP port 514
+ to syslog servers.
+
config LOG_TEST
bool "Provide a test for logging"
- depends on LOG
+ depends on LOG && UNIT_TEST
default y if SANDBOX
help
This enables a 'log test' command to test logging. It is normally
diff --git a/common/Makefile b/common/Makefile
index 702f2396cf..d84e10ba99 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -132,6 +132,7 @@ obj-$(CONFIG_DFU_OVER_USB) += dfu.o
obj-y += command.o
obj-$(CONFIG_$(SPL_TPL_)LOG) += log.o
obj-$(CONFIG_$(SPL_TPL_)LOG_CONSOLE) += log_console.o
+obj-$(CONFIG_$(SPL_TPL_)LOG_SYSLOG) += log_syslog.o
obj-y += s_record.o
obj-$(CONFIG_CMD_LOADB) += xyzModem.o
obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
diff --git a/common/log_syslog.c b/common/log_syslog.c
new file mode 100644
index 0000000000..5e3e20e8a4
--- /dev/null
+++ b/common/log_syslog.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Log to syslog.
+ *
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <log.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BUFFER_SIZE 480
+
+static void append(char **buf, char *buf_end, const char *fmt, ...)
+{
+ va_list args;
+ size_t size = buf_end - *buf;
+
+ va_start(args, fmt);
+ vsnprintf(*buf, size, fmt, args);
+ va_end(args);
+ *buf += strlen(*buf);
+}
+
+static int log_syslog_emit(struct log_device *ldev, struct log_rec *rec)
+{
+ int ret;
+ int fmt = gd->log_fmt;
+ char msg[BUFFER_SIZE];
+ char *msg_end = msg + BUFFER_SIZE;
+ char *ptr = msg;
+ char *iphdr;
+ char *log_msg;
+ int eth_hdr_size;
+ struct in_addr bcast_ip;
+ static int processing_msg;
+ unsigned int log_level;
+ char *log_hostname;
+
+ /* Fend off messages from the network stack while writing a message */
+ if (processing_msg)
+ return 0;
+
+ processing_msg = 1;
+
+ /* Setup packet buffers */
+ net_init();
+ /* Disable hardware and put it into the reset state */
+ eth_halt();
+ /* Set current device according to environment variables */
+ eth_set_current();
+ /* Get hardware ready for send and receive operations */
+ ret = eth_init();
+ if (ret < 0) {
+ eth_halt();
+ goto out;
+ }
+
+ memset(msg, 0, BUFFER_SIZE);
+
+ /* Set ethernet header */
+ eth_hdr_size = net_set_ether((uchar *)ptr, net_bcast_ethaddr, PROT_IP);
+ ptr += eth_hdr_size;
+ iphdr = ptr;
+ ptr += IP_UDP_HDR_SIZE;
+ log_msg = ptr;
+
+ /*
+ * The syslog log levels defined in RFC 5424 match the U-Boot ones up to
+ * level 7 (debug).
+ */
+ log_level = rec->level;
+ if (log_level > 7)
+ log_level = 7;
+ /* Leave high bits as 0 to write a 'kernel message' */
+
+ /* Write log message to buffer */
+ append(&ptr, msg_end, "<%u>", log_level);
+ log_hostname = env_get("log_hostname");
+ if (log_hostname)
+ append(&ptr, msg_end, "%s ", log_hostname);
+ append(&ptr, msg_end, "uboot: ");
+ if (fmt & (1 << LOGF_LEVEL))
+ append(&ptr, msg_end, "%s.",
+ log_get_level_name(rec->level));
+ if (fmt & (1 << LOGF_CAT))
+ append(&ptr, msg_end, "%s,",
+ log_get_cat_name(rec->cat));
+ if (fmt & (1 << LOGF_FILE))
+ append(&ptr, msg_end, "%s:", rec->file);
+ if (fmt & (1 << LOGF_LINE))
+ append(&ptr, msg_end, "%d-", rec->line);
+ if (fmt & (1 << LOGF_FUNC))
+ append(&ptr, msg_end, "%s()", rec->func);
+ if (fmt & (1 << LOGF_MSG))
+ append(&ptr, msg_end, "%s%s",
+ fmt != (1 << LOGF_MSG) ? " " : "", rec->msg);
+ /* Consider trailing 0x00 */
+ ptr++;
+
+ debug("log message: '%s'\n", log_msg);
+
+ /* Broadcast message */
+ bcast_ip.s_addr = 0xFFFFFFFFL;
+ net_set_udp_header((uchar *)iphdr, bcast_ip, 514, 514, ptr - log_msg);
+ net_send_packet((uchar *)msg, ptr - msg);
+
+out:
+ processing_msg = 0;
+ return ret;
+}
+
+LOG_DRIVER(syslog) = {
+ .name = "syslog",
+ .emit = log_syslog_emit,
+};