If the buffer pass to msg_print_text is not big enough to put both all
prefixes and log_text(msg), kernel will quietly break.
That means the user may not have the chance to know whether the
log_text(msg) is fully printed into buffer or not.

In this patch, once above case happened, we try to calculate how many
characters of log_text(msg) are dropped and add warning for debugging
purpose.

Signed-off-by: pierre Kuo <vichy....@gmail.com>
---
Changes since v2:
 * fix typo in commit message from "waring for debugging purpose" to "warning 
for debugging purpose"

 kernel/printk/printk.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index fc47863..6cbb3699 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -558,6 +558,12 @@ static u32 msg_used_size(u16 text_len, u16 dict_len, u32 
*pad_len)
 #define MAX_LOG_TAKE_PART 4
 static const char trunc_msg[] = "<truncated>";
 
+/*
+ * Define max drop msg length that we put in next msg
+ */
+#define MAX_DROP_MSG_LENGTH 32
+static char drop_msg[MAX_DROP_MSG_LENGTH];
+
 static u32 truncate_msg(u16 *text_len, u16 *trunc_msg_len,
                        u16 *dict_len, u32 *pad_len)
 {
@@ -1264,8 +1270,23 @@ static size_t msg_print_text(const struct printk_log 
*msg, bool syslog, char *bu
 
                if (buf) {
                        if (print_prefix(msg, syslog, NULL) +
-                           text_len + 1 >= size - len)
+                           text_len + 1 >= size - len) {
+                               /* below stores dropped characters
+                                * related information in next msg
+                                */
+                               size_t drop_len;
+
+                               drop_len = scnprintf(drop_msg,
+                                       MAX_DROP_MSG_LENGTH,
+                                       "<%u characters dropped>",
+                                       (next) ?
+                                       (unsigned int)(text_size + next - text) 
:
+                                       (unsigned int)text_size);
+                               drop_msg[drop_len] = 0;
+                               log_store(msg->facility, msg->level, msg->flags,
+                                       0, NULL, 0, drop_msg, strlen(drop_msg));
                                break;
+                       }
 
                        len += print_prefix(msg, syslog, buf + len);
                        memcpy(buf + len, text, text_len);
-- 
1.9.1

Reply via email to