From 229d44a88487896b7d5430b6b0d5dba35c8e1db6 Mon Sep 17 00:00:00 2001 From: Minggui Cao Date: Thu, 25 Apr 2019 15:04:58 +0800 Subject: [PATCH] DM: add kmsg logger to sync with kernel log kmsg logger used to output ACRN-DM log to /dev/kmsg, it is easy to sync with kernel log. it is better just output key info or error/failure log to kmsg for kernel log size is limited. Tracked-On: #3012 Signed-off-by: Minggui Cao Acked-by: Yin Fengwei --- devicemodel/Makefile | 1 + devicemodel/log/kmsg_logger.c | 99 +++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 devicemodel/log/kmsg_logger.c diff --git a/devicemodel/Makefile b/devicemodel/Makefile index fd6958c4c..cc9c3bd4e 100644 --- a/devicemodel/Makefile +++ b/devicemodel/Makefile @@ -156,6 +156,7 @@ SRCS += vmcfg/apl-mrb/vm1/vm1.c # log SRCS += log/log.c +SRCS += log/kmsg_logger.c OBJS := $(patsubst %.c,$(DM_OBJDIR)/%.o,$(SRCS)) diff --git a/devicemodel/log/kmsg_logger.c b/devicemodel/log/kmsg_logger.c new file mode 100644 index 000000000..025cd29e4 --- /dev/null +++ b/devicemodel/log/kmsg_logger.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" + +#define KMSG_DEV_NODE "/dev/kmsg" +#define KMSG_PREFIX "acrn_dm: " + +#define KMSG_MAX_LEN (MAX_ONE_LOG_SIZE + 64) +#define DEFAULT_KMSG_LEVEL LOG_NOTICE + +static int kmsg_fd = -1; + +static uint8_t kmsg_log_level = DEFAULT_KMSG_LEVEL; +static bool kmsg_enabled = false; + +static bool is_kmsg_enabled(void) +{ + return kmsg_enabled; +} + +static uint8_t get_kmsg_log_level(void) +{ + return kmsg_log_level; +} + +static int init_kmsg_logger(bool enable, uint8_t log_level) +{ + kmsg_enabled = enable; + kmsg_log_level = log_level; + + /* usually this init should be called once in DM whole life */ + if (kmsg_fd > 0) + return kmsg_fd; + + kmsg_fd = open(KMSG_DEV_NODE, O_RDWR | O_APPEND | O_NONBLOCK); + if (kmsg_fd < 0) { + kmsg_enabled = false; + perror(KMSG_PREFIX"open kmsg dev failed"); + } + + return kmsg_fd; +} + +static void deinit_kmsg(void) +{ + if (kmsg_fd > 0) { + close(kmsg_fd); + kmsg_fd = -1; + + kmsg_enabled = false; + } +} + +static void write_to_kmsg(const char *fmt, va_list args) +{ + char kmsg_buf[KMSG_MAX_LEN] = KMSG_PREFIX; + int len1, len2; + int write_cnt; + + if (kmsg_fd < 0) + return; + + len1 = strlen(KMSG_PREFIX); + len2 = vsnprintf(kmsg_buf + len1, MAX_ONE_LOG_SIZE, fmt, args); + + write_cnt = write(kmsg_fd, kmsg_buf, len1 + len2); + if (write_cnt < 0) { + perror(KMSG_PREFIX"write kmsg failed"); + close(kmsg_fd); + kmsg_fd = -1; + } +} + +struct logger_ops logger_kmsg = { + .name = "kmsg", + .is_enabled = is_kmsg_enabled, + .get_log_level = get_kmsg_log_level, + .init = init_kmsg_logger, + .deinit = deinit_kmsg, + .output = write_to_kmsg, +}; + +DEFINE_LOGGER_DEVICE(logger_kmsg);