Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755125AbbGCKuq (ORCPT ); Fri, 3 Jul 2015 06:50:46 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:65390 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754726AbbGCKuY (ORCPT ); Fri, 3 Jul 2015 06:50:24 -0400 X-AuditID: cbfec7f5-f794b6d000001495-24-559668e67b60 From: Marcin Niesluchowski To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org Cc: Jonathan Corbet , Greg Kroah-Hartman , Petr Mladek , Tejun Heo , Kay Sievers , Andrew Morton , Joe Perches , Karol Lewandowski , Bartlomiej Zolnierkiewicz , Marcin Niesluchowski Subject: [RFC 2/8] printk: add one function for storing log in proper format Date: Fri, 03 Jul 2015 12:49:49 +0200 Message-id: <1435920595-30879-3-git-send-email-m.niesluchow@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1435920595-30879-1-git-send-email-m.niesluchow@samsung.com> References: <1435920595-30879-1-git-send-email-m.niesluchow@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrGLMWRmVeSWpSXmKPExsVy+t/xK7rPMqaFGjy8pmUxZ/0aNouNM9az Wjw50M5o0bx4PZvF7PuPWSwaP81ltri16jm7xebvHWwWC9uWsFhc3jWHzeLQ2R8sFgv/b2ay +LX8KKMDr8emVZ1sHidm/Gbx2D93DbvH4r7JrB5fVl1j9ujbsorR48yCI+wenzfJeXxc7xnA GcVlk5Kak1mWWqRvl8CVsWzFI5aCn8YV06a+Ym1gvKDexcjJISFgItHct4cNwhaTuHBvPZDN xSEksJRR4mzHFSinmUni9NNOZpAqNgFTibZle9hBbBGBCImFF5tYQIqYBaYxS5xt3gtWJCzg I7H16iQWEJtFQFXiwtcmMJtXwENi5402qHVyEiePTWYFsTkFPCU+9S0D6xUCqtlwbD7TBEbe BYwMqxhFU0uTC4qT0nON9IoTc4tL89L1kvNzNzFCQvfrDsalx6wOMQpwMCrx8F44PTVUiDWx rLgy9xCjBAezkgjv8+BpoUK8KYmVValF+fFFpTmpxYcYpTlYlMR5Z+56HyIkkJ5YkpqdmlqQ WgSTZeLglGpgXGLU2PiZxefLKcFlndfYLHYrLLy8Nb795GFtn7PXvHUX5bFst015c0zr5LLm +W5fdm2uaV++JOr3zP278jS7imxqFzVYH1369l+Dhv5h/4ezKi6arXpWwrpVOchQJNl5lS2L Cm9m04k7R6u8jrYu3b/TaZ47P4uQ7k0Xz5ISx5kvK72m//M3UWIpzkg01GIuKk4EAFsl96BZ AgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6673 Lines: 226 Preparation commit for future changes purpose. Separate code responsible for storing log message in proper format from operations on consoles by putting it in another function. Signed-off-by: Marcin Niesluchowski --- kernel/printk/printk.c | 183 ++++++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 85 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 98f5af5..105887c 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -602,6 +602,102 @@ static size_t cont_print_text(char *text, size_t size) return textlen; } +static int log_format_and_store(int facility, int level, + const char *dict, size_t dictlen, + const char *fmt, va_list args) +{ + static char textbuf[LOG_LINE_MAX]; + char *text = textbuf; + size_t text_len = 0; + enum log_flags lflags = 0; + int printed_len = 0; + + /* + * The printf needs to come first; we need the syslog + * prefix which might be passed-in as a parameter. + */ + text_len = vscnprintf(text, sizeof(textbuf), fmt, args); + + /* mark and strip a trailing newline */ + if (text_len && text[text_len-1] == '\n') { + text_len--; + lflags |= LOG_NEWLINE; + } + + /* strip kernel syslog prefix and extract log level or control flags */ + if (facility == 0) { + int kern_level = printk_get_level(text); + + if (kern_level) { + const char *end_of_header = printk_skip_level(text); + + switch (kern_level) { + case '0' ... '7': + if (level == LOGLEVEL_DEFAULT) + level = kern_level - '0'; + /* fallthrough */ + case 'd': /* KERN_DEFAULT */ + lflags |= LOG_PREFIX; + } + /* + * No need to check length here because vscnprintf + * put '\0' at the end of the string. Only valid and + * newly printed level is detected. + */ + text_len -= end_of_header - text; + text = (char *)end_of_header; + } + } + + if (level == LOGLEVEL_DEFAULT) + level = default_message_loglevel; + + if (dict) + lflags |= LOG_PREFIX|LOG_NEWLINE; + + if (!(lflags & LOG_NEWLINE)) { + /* + * Flush the conflicting buffer. An earlier newline was missing, + * or another task also prints continuation lines. + */ + if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) + cont_flush(LOG_NEWLINE); + + /* buffer line if possible, otherwise store it right away */ + if (cont_add(facility, level, text, text_len)) + printed_len += text_len; + else + printed_len += log_store(facility, level, + lflags | LOG_CONT, 0, + dict, dictlen, text, text_len); + } else { + bool stored = false; + + /* + * If an earlier newline was missing and it was the same task, + * either merge it with the current buffer and flush, or if + * there was a race with interrupts (prefix == true) then just + * flush it out and store this line separately. + * If the preceding printk was from a different task and missed + * a newline, flush and append the newline. + */ + if (cont.len) { + if (cont.owner == current && !(lflags & LOG_PREFIX)) + stored = cont_add(facility, level, text, + text_len); + cont_flush(LOG_NEWLINE); + } + + if (stored) + printed_len += text_len; + else + printed_len += log_store(facility, level, + lflags, 0, dict, dictlen, + text, text_len); + } + return printed_len; +} + int dmesg_restrict = IS_ENABLED(CONFIG_SECURITY_DMESG_RESTRICT); static int syslog_action_restricted(int type) @@ -1657,10 +1753,6 @@ asmlinkage int vprintk_emit(int facility, int level, const char *fmt, va_list args) { static int recursion_bug; - static char textbuf[LOG_LINE_MAX]; - char *text = textbuf; - size_t text_len = 0; - enum log_flags lflags = 0; unsigned long flags; int this_cpu; int printed_len = 0; @@ -1714,87 +1806,8 @@ asmlinkage int vprintk_emit(int facility, int level, strlen(recursion_msg)); } - /* - * The printf needs to come first; we need the syslog - * prefix which might be passed-in as a parameter. - */ - text_len = vscnprintf(text, sizeof(textbuf), fmt, args); - - /* mark and strip a trailing newline */ - if (text_len && text[text_len-1] == '\n') { - text_len--; - lflags |= LOG_NEWLINE; - } - - /* strip kernel syslog prefix and extract log level or control flags */ - if (facility == 0) { - int kern_level = printk_get_level(text); - - if (kern_level) { - const char *end_of_header = printk_skip_level(text); - switch (kern_level) { - case '0' ... '7': - if (level == LOGLEVEL_DEFAULT) - level = kern_level - '0'; - /* fallthrough */ - case 'd': /* KERN_DEFAULT */ - lflags |= LOG_PREFIX; - } - /* - * No need to check length here because vscnprintf - * put '\0' at the end of the string. Only valid and - * newly printed level is detected. - */ - text_len -= end_of_header - text; - text = (char *)end_of_header; - } - } - - if (level == LOGLEVEL_DEFAULT) - level = default_message_loglevel; - - if (dict) - lflags |= LOG_PREFIX|LOG_NEWLINE; - - if (!(lflags & LOG_NEWLINE)) { - /* - * Flush the conflicting buffer. An earlier newline was missing, - * or another task also prints continuation lines. - */ - if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) - cont_flush(LOG_NEWLINE); - - /* buffer line if possible, otherwise store it right away */ - if (cont_add(facility, level, text, text_len)) - printed_len += text_len; - else - printed_len += log_store(facility, level, - lflags | LOG_CONT, 0, - dict, dictlen, text, text_len); - } else { - bool stored = false; - - /* - * If an earlier newline was missing and it was the same task, - * either merge it with the current buffer and flush, or if - * there was a race with interrupts (prefix == true) then just - * flush it out and store this line separately. - * If the preceding printk was from a different task and missed - * a newline, flush and append the newline. - */ - if (cont.len) { - if (cont.owner == current && !(lflags & LOG_PREFIX)) - stored = cont_add(facility, level, text, - text_len); - cont_flush(LOG_NEWLINE); - } - - if (stored) - printed_len += text_len; - else - printed_len += log_store(facility, level, lflags, 0, - dict, dictlen, text, text_len); - } + printed_len += log_format_and_store(facility, level, dict, dictlen, + fmt, args); logbuf_cpu = UINT_MAX; raw_spin_unlock(&logbuf_lock); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/