2012-10-17 06:06:40

by Joe Perches

[permalink] [raw]
Subject: [PATCH 00/23] printk: refactoring

Make printk a bit more readable.

Joe Perches (23):
printk: Move to separate directory for easier modification
printk: Add console_cmdline.h
printk: Move braille console support into separate braille.[ch] files
printk: Use pointer for console_cmdline indexing
printk: rename struct log to struct printk_log
printk: Rename log_buf and __LOG_BUF_LEN
printk: Rename log_first and log_next variables
printk: Rename log_<foo> variables and functions
printk: Rename enum log_flags to printk_log_flags
printk: Rename log_wait to printk_log_wait
printk: Rename logbuf_lock to printk_logbuf_lock
printk: Rename clear_seq and clear_idx variables
printk: Remove static from printk_ variables
printk: Rename LOG_ALIGN to PRINTK_LOG_ALIGN
printk: Add and use printk_log.h
printk: Add printk_log.c
printk: Make wait_queue_head_t printk_log_wait extern
printk: Rename and move 2 #defines to printk_log.h
printk: Move devkmsg bits to separate file
printk: Prefix print_time and msg_print_text with printk_
printk: Move functions printk_print_time and printk_msg_print_text
printk: Add printk_syslog.c and .h
printk: Move kmsg_dump functions to separate file

drivers/accessibility/braille/braille_console.c | 9 +-
fs/proc/kmsg.c | 4 +-
kernel/Makefile | 3 +-
kernel/printk.c | 2820 -----------------------
kernel/printk/Makefile | 6 +
kernel/printk/braille.c | 48 +
kernel/printk/braille.h | 48 +
kernel/printk/console_cmdline.h | 14 +
kernel/printk/devkmsg.c | 309 +++
kernel/printk/kmsg_dump.c | 328 +++
kernel/printk/printk.c | 1515 ++++++++++++
kernel/printk/printk_log.c | 263 +++
kernel/printk/printk_log.h | 123 +
kernel/printk/printk_syslog.c | 354 +++
kernel/printk/printk_syslog.h | 12 +
15 files changed, 3031 insertions(+), 2825 deletions(-)
delete mode 100644 kernel/printk.c
create mode 100644 kernel/printk/Makefile
create mode 100644 kernel/printk/braille.c
create mode 100644 kernel/printk/braille.h
create mode 100644 kernel/printk/console_cmdline.h
create mode 100644 kernel/printk/devkmsg.c
create mode 100644 kernel/printk/kmsg_dump.c
create mode 100644 kernel/printk/printk.c
create mode 100644 kernel/printk/printk_log.c
create mode 100644 kernel/printk/printk_log.h
create mode 100644 kernel/printk/printk_syslog.c
create mode 100644 kernel/printk/printk_syslog.h

--
1.7.10.4


2012-10-17 06:06:51

by Joe Perches

[permalink] [raw]
Subject: [PATCH 01/23] printk: Move to separate directory for easier modification

Make it easier to break up printk into bite-sized chunks.

Remove printk path/filename from comment.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/Makefile | 3 ++-
kernel/printk/Makefile | 1 +
kernel/{ => printk}/printk.c | 2 --
3 files changed, 3 insertions(+), 3 deletions(-)
create mode 100644 kernel/printk/Makefile
rename kernel/{ => printk}/printk.c (99%)

diff --git a/kernel/Makefile b/kernel/Makefile
index 0dfeca4..d53980d 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#

-obj-y = fork.o exec_domain.o panic.o printk.o \
+obj-y = fork.o exec_domain.o panic.o \
cpu.o exit.o itimer.o time.o softirq.o resource.o \
sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o workqueue.o pid.o task_work.o \
@@ -24,6 +24,7 @@ endif

obj-y += sched/
obj-y += power/
+obj-y += printk/

ifeq ($(CONFIG_CHECKPOINT_RESTORE),y)
obj-$(CONFIG_X86) += kcmp.o
diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
new file mode 100644
index 0000000..36d306d
--- /dev/null
+++ b/kernel/printk/Makefile
@@ -0,0 +1 @@
+obj-y = printk.o
diff --git a/kernel/printk.c b/kernel/printk/printk.c
similarity index 99%
rename from kernel/printk.c
rename to kernel/printk/printk.c
index 2d607f4..1950ecf 100644
--- a/kernel/printk.c
+++ b/kernel/printk/printk.c
@@ -1,6 +1,4 @@
/*
- * linux/kernel/printk.c
- *
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Modified to make sys_syslog() more flexible: added commands to
--
1.7.10.4

2012-10-17 06:07:01

by Joe Perches

[permalink] [raw]
Subject: [PATCH 02/23] printk: Add console_cmdline.h

Add an include file for the console_cmdline struct
so that the braille console driver can be separated.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/console_cmdline.h | 14 ++++++++++++++
kernel/printk/printk.c | 13 ++++---------
2 files changed, 18 insertions(+), 9 deletions(-)
create mode 100644 kernel/printk/console_cmdline.h

diff --git a/kernel/printk/console_cmdline.h b/kernel/printk/console_cmdline.h
new file mode 100644
index 0000000..cbd69d8
--- /dev/null
+++ b/kernel/printk/console_cmdline.h
@@ -0,0 +1,14 @@
+#ifndef _CONSOLE_CMDLINE_H
+#define _CONSOLE_CMDLINE_H
+
+struct console_cmdline
+{
+ char name[8]; /* Name of the driver */
+ int index; /* Minor dev. to use */
+ char *options; /* Options for the driver */
+#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
+ char *brl_options; /* Options for braille driver */
+#endif
+};
+
+#endif
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 1950ecf..50ef6af 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -46,6 +46,8 @@
#define CREATE_TRACE_POINTS
#include <trace/events/printk.h>

+#include "console_cmdline.h"
+
/*
* Architectures can override it:
*/
@@ -100,22 +102,15 @@ static int console_locked, console_suspended;
*/
static struct console *exclusive_console;

+
/*
* Array of consoles built from command line options (console=)
*/
-struct console_cmdline
-{
- char name[8]; /* Name of the driver */
- int index; /* Minor dev. to use */
- char *options; /* Options for the driver */
-#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
- char *brl_options; /* Options for braille driver */
-#endif
-};

#define MAX_CMDLINECONSOLES 8

static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+
static int selected_console = -1;
static int preferred_console = -1;
int console_set_on_cmdline;
--
1.7.10.4

2012-10-17 06:07:12

by Joe Perches

[permalink] [raw]
Subject: [PATCH 03/23] printk: Move braille console support into separate braille.[ch] files

Create files with prototypes and static inlines for braille
support. Make braille_console functions return 1 on success.

cc: Samuel Thibault <[email protected]>
Signed-off-by: Joe Perches <[email protected]>
---
drivers/accessibility/braille/braille_console.c | 9 ++++-
kernel/printk/Makefile | 1 +
kernel/printk/braille.c | 48 +++++++++++++++++++++++
kernel/printk/braille.h | 48 +++++++++++++++++++++++
kernel/printk/printk.c | 44 ++++++---------------
5 files changed, 117 insertions(+), 33 deletions(-)
create mode 100644 kernel/printk/braille.c
create mode 100644 kernel/printk/braille.h

diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
index d21167b..dc34a5b 100644
--- a/drivers/accessibility/braille/braille_console.c
+++ b/drivers/accessibility/braille/braille_console.c
@@ -359,6 +359,9 @@ int braille_register_console(struct console *console, int index,
char *console_options, char *braille_options)
{
int ret;
+
+ if (!(console->flags & CON_BRL))
+ return 0;
if (!console_options)
/* Only support VisioBraille for now */
console_options = "57600o8";
@@ -374,15 +377,17 @@ int braille_register_console(struct console *console, int index,
braille_co = console;
register_keyboard_notifier(&keyboard_notifier_block);
register_vt_notifier(&vt_notifier_block);
- return 0;
+ return 1;
}

int braille_unregister_console(struct console *console)
{
if (braille_co != console)
return -EINVAL;
+ if (!(console->flags & CON_BRL))
+ return 0;
unregister_keyboard_notifier(&keyboard_notifier_block);
unregister_vt_notifier(&vt_notifier_block);
braille_co = NULL;
- return 0;
+ return 1;
}
diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index 36d306d..85405bd 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1 +1,2 @@
obj-y = printk.o
+obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/braille.c b/kernel/printk/braille.c
new file mode 100644
index 0000000..b51087f
--- /dev/null
+++ b/kernel/printk/braille.c
@@ -0,0 +1,48 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/string.h>
+
+#include "console_cmdline.h"
+#include "braille.h"
+
+char *_braille_console_setup(char **str, char **brl_options)
+{
+ if (!memcmp(*str, "brl,", 4)) {
+ *brl_options = "";
+ *str += 4;
+ } else if (!memcmp(str, "brl=", 4)) {
+ *brl_options = *str + 4;
+ *str = strchr(*brl_options, ',');
+ if (!*str)
+ pr_err("need port name after brl=\n");
+ else
+ *((*str)++) = 0;
+ }
+
+ return *str;
+}
+
+int
+_braille_register_console(struct console *console, struct console_cmdline *c)
+{
+ int rtn = 0;
+
+ if (c->brl_options) {
+ console->flags |= CON_BRL;
+ rtn = braille_register_console(console, c->index, c->options,
+ c->brl_options);
+ }
+
+ return rtn;
+}
+
+int
+_braille_unregister_console(struct console *console)
+{
+ if (console->flags & CON_BRL)
+ return braille_unregister_console(console);
+
+ return 0;
+}
diff --git a/kernel/printk/braille.h b/kernel/printk/braille.h
new file mode 100644
index 0000000..d2e6bc3
--- /dev/null
+++ b/kernel/printk/braille.h
@@ -0,0 +1,48 @@
+#ifndef _PRINTK_BRAILLE_H
+#define _PRINTK_BRAILLE_H
+
+#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
+
+static inline void
+braille_set_options(struct console_cmdline *c, char *brl_options)
+{
+ c->brl_options = brl_options;
+}
+
+char *
+_braille_console_setup(char **str, char **brl_options);
+
+int
+_braille_register_console(struct console *console, struct console_cmdline *c);
+
+int
+_braille_unregister_console(struct console *console);
+
+#else
+
+static inline void
+braille_set_options(struct console_cmdline *c, char *brl_options)
+{
+}
+
+static inline char *
+_braille_console_setup(char **str, char **brl_options)
+{
+ return *str;
+}
+
+static inline int
+_braille_register_console(struct console *console, struct console_cmdline *c)
+{
+ return 0;
+}
+
+static inline int
+_braille_unregister_console(struct console *console)
+{
+ return 0;
+}
+
+#endif
+
+#endif
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 50ef6af..df5b80f 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -47,6 +47,7 @@
#include <trace/events/printk.h>

#include "console_cmdline.h"
+#include "braille.h"

/*
* Architectures can override it:
@@ -1731,9 +1732,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
c = &console_cmdline[i];
strlcpy(c->name, name, sizeof(c->name));
c->options = options;
-#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
- c->brl_options = brl_options;
-#endif
+ braille_set_options(c, brl_options);
+
c->index = idx;
return 0;
}
@@ -1746,20 +1746,8 @@ static int __init console_setup(char *str)
char *s, *options, *brl_options = NULL;
int idx;

-#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
- if (!memcmp(str, "brl,", 4)) {
- brl_options = "";
- str += 4;
- } else if (!memcmp(str, "brl=", 4)) {
- brl_options = str + 4;
- str = strchr(brl_options, ',');
- if (!str) {
- printk(KERN_ERR "need port name after brl=\n");
- return 1;
- }
- *(str++) = 0;
- }
-#endif
+ if (_braille_console_setup(&str, &brl_options))
+ return 1;

/*
* Decode str into name, index, options.
@@ -2286,16 +2274,10 @@ void register_console(struct console *newcon)
continue;
if (newcon->index < 0)
newcon->index = console_cmdline[i].index;
-#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
- if (console_cmdline[i].brl_options) {
- newcon->flags |= CON_BRL;
- braille_register_console(newcon,
- console_cmdline[i].index,
- console_cmdline[i].options,
- console_cmdline[i].brl_options);
+
+ if (_braille_register_console(newcon, &console_cmdline[i]))
return;
- }
-#endif
+
if (newcon->setup &&
newcon->setup(newcon, console_cmdline[i].options) != 0)
break;
@@ -2383,13 +2365,13 @@ EXPORT_SYMBOL(register_console);
int unregister_console(struct console *console)
{
struct console *a, *b;
- int res = 1;
+ int res;

-#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
- if (console->flags & CON_BRL)
- return braille_unregister_console(console);
-#endif
+ res = _braille_unregister_console(console);
+ if (res)
+ return res;

+ res = 1;
console_lock();
if (console_drivers == console) {
console_drivers=console->next;
--
1.7.10.4

2012-10-17 06:07:24

by Joe Perches

[permalink] [raw]
Subject: [PATCH 04/23] printk: Use pointer for console_cmdline indexing

Make the code a bit more compact by always using a pointer
for the active console_cmdline.

Move overly indented code to correct indent level.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 49 +++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index df5b80f..099c439 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1718,18 +1718,19 @@ static int __add_preferred_console(char *name, int idx, char *options,
* See if this tty is not yet registered, and
* if we have a slot free.
*/
- for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
- if (strcmp(console_cmdline[i].name, name) == 0 &&
- console_cmdline[i].index == idx) {
- if (!brl_options)
- selected_console = i;
- return 0;
+ for (i = 0, c = console_cmdline;
+ i < MAX_CMDLINECONSOLES && c->name[0];
+ i++, c++) {
+ if (strcmp(c->name, name) == 0 && c->index == idx) {
+ if (!brl_options)
+ selected_console = i;
+ return 0;
}
+ }
if (i == MAX_CMDLINECONSOLES)
return -E2BIG;
if (!brl_options)
selected_console = i;
- c = &console_cmdline[i];
strlcpy(c->name, name, sizeof(c->name));
c->options = options;
braille_set_options(c, brl_options);
@@ -1802,15 +1803,15 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
struct console_cmdline *c;
int i;

- for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
- if (strcmp(console_cmdline[i].name, name) == 0 &&
- console_cmdline[i].index == idx) {
- c = &console_cmdline[i];
- strlcpy(c->name, name_new, sizeof(c->name));
- c->name[sizeof(c->name) - 1] = 0;
- c->options = options;
- c->index = idx_new;
- return i;
+ for (i = 0, c = console_cmdline;
+ i < MAX_CMDLINECONSOLES && c->name[0];
+ i++, c++)
+ if (strcmp(c->name, name) == 0 && c->index == idx) {
+ strlcpy(c->name, name_new, sizeof(c->name));
+ c->name[sizeof(c->name) - 1] = 0;
+ c->options = options;
+ c->index = idx_new;
+ return i;
}
/* not found */
return -1;
@@ -2218,6 +2219,7 @@ void register_console(struct console *newcon)
int i;
unsigned long flags;
struct console *bcon = NULL;
+ struct console_cmdline *c;

/*
* before we register a new CON_BOOT console, make sure we don't
@@ -2265,24 +2267,25 @@ void register_console(struct console *newcon)
* See if this console matches one we selected on
* the command line.
*/
- for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0];
- i++) {
- if (strcmp(console_cmdline[i].name, newcon->name) != 0)
+ for (i = 0, c = console_cmdline;
+ i < MAX_CMDLINECONSOLES && c->name[0];
+ i++, c++) {
+ if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&
- newcon->index != console_cmdline[i].index)
+ newcon->index != c->index)
continue;
if (newcon->index < 0)
- newcon->index = console_cmdline[i].index;
+ newcon->index = c->index;

- if (_braille_register_console(newcon, &console_cmdline[i]))
+ if (_braille_register_console(newcon, c))
return;

if (newcon->setup &&
newcon->setup(newcon, console_cmdline[i].options) != 0)
break;
newcon->flags |= CON_ENABLED;
- newcon->index = console_cmdline[i].index;
+ newcon->index = c->index;
if (i == selected_console) {
newcon->flags |= CON_CONSDEV;
preferred_console = selected_console;
--
1.7.10.4

2012-10-17 06:07:34

by Joe Perches

[permalink] [raw]
Subject: [PATCH 05/23] printk: rename struct log to struct printk_log

Rename the struct to enable moving portions of
printk.c to separate files.

The rename changes output of /proc/vmcoreinfo.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 80 ++++++++++++++++++++++++------------------------
1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 099c439..da2db46 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -172,7 +172,7 @@ static int console_may_schedule;
* 67 "g"
* 0032 00 00 00 padding to next message header
*
- * The 'struct log' buffer header must never be directly exported to
+ * The 'struct printk_log' buffer header must never be directly exported to
* userspace, it is a kernel-private implementation detail that might
* need to be changed in the future, when the requirements change.
*
@@ -194,7 +194,7 @@ enum log_flags {
LOG_CONT = 8, /* text is a fragment of a continuation line */
};

-struct log {
+struct printk_log {
u64 ts_nsec; /* timestamp in nanoseconds */
u16 len; /* length of entire record */
u16 text_len; /* length of text buffer */
@@ -241,7 +241,7 @@ static u32 clear_idx;
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
#define LOG_ALIGN 4
#else
-#define LOG_ALIGN __alignof__(struct log)
+#define LOG_ALIGN __alignof__(struct printk_log)
#endif
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
@@ -252,35 +252,35 @@ static u32 log_buf_len = __LOG_BUF_LEN;
static volatile unsigned int logbuf_cpu = UINT_MAX;

/* human readable text of the record */
-static char *log_text(const struct log *msg)
+static char *log_text(const struct printk_log *msg)
{
- return (char *)msg + sizeof(struct log);
+ return (char *)msg + sizeof(struct printk_log);
}

/* optional key/value pair dictionary attached to the record */
-static char *log_dict(const struct log *msg)
+static char *log_dict(const struct printk_log *msg)
{
- return (char *)msg + sizeof(struct log) + msg->text_len;
+ return (char *)msg + sizeof(struct printk_log) + msg->text_len;
}

/* get record by index; idx must point to valid msg */
-static struct log *log_from_idx(u32 idx)
+static struct printk_log *log_from_idx(u32 idx)
{
- struct log *msg = (struct log *)(log_buf + idx);
+ struct printk_log *msg = (struct printk_log *)(log_buf + idx);

/*
* A length == 0 record is the end of buffer marker. Wrap around and
* read the message at the start of the buffer.
*/
if (!msg->len)
- return (struct log *)log_buf;
+ return (struct printk_log *)log_buf;
return msg;
}

/* get next record; idx must point to valid msg */
static u32 log_next(u32 idx)
{
- struct log *msg = (struct log *)(log_buf + idx);
+ struct printk_log *msg = (struct printk_log *)(log_buf + idx);

/* length == 0 indicates the end of the buffer; wrap */
/*
@@ -289,7 +289,7 @@ static u32 log_next(u32 idx)
* return the one after that.
*/
if (!msg->len) {
- msg = (struct log *)log_buf;
+ msg = (struct printk_log *)log_buf;
return msg->len;
}
return idx + msg->len;
@@ -301,11 +301,11 @@ static void log_store(int facility, int level,
const char *dict, u16 dict_len,
const char *text, u16 text_len)
{
- struct log *msg;
+ struct printk_log *msg;
u32 size, pad_len;

/* number of '\0' padding bytes to next message */
- size = sizeof(struct log) + text_len + dict_len;
+ size = sizeof(struct printk_log) + text_len + dict_len;
pad_len = (-size) & (LOG_ALIGN - 1);
size += pad_len;

@@ -317,7 +317,7 @@ static void log_store(int facility, int level,
else
free = log_first_idx - log_next_idx;

- if (free > size + sizeof(struct log))
+ if (free > size + sizeof(struct printk_log))
break;

/* drop old messages until we have enough contiuous space */
@@ -325,18 +325,18 @@ static void log_store(int facility, int level,
log_first_seq++;
}

- if (log_next_idx + size + sizeof(struct log) >= log_buf_len) {
+ if (log_next_idx + size + sizeof(struct printk_log) >= log_buf_len) {
/*
* This message + an additional empty header does not fit
* at the end of the buffer. Add an empty header with len == 0
* to signify a wrap around.
*/
- memset(log_buf + log_next_idx, 0, sizeof(struct log));
+ memset(log_buf + log_next_idx, 0, sizeof(struct printk_log));
log_next_idx = 0;
}

/* fill message */
- msg = (struct log *)(log_buf + log_next_idx);
+ msg = (struct printk_log *)(log_buf + log_next_idx);
memcpy(log_text(msg), text, text_len);
msg->text_len = text_len;
memcpy(log_dict(msg), dict, dict_len);
@@ -349,7 +349,7 @@ static void log_store(int facility, int level,
else
msg->ts_nsec = local_clock();
memset(log_dict(msg) + dict_len, 0, pad_len);
- msg->len = sizeof(struct log) + text_len + dict_len + pad_len;
+ msg->len = sizeof(struct printk_log) + text_len + dict_len + pad_len;

/* insert message */
log_next_idx += msg->len;
@@ -425,7 +425,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct devkmsg_user *user = file->private_data;
- struct log *msg;
+ struct printk_log *msg;
u64 ts_usec;
size_t i;
char cont = '-';
@@ -668,14 +668,14 @@ void log_buf_kexec_setup(void)
VMCOREINFO_SYMBOL(log_first_idx);
VMCOREINFO_SYMBOL(log_next_idx);
/*
- * Export struct log size and field offsets. User space tools can
+ * Export struct printk_log size and field offsets. User space tools can
* parse it and detect any changes to structure down the line.
*/
- VMCOREINFO_STRUCT_SIZE(log);
- VMCOREINFO_OFFSET(log, ts_nsec);
- VMCOREINFO_OFFSET(log, len);
- VMCOREINFO_OFFSET(log, text_len);
- VMCOREINFO_OFFSET(log, dict_len);
+ VMCOREINFO_STRUCT_SIZE(printk_log);
+ VMCOREINFO_OFFSET(printk_log, ts_nsec);
+ VMCOREINFO_OFFSET(printk_log, len);
+ VMCOREINFO_OFFSET(printk_log, text_len);
+ VMCOREINFO_OFFSET(printk_log, dict_len);
}
#endif

@@ -849,7 +849,7 @@ static size_t print_time(u64 ts, char *buf)
(unsigned long)ts, rem_nsec / 1000);
}

-static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
+static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
{
size_t len = 0;
unsigned int prefix = (msg->facility << 3) | msg->level;
@@ -872,7 +872,7 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
return len;
}

-static size_t msg_print_text(const struct log *msg, enum log_flags prev,
+static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size)
{
const char *text = log_text(msg);
@@ -934,7 +934,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev,
static int syslog_print(char __user *buf, int size)
{
char *text;
- struct log *msg;
+ struct printk_log *msg;
int len = 0;

text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
@@ -1025,7 +1025,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx;
prev = 0;
while (seq < log_next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);

len += msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags;
@@ -1038,7 +1038,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx;
prev = 0;
while (len > size && seq < log_next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);

len -= msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags;
@@ -1052,7 +1052,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
len = 0;
prev = 0;
while (len >= 0 && seq < next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);
int textlen;

textlen = msg_print_text(msg, prev, true, text,
@@ -1198,7 +1198,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)

error = 0;
while (seq < log_next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);

error += msg_print_text(msg, prev, true, NULL, 0);
idx = log_next(idx);
@@ -1699,10 +1699,10 @@ static struct cont {
u8 level;
bool flushed:1;
} cont;
-static struct log *log_from_idx(u32 idx) { return NULL; }
+static struct printk_log *log_from_idx(u32 idx) { return NULL; }
static u32 log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
-static size_t msg_print_text(const struct log *msg, enum log_flags prev,
+static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size) { return 0; }
static size_t cont_print_text(char *text, size_t size) { return 0; }

@@ -2025,7 +2025,7 @@ void console_unlock(void)
console_cont_flush(text, sizeof(text));
again:
for (;;) {
- struct log *msg;
+ struct printk_log *msg;
size_t len;
int level;

@@ -2601,7 +2601,7 @@ void kmsg_dump(enum kmsg_dump_reason reason)
bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
char *line, size_t size, size_t *len)
{
- struct log *msg;
+ struct printk_log *msg;
size_t l = 0;
bool ret = false;

@@ -2713,7 +2713,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper->cur_idx;
prev = 0;
while (seq < dumper->next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);

l += msg_print_text(msg, prev, true, NULL, 0);
idx = log_next(idx);
@@ -2726,7 +2726,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper->cur_idx;
prev = 0;
while (l > size && seq < dumper->next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);

l -= msg_print_text(msg, prev, true, NULL, 0);
idx = log_next(idx);
@@ -2741,7 +2741,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
l = 0;
prev = 0;
while (seq < dumper->next_seq) {
- struct log *msg = log_from_idx(idx);
+ struct printk_log *msg = log_from_idx(idx);

l += msg_print_text(msg, prev, syslog, buf + l, size - l);
idx = log_next(idx);
--
1.7.10.4

2012-10-17 06:07:41

by Joe Perches

[permalink] [raw]
Subject: [PATCH 06/23] printk: Rename log_buf and __LOG_BUF_LEN

Make these generic names more specific to the printk
subsystem and allow these variables to become non-static.

Rename log_buf to printk_log_buf.
Rename __LOG_BUF_LEN define to __PRINTK_LOG_BUF_LEN.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 76 ++++++++++++++++++++++++------------------------
1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index da2db46..c45afb1 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -243,10 +243,10 @@ static u32 clear_idx;
#else
#define LOG_ALIGN __alignof__(struct printk_log)
#endif
-#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
-static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
-static char *log_buf = __log_buf;
-static u32 log_buf_len = __LOG_BUF_LEN;
+#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+static char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(LOG_ALIGN);
+static char *printk_log_buf = __printk_log_buf;
+static u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;

/* cpu currently holding logbuf_lock */
static volatile unsigned int logbuf_cpu = UINT_MAX;
@@ -266,21 +266,21 @@ static char *log_dict(const struct printk_log *msg)
/* get record by index; idx must point to valid msg */
static struct printk_log *log_from_idx(u32 idx)
{
- struct printk_log *msg = (struct printk_log *)(log_buf + idx);
+ struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);

/*
* A length == 0 record is the end of buffer marker. Wrap around and
* read the message at the start of the buffer.
*/
if (!msg->len)
- return (struct printk_log *)log_buf;
+ return (struct printk_log *)printk_log_buf;
return msg;
}

/* get next record; idx must point to valid msg */
static u32 log_next(u32 idx)
{
- struct printk_log *msg = (struct printk_log *)(log_buf + idx);
+ struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);

/* length == 0 indicates the end of the buffer; wrap */
/*
@@ -289,7 +289,7 @@ static u32 log_next(u32 idx)
* return the one after that.
*/
if (!msg->len) {
- msg = (struct printk_log *)log_buf;
+ msg = (struct printk_log *)printk_log_buf;
return msg->len;
}
return idx + msg->len;
@@ -313,7 +313,7 @@ static void log_store(int facility, int level,
u32 free;

if (log_next_idx > log_first_idx)
- free = max(log_buf_len - log_next_idx, log_first_idx);
+ free = max(printk_log_buf_len - log_next_idx, log_first_idx);
else
free = log_first_idx - log_next_idx;

@@ -325,18 +325,18 @@ static void log_store(int facility, int level,
log_first_seq++;
}

- if (log_next_idx + size + sizeof(struct printk_log) >= log_buf_len) {
+ if (log_next_idx + size + sizeof(struct printk_log) >= printk_log_buf_len) {
/*
* This message + an additional empty header does not fit
* at the end of the buffer. Add an empty header with len == 0
* to signify a wrap around.
*/
- memset(log_buf + log_next_idx, 0, sizeof(struct printk_log));
+ memset(printk_log_buf + log_next_idx, 0, sizeof(struct printk_log));
log_next_idx = 0;
}

/* fill message */
- msg = (struct printk_log *)(log_buf + log_next_idx);
+ msg = (struct printk_log *)(printk_log_buf + log_next_idx);
memcpy(log_text(msg), text, text_len);
msg->text_len = text_len;
memcpy(log_dict(msg), dict, dict_len);
@@ -663,8 +663,8 @@ const struct file_operations kmsg_fops = {
*/
void log_buf_kexec_setup(void)
{
- VMCOREINFO_SYMBOL(log_buf);
- VMCOREINFO_SYMBOL(log_buf_len);
+ VMCOREINFO_SYMBOL(printk_log_buf);
+ VMCOREINFO_SYMBOL(printk_log_buf_len);
VMCOREINFO_SYMBOL(log_first_idx);
VMCOREINFO_SYMBOL(log_next_idx);
/*
@@ -679,60 +679,60 @@ void log_buf_kexec_setup(void)
}
#endif

-/* requested log_buf_len from kernel cmdline */
-static unsigned long __initdata new_log_buf_len;
+/* requested printk_log_buf_len from kernel cmdline */
+static unsigned long __initdata new_printk_log_buf_len;

-/* save requested log_buf_len since it's too early to process it */
-static int __init log_buf_len_setup(char *str)
+/* save requested printk_log_buf_len since it's too early to process it */
+static int __init printk_log_buf_len_setup(char *str)
{
unsigned size = memparse(str, &str);

if (size)
size = roundup_pow_of_two(size);
- if (size > log_buf_len)
- new_log_buf_len = size;
+ if (size > printk_log_buf_len)
+ new_printk_log_buf_len = size;

return 0;
}
-early_param("log_buf_len", log_buf_len_setup);
+early_param("log_buf_len", printk_log_buf_len_setup);

void __init setup_log_buf(int early)
{
unsigned long flags;
- char *new_log_buf;
+ char *new_printk_log_buf;
int free;

- if (!new_log_buf_len)
+ if (!new_printk_log_buf_len)
return;

if (early) {
unsigned long mem;

- mem = memblock_alloc(new_log_buf_len, PAGE_SIZE);
+ mem = memblock_alloc(new_printk_log_buf_len, PAGE_SIZE);
if (!mem)
return;
- new_log_buf = __va(mem);
+ new_printk_log_buf = __va(mem);
} else {
- new_log_buf = alloc_bootmem_nopanic(new_log_buf_len);
+ new_printk_log_buf = alloc_bootmem_nopanic(new_printk_log_buf_len);
}

- if (unlikely(!new_log_buf)) {
- pr_err("log_buf_len: %ld bytes not available\n",
- new_log_buf_len);
+ if (unlikely(!new_printk_log_buf)) {
+ pr_err("printk_log_buf_len: %ld bytes not available\n",
+ new_printk_log_buf_len);
return;
}

raw_spin_lock_irqsave(&logbuf_lock, flags);
- log_buf_len = new_log_buf_len;
- log_buf = new_log_buf;
- new_log_buf_len = 0;
- free = __LOG_BUF_LEN - log_next_idx;
- memcpy(log_buf, __log_buf, __LOG_BUF_LEN);
+ printk_log_buf_len = new_printk_log_buf_len;
+ printk_log_buf = new_printk_log_buf;
+ new_printk_log_buf_len = 0;
+ free = __PRINTK_LOG_BUF_LEN - log_next_idx;
+ memcpy(printk_log_buf, __printk_log_buf, __PRINTK_LOG_BUF_LEN);
raw_spin_unlock_irqrestore(&logbuf_lock, flags);

- pr_info("log_buf_len: %d\n", log_buf_len);
+ pr_info("printk_log_buf_len: %d\n", printk_log_buf_len);
pr_info("early log buf free: %d(%d%%)\n",
- free, (free * 100) / __LOG_BUF_LEN);
+ free, (free * 100) / __PRINTK_LOG_BUF_LEN);
}

#ifdef CONFIG_BOOT_PRINTK_DELAY
@@ -1211,7 +1211,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
break;
/* Size of the log buffer */
case SYSLOG_ACTION_SIZE_BUFFER:
- error = log_buf_len;
+ error = printk_log_buf_len;
break;
default:
error = -EINVAL;
@@ -1243,7 +1243,7 @@ MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to"

/*
* Call the console drivers, asking them to write out
- * log_buf[start] to log_buf[end - 1].
+ * printk_log_buf[start] to printk_log_buf[end - 1].
* The console_lock must be held.
*/
static void call_console_drivers(int level, const char *text, size_t len)
--
1.7.10.4

2012-10-17 06:07:49

by Joe Perches

[permalink] [raw]
Subject: [PATCH 07/23] printk: Rename log_first and log_next variables

Make these generic names more specific to the printk
subsystem and allow these variables to become non-static.

Rename log_first_idx to printk_log_first_idx.
Rename log_first_seq to printk_log_first_seq.
Rename log_next_idx to printk_log_next_idx.
Rename log_next_seq to printk_log_next_seq.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 150 ++++++++++++++++++++++++------------------------
1 file changed, 75 insertions(+), 75 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c45afb1..602a1ab 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -218,12 +218,12 @@ static enum log_flags syslog_prev;
static size_t syslog_partial;

/* index and sequence number of the first record stored in the buffer */
-static u64 log_first_seq;
-static u32 log_first_idx;
+static u64 printk_log_first_seq;
+static u32 printk_log_first_idx;

/* index and sequence number of the next record to store in the buffer */
-static u64 log_next_seq;
-static u32 log_next_idx;
+static u64 printk_log_next_seq;
+static u32 printk_log_next_idx;

/* the next printk record to write to the console */
static u64 console_seq;
@@ -309,34 +309,34 @@ static void log_store(int facility, int level,
pad_len = (-size) & (LOG_ALIGN - 1);
size += pad_len;

- while (log_first_seq < log_next_seq) {
+ while (printk_log_first_seq < printk_log_next_seq) {
u32 free;

- if (log_next_idx > log_first_idx)
- free = max(printk_log_buf_len - log_next_idx, log_first_idx);
+ if (printk_log_next_idx > printk_log_first_idx)
+ free = max(printk_log_buf_len - printk_log_next_idx, printk_log_first_idx);
else
- free = log_first_idx - log_next_idx;
+ free = printk_log_first_idx - printk_log_next_idx;

if (free > size + sizeof(struct printk_log))
break;

/* drop old messages until we have enough contiuous space */
- log_first_idx = log_next(log_first_idx);
- log_first_seq++;
+ printk_log_first_idx = log_next(printk_log_first_idx);
+ printk_log_first_seq++;
}

- if (log_next_idx + size + sizeof(struct printk_log) >= printk_log_buf_len) {
+ if (printk_log_next_idx + size + sizeof(struct printk_log) >= printk_log_buf_len) {
/*
* This message + an additional empty header does not fit
* at the end of the buffer. Add an empty header with len == 0
* to signify a wrap around.
*/
- memset(printk_log_buf + log_next_idx, 0, sizeof(struct printk_log));
- log_next_idx = 0;
+ memset(printk_log_buf + printk_log_next_idx, 0, sizeof(struct printk_log));
+ printk_log_next_idx = 0;
}

/* fill message */
- msg = (struct printk_log *)(printk_log_buf + log_next_idx);
+ msg = (struct printk_log *)(printk_log_buf + printk_log_next_idx);
memcpy(log_text(msg), text, text_len);
msg->text_len = text_len;
memcpy(log_dict(msg), dict, dict_len);
@@ -352,8 +352,8 @@ static void log_store(int facility, int level,
msg->len = sizeof(struct printk_log) + text_len + dict_len + pad_len;

/* insert message */
- log_next_idx += msg->len;
- log_next_seq++;
+ printk_log_next_idx += msg->len;
+ printk_log_next_seq++;
}

/* /dev/kmsg - userspace message inject/listen interface */
@@ -439,7 +439,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
if (ret)
return ret;
raw_spin_lock_irq(&logbuf_lock);
- while (user->seq == log_next_seq) {
+ while (user->seq == printk_log_next_seq) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
raw_spin_unlock_irq(&logbuf_lock);
@@ -448,16 +448,16 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,

raw_spin_unlock_irq(&logbuf_lock);
ret = wait_event_interruptible(log_wait,
- user->seq != log_next_seq);
+ user->seq != printk_log_next_seq);
if (ret)
goto out;
raw_spin_lock_irq(&logbuf_lock);
}

- if (user->seq < log_first_seq) {
+ if (user->seq < printk_log_first_seq) {
/* our last seen message is gone, return error and reset */
- user->idx = log_first_idx;
- user->seq = log_first_seq;
+ user->idx = printk_log_first_idx;
+ user->seq = printk_log_first_seq;
ret = -EPIPE;
raw_spin_unlock_irq(&logbuf_lock);
goto out;
@@ -557,8 +557,8 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
switch (whence) {
case SEEK_SET:
/* the first record */
- user->idx = log_first_idx;
- user->seq = log_first_seq;
+ user->idx = printk_log_first_idx;
+ user->seq = printk_log_first_seq;
break;
case SEEK_DATA:
/*
@@ -571,8 +571,8 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
break;
case SEEK_END:
/* after the last record */
- user->idx = log_next_idx;
- user->seq = log_next_seq;
+ user->idx = printk_log_next_idx;
+ user->seq = printk_log_next_seq;
break;
default:
ret = -EINVAL;
@@ -592,9 +592,9 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait)
poll_wait(file, &log_wait, wait);

raw_spin_lock_irq(&logbuf_lock);
- if (user->seq < log_next_seq) {
+ if (user->seq < printk_log_next_seq) {
/* return error when data has vanished underneath us */
- if (user->seq < log_first_seq)
+ if (user->seq < printk_log_first_seq)
ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI;
ret = POLLIN|POLLRDNORM;
}
@@ -623,8 +623,8 @@ static int devkmsg_open(struct inode *inode, struct file *file)
mutex_init(&user->lock);

raw_spin_lock_irq(&logbuf_lock);
- user->idx = log_first_idx;
- user->seq = log_first_seq;
+ user->idx = printk_log_first_idx;
+ user->seq = printk_log_first_seq;
raw_spin_unlock_irq(&logbuf_lock);

file->private_data = user;
@@ -665,8 +665,8 @@ void log_buf_kexec_setup(void)
{
VMCOREINFO_SYMBOL(printk_log_buf);
VMCOREINFO_SYMBOL(printk_log_buf_len);
- VMCOREINFO_SYMBOL(log_first_idx);
- VMCOREINFO_SYMBOL(log_next_idx);
+ VMCOREINFO_SYMBOL(printk_log_first_idx);
+ VMCOREINFO_SYMBOL(printk_log_next_idx);
/*
* Export struct printk_log size and field offsets. User space tools can
* parse it and detect any changes to structure down the line.
@@ -726,7 +726,7 @@ void __init setup_log_buf(int early)
printk_log_buf_len = new_printk_log_buf_len;
printk_log_buf = new_printk_log_buf;
new_printk_log_buf_len = 0;
- free = __PRINTK_LOG_BUF_LEN - log_next_idx;
+ free = __PRINTK_LOG_BUF_LEN - printk_log_next_idx;
memcpy(printk_log_buf, __printk_log_buf, __PRINTK_LOG_BUF_LEN);
raw_spin_unlock_irqrestore(&logbuf_lock, flags);

@@ -946,14 +946,14 @@ static int syslog_print(char __user *buf, int size)
size_t skip;

raw_spin_lock_irq(&logbuf_lock);
- if (syslog_seq < log_first_seq) {
+ if (syslog_seq < printk_log_first_seq) {
/* messages are gone, move to first one */
- syslog_seq = log_first_seq;
- syslog_idx = log_first_idx;
+ syslog_seq = printk_log_first_seq;
+ syslog_idx = printk_log_first_idx;
syslog_prev = 0;
syslog_partial = 0;
}
- if (syslog_seq == log_next_seq) {
+ if (syslog_seq == printk_log_next_seq) {
raw_spin_unlock_irq(&logbuf_lock);
break;
}
@@ -1011,10 +1011,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
u32 idx;
enum log_flags prev;

- if (clear_seq < log_first_seq) {
+ if (clear_seq < printk_log_first_seq) {
/* messages are gone, move to first available one */
- clear_seq = log_first_seq;
- clear_idx = log_first_idx;
+ clear_seq = printk_log_first_seq;
+ clear_idx = printk_log_first_idx;
}

/*
@@ -1024,7 +1024,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
seq = clear_seq;
idx = clear_idx;
prev = 0;
- while (seq < log_next_seq) {
+ while (seq < printk_log_next_seq) {
struct printk_log *msg = log_from_idx(idx);

len += msg_print_text(msg, prev, true, NULL, 0);
@@ -1037,7 +1037,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
seq = clear_seq;
idx = clear_idx;
prev = 0;
- while (len > size && seq < log_next_seq) {
+ while (len > size && seq < printk_log_next_seq) {
struct printk_log *msg = log_from_idx(idx);

len -= msg_print_text(msg, prev, true, NULL, 0);
@@ -1047,7 +1047,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
}

/* last message fitting into this dump */
- next_seq = log_next_seq;
+ next_seq = printk_log_next_seq;

len = 0;
prev = 0;
@@ -1072,18 +1072,18 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
len += textlen;
raw_spin_lock_irq(&logbuf_lock);

- if (seq < log_first_seq) {
+ if (seq < printk_log_first_seq) {
/* messages are gone, move to next one */
- seq = log_first_seq;
- idx = log_first_idx;
+ seq = printk_log_first_seq;
+ idx = printk_log_first_idx;
prev = 0;
}
}
}

if (clear) {
- clear_seq = log_next_seq;
- clear_idx = log_next_idx;
+ clear_seq = printk_log_next_seq;
+ clear_idx = printk_log_next_idx;
}
raw_spin_unlock_irq(&logbuf_lock);

@@ -1122,7 +1122,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
goto out;
}
error = wait_event_interruptible(log_wait,
- syslog_seq != log_next_seq);
+ syslog_seq != printk_log_next_seq);
if (error)
goto out;
error = syslog_print(buf, len);
@@ -1177,10 +1177,10 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
/* Number of chars in the log buffer */
case SYSLOG_ACTION_SIZE_UNREAD:
raw_spin_lock_irq(&logbuf_lock);
- if (syslog_seq < log_first_seq) {
+ if (syslog_seq < printk_log_first_seq) {
/* messages are gone, move to first one */
- syslog_seq = log_first_seq;
- syslog_idx = log_first_idx;
+ syslog_seq = printk_log_first_seq;
+ syslog_idx = printk_log_first_idx;
syslog_prev = 0;
syslog_partial = 0;
}
@@ -1190,14 +1190,14 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
* for pending data, not the size; return the count of
* records, not the length.
*/
- error = log_next_idx - syslog_idx;
+ error = printk_log_next_idx - syslog_idx;
} else {
u64 seq = syslog_seq;
u32 idx = syslog_idx;
enum log_flags prev = syslog_prev;

error = 0;
- while (seq < log_next_seq) {
+ while (seq < printk_log_next_seq) {
struct printk_log *msg = log_from_idx(idx);

error += msg_print_text(msg, prev, true, NULL, 0);
@@ -1689,9 +1689,9 @@ static u32 syslog_idx;
static u64 console_seq;
static u32 console_idx;
static enum log_flags syslog_prev;
-static u64 log_first_seq;
-static u32 log_first_idx;
-static u64 log_next_seq;
+static u64 printk_log_first_seq;
+static u32 printk_log_first_idx;
+static u64 printk_log_next_seq;
static enum log_flags console_prev;
static struct cont {
size_t len;
@@ -1978,7 +1978,7 @@ static void console_cont_flush(char *text, size_t size)
* busy. The earlier ones need to be printed before this one, we
* did not flush any fragment so far, so just let it queue up.
*/
- if (console_seq < log_next_seq && !cont.cons)
+ if (console_seq < printk_log_next_seq && !cont.cons)
goto out;

len = cont_print_text(text, size);
@@ -2030,19 +2030,19 @@ again:
int level;

raw_spin_lock_irqsave(&logbuf_lock, flags);
- if (seen_seq != log_next_seq) {
+ if (seen_seq != printk_log_next_seq) {
wake_klogd = true;
- seen_seq = log_next_seq;
+ seen_seq = printk_log_next_seq;
}

- if (console_seq < log_first_seq) {
+ if (console_seq < printk_log_first_seq) {
/* messages are gone, move to first one */
- console_seq = log_first_seq;
- console_idx = log_first_idx;
+ console_seq = printk_log_first_seq;
+ console_idx = printk_log_first_idx;
console_prev = 0;
}
skip:
- if (console_seq == log_next_seq)
+ if (console_seq == printk_log_next_seq)
break;

msg = log_from_idx(console_idx);
@@ -2093,7 +2093,7 @@ skip:
* flush, no worries.
*/
raw_spin_lock(&logbuf_lock);
- retry = console_seq != log_next_seq;
+ retry = console_seq != printk_log_next_seq;
raw_spin_unlock_irqrestore(&logbuf_lock, flags);

if (retry && console_trylock())
@@ -2566,8 +2566,8 @@ void kmsg_dump(enum kmsg_dump_reason reason)
raw_spin_lock_irqsave(&logbuf_lock, flags);
dumper->cur_seq = clear_seq;
dumper->cur_idx = clear_idx;
- dumper->next_seq = log_next_seq;
- dumper->next_idx = log_next_idx;
+ dumper->next_seq = printk_log_next_seq;
+ dumper->next_idx = printk_log_next_idx;
raw_spin_unlock_irqrestore(&logbuf_lock, flags);

/* invoke dumper which will iterate over records */
@@ -2608,14 +2608,14 @@ bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
if (!dumper->active)
goto out;

- if (dumper->cur_seq < log_first_seq) {
+ if (dumper->cur_seq < printk_log_first_seq) {
/* messages are gone, move to first available one */
- dumper->cur_seq = log_first_seq;
- dumper->cur_idx = log_first_idx;
+ dumper->cur_seq = printk_log_first_seq;
+ dumper->cur_idx = printk_log_first_idx;
}

/* last entry */
- if (dumper->cur_seq >= log_next_seq)
+ if (dumper->cur_seq >= printk_log_next_seq)
goto out;

msg = log_from_idx(dumper->cur_idx);
@@ -2696,10 +2696,10 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
goto out;

raw_spin_lock_irqsave(&logbuf_lock, flags);
- if (dumper->cur_seq < log_first_seq) {
+ if (dumper->cur_seq < printk_log_first_seq) {
/* messages are gone, move to first available one */
- dumper->cur_seq = log_first_seq;
- dumper->cur_idx = log_first_idx;
+ dumper->cur_seq = printk_log_first_seq;
+ dumper->cur_idx = printk_log_first_idx;
}

/* last entry */
@@ -2774,8 +2774,8 @@ void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
{
dumper->cur_seq = clear_seq;
dumper->cur_idx = clear_idx;
- dumper->next_seq = log_next_seq;
- dumper->next_idx = log_next_idx;
+ dumper->next_seq = printk_log_next_seq;
+ dumper->next_idx = printk_log_next_idx;
}

/**
--
1.7.10.4

2012-10-17 06:07:57

by Joe Perches

[permalink] [raw]
Subject: [PATCH 08/23] printk: Rename log_<foo> variables and functions

Make these generic names more specific to the printk
subsystem and allow these variables and functions to
become non-static.

Rename log_text to printk_log_text.
Rename log_dict to printk_log_dict.
Rename log_from_idx to printk_log_from_idx.
Rename log_next to printk_log_next.
Rename log_store to printk_log_store.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 100 ++++++++++++++++++++++++------------------------
1 file changed, 50 insertions(+), 50 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 602a1ab..992c064 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -252,19 +252,19 @@ static u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;
static volatile unsigned int logbuf_cpu = UINT_MAX;

/* human readable text of the record */
-static char *log_text(const struct printk_log *msg)
+static char *printk_log_text(const struct printk_log *msg)
{
return (char *)msg + sizeof(struct printk_log);
}

/* optional key/value pair dictionary attached to the record */
-static char *log_dict(const struct printk_log *msg)
+static char *printk_log_dict(const struct printk_log *msg)
{
return (char *)msg + sizeof(struct printk_log) + msg->text_len;
}

/* get record by index; idx must point to valid msg */
-static struct printk_log *log_from_idx(u32 idx)
+static struct printk_log *printk_log_from_idx(u32 idx)
{
struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);

@@ -278,7 +278,7 @@ static struct printk_log *log_from_idx(u32 idx)
}

/* get next record; idx must point to valid msg */
-static u32 log_next(u32 idx)
+static u32 printk_log_next(u32 idx)
{
struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);

@@ -296,10 +296,10 @@ static u32 log_next(u32 idx)
}

/* insert record into the buffer, discard old ones, update heads */
-static void log_store(int facility, int level,
- enum log_flags flags, u64 ts_nsec,
- const char *dict, u16 dict_len,
- const char *text, u16 text_len)
+static void printk_log_store(int facility, int level,
+ enum log_flags flags, u64 ts_nsec,
+ const char *dict, u16 dict_len,
+ const char *text, u16 text_len)
{
struct printk_log *msg;
u32 size, pad_len;
@@ -321,7 +321,7 @@ static void log_store(int facility, int level,
break;

/* drop old messages until we have enough contiuous space */
- printk_log_first_idx = log_next(printk_log_first_idx);
+ printk_log_first_idx = printk_log_next(printk_log_first_idx);
printk_log_first_seq++;
}

@@ -337,9 +337,9 @@ static void log_store(int facility, int level,

/* fill message */
msg = (struct printk_log *)(printk_log_buf + printk_log_next_idx);
- memcpy(log_text(msg), text, text_len);
+ memcpy(printk_log_text(msg), text, text_len);
msg->text_len = text_len;
- memcpy(log_dict(msg), dict, dict_len);
+ memcpy(printk_log_dict(msg), dict, dict_len);
msg->dict_len = dict_len;
msg->facility = facility;
msg->level = level & 7;
@@ -348,7 +348,7 @@ static void log_store(int facility, int level,
msg->ts_nsec = ts_nsec;
else
msg->ts_nsec = local_clock();
- memset(log_dict(msg) + dict_len, 0, pad_len);
+ memset(printk_log_dict(msg) + dict_len, 0, pad_len);
msg->len = sizeof(struct printk_log) + text_len + dict_len + pad_len;

/* insert message */
@@ -463,7 +463,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
goto out;
}

- msg = log_from_idx(user->idx);
+ msg = printk_log_from_idx(user->idx);
ts_usec = msg->ts_nsec;
do_div(ts_usec, 1000);

@@ -488,7 +488,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,

/* escape non-printable characters */
for (i = 0; i < msg->text_len; i++) {
- unsigned char c = log_text(msg)[i];
+ unsigned char c = printk_log_text(msg)[i];

if (c < ' ' || c >= 127 || c == '\\')
len += sprintf(user->buf + len, "\\x%02x", c);
@@ -501,7 +501,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
bool line = true;

for (i = 0; i < msg->dict_len; i++) {
- unsigned char c = log_dict(msg)[i];
+ unsigned char c = printk_log_dict(msg)[i];

if (line) {
user->buf[len++] = ' ';
@@ -524,7 +524,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
user->buf[len++] = '\n';
}

- user->idx = log_next(user->idx);
+ user->idx = printk_log_next(user->idx);
user->seq++;
raw_spin_unlock_irq(&logbuf_lock);

@@ -875,7 +875,7 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size)
{
- const char *text = log_text(msg);
+ const char *text = printk_log_text(msg);
size_t text_size = msg->text_len;
bool prefix = true;
bool newline = true;
@@ -959,12 +959,12 @@ static int syslog_print(char __user *buf, int size)
}

skip = syslog_partial;
- msg = log_from_idx(syslog_idx);
+ msg = printk_log_from_idx(syslog_idx);
n = msg_print_text(msg, syslog_prev, true, text,
LOG_LINE_MAX + PREFIX_MAX);
if (n - syslog_partial <= size) {
/* message fits into buffer, move forward */
- syslog_idx = log_next(syslog_idx);
+ syslog_idx = printk_log_next(syslog_idx);
syslog_seq++;
syslog_prev = msg->flags;
n -= syslog_partial;
@@ -1025,11 +1025,11 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx;
prev = 0;
while (seq < printk_log_next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);

len += msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags;
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
}

@@ -1038,11 +1038,11 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx;
prev = 0;
while (len > size && seq < printk_log_next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);

len -= msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags;
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
}

@@ -1052,7 +1052,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
len = 0;
prev = 0;
while (len >= 0 && seq < next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);
int textlen;

textlen = msg_print_text(msg, prev, true, text,
@@ -1061,7 +1061,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
len = textlen;
break;
}
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
prev = msg->flags;

@@ -1198,10 +1198,10 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)

error = 0;
while (seq < printk_log_next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);

error += msg_print_text(msg, prev, true, NULL, 0);
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
prev = msg->flags;
}
@@ -1400,8 +1400,8 @@ static void cont_flush(enum log_flags flags)
* console; wait for the console to pick up the rest of the
* line. LOG_NOCONS suppresses a duplicated output.
*/
- log_store(cont.facility, cont.level, flags | LOG_NOCONS,
- cont.ts_nsec, NULL, 0, cont.buf, cont.len);
+ printk_log_store(cont.facility, cont.level, flags | LOG_NOCONS,
+ cont.ts_nsec, NULL, 0, cont.buf, cont.len);
cont.flags = flags;
cont.flushed = true;
} else {
@@ -1409,8 +1409,8 @@ static void cont_flush(enum log_flags flags)
* If no fragment of this line ever reached the console,
* just submit it to the store and free the buffer.
*/
- log_store(cont.facility, cont.level, flags, 0,
- NULL, 0, cont.buf, cont.len);
+ printk_log_store(cont.facility, cont.level, flags, 0,
+ NULL, 0, cont.buf, cont.len);
cont.len = 0;
}
}
@@ -1522,8 +1522,8 @@ asmlinkage int vprintk_emit(int facility, int level,
recursion_bug = 0;
printed_len += strlen(recursion_msg);
/* emit KERN_CRIT message */
- log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0,
- NULL, 0, recursion_msg, printed_len);
+ printk_log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0,
+ NULL, 0, recursion_msg, printed_len);
}

/*
@@ -1574,8 +1574,8 @@ asmlinkage int vprintk_emit(int facility, int level,

/* buffer line if possible, otherwise store it right away */
if (!cont_add(facility, level, text, text_len))
- log_store(facility, level, lflags | LOG_CONT, 0,
- dict, dictlen, text, text_len);
+ printk_log_store(facility, level, lflags | LOG_CONT, 0,
+ dict, dictlen, text, text_len);
} else {
bool stored = false;

@@ -1592,8 +1592,8 @@ asmlinkage int vprintk_emit(int facility, int level,
}

if (!stored)
- log_store(facility, level, lflags, 0,
- dict, dictlen, text, text_len);
+ printk_log_store(facility, level, lflags, 0,
+ dict, dictlen, text, text_len);
}
printed_len += text_len;

@@ -1699,8 +1699,8 @@ static struct cont {
u8 level;
bool flushed:1;
} cont;
-static struct printk_log *log_from_idx(u32 idx) { return NULL; }
-static u32 log_next(u32 idx) { return 0; }
+static struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
+static u32 printk_log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size) { return 0; }
@@ -2045,13 +2045,13 @@ skip:
if (console_seq == printk_log_next_seq)
break;

- msg = log_from_idx(console_idx);
+ msg = printk_log_from_idx(console_idx);
if (msg->flags & LOG_NOCONS) {
/*
* Skip record we have buffered and already printed
* directly to the console when we received it.
*/
- console_idx = log_next(console_idx);
+ console_idx = printk_log_next(console_idx);
console_seq++;
/*
* We will get here again when we register a new
@@ -2066,7 +2066,7 @@ skip:
level = msg->level;
len = msg_print_text(msg, console_prev, false,
text, sizeof(text));
- console_idx = log_next(console_idx);
+ console_idx = printk_log_next(console_idx);
console_seq++;
console_prev = msg->flags;
raw_spin_unlock(&logbuf_lock);
@@ -2618,10 +2618,10 @@ bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
if (dumper->cur_seq >= printk_log_next_seq)
goto out;

- msg = log_from_idx(dumper->cur_idx);
+ msg = printk_log_from_idx(dumper->cur_idx);
l = msg_print_text(msg, 0, syslog, line, size);

- dumper->cur_idx = log_next(dumper->cur_idx);
+ dumper->cur_idx = printk_log_next(dumper->cur_idx);
dumper->cur_seq++;
ret = true;
out:
@@ -2713,10 +2713,10 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper->cur_idx;
prev = 0;
while (seq < dumper->next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);

l += msg_print_text(msg, prev, true, NULL, 0);
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
prev = msg->flags;
}
@@ -2726,10 +2726,10 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper->cur_idx;
prev = 0;
while (l > size && seq < dumper->next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);

l -= msg_print_text(msg, prev, true, NULL, 0);
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
prev = msg->flags;
}
@@ -2741,10 +2741,10 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
l = 0;
prev = 0;
while (seq < dumper->next_seq) {
- struct printk_log *msg = log_from_idx(idx);
+ struct printk_log *msg = printk_log_from_idx(idx);

l += msg_print_text(msg, prev, syslog, buf + l, size - l);
- idx = log_next(idx);
+ idx = printk_log_next(idx);
seq++;
prev = msg->flags;
}
--
1.7.10.4

2012-10-17 06:08:09

by Joe Perches

[permalink] [raw]
Subject: [PATCH 09/23] printk: Rename enum log_flags to printk_log_flags

Make this generic enum more specific to the printk subsystem.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 992c064..341f2d9 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -187,7 +187,7 @@ static int console_may_schedule;
* separated by ',', and find the message after the ';' character.
*/

-enum log_flags {
+enum printk_log_flags {
LOG_NOCONS = 1, /* already flushed, do not print to console */
LOG_NEWLINE = 2, /* text ended with a newline */
LOG_PREFIX = 4, /* text started with a prefix */
@@ -214,7 +214,7 @@ static DEFINE_RAW_SPINLOCK(logbuf_lock);
/* the next printk record to read by syslog(READ) or /proc/kmsg */
static u64 syslog_seq;
static u32 syslog_idx;
-static enum log_flags syslog_prev;
+static enum printk_log_flags syslog_prev;
static size_t syslog_partial;

/* index and sequence number of the first record stored in the buffer */
@@ -228,7 +228,7 @@ static u32 printk_log_next_idx;
/* the next printk record to write to the console */
static u64 console_seq;
static u32 console_idx;
-static enum log_flags console_prev;
+static enum printk_log_flags console_prev;

/* the next printk record to read after the last 'clear' command */
static u64 clear_seq;
@@ -297,7 +297,7 @@ static u32 printk_log_next(u32 idx)

/* insert record into the buffer, discard old ones, update heads */
static void printk_log_store(int facility, int level,
- enum log_flags flags, u64 ts_nsec,
+ enum printk_log_flags flags, u64 ts_nsec,
const char *dict, u16 dict_len,
const char *text, u16 text_len)
{
@@ -360,7 +360,7 @@ static void printk_log_store(int facility, int level,
struct devkmsg_user {
u64 seq;
u32 idx;
- enum log_flags prev;
+ enum printk_log_flags prev;
struct mutex lock;
char buf[8192];
};
@@ -872,7 +872,8 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
return len;
}

-static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
+static size_t msg_print_text(const struct printk_log *msg,
+ enum printk_log_flags prev,
bool syslog, char *buf, size_t size)
{
const char *text = printk_log_text(msg);
@@ -1009,7 +1010,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
u64 next_seq;
u64 seq;
u32 idx;
- enum log_flags prev;
+ enum printk_log_flags prev;

if (clear_seq < printk_log_first_seq) {
/* messages are gone, move to first available one */
@@ -1194,7 +1195,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
} else {
u64 seq = syslog_seq;
u32 idx = syslog_idx;
- enum log_flags prev = syslog_prev;
+ enum printk_log_flags prev = syslog_prev;

error = 0;
while (seq < printk_log_next_seq) {
@@ -1383,11 +1384,11 @@ static struct cont {
u64 ts_nsec; /* time of first print */
u8 level; /* log level of first message */
u8 facility; /* log level of first message */
- enum log_flags flags; /* prefix, newline flags */
+ enum printk_log_flags flags; /* prefix, newline flags */
bool flushed:1; /* buffer sealed and committed */
} cont;

-static void cont_flush(enum log_flags flags)
+static void cont_flush(enum printk_log_flags flags)
{
if (cont.flushed)
return;
@@ -1481,7 +1482,7 @@ asmlinkage int vprintk_emit(int facility, int level,
static char textbuf[LOG_LINE_MAX];
char *text = textbuf;
size_t text_len;
- enum log_flags lflags = 0;
+ enum printk_log_flags lflags = 0;
unsigned long flags;
int this_cpu;
int printed_len = 0;
@@ -1688,11 +1689,11 @@ static u64 syslog_seq;
static u32 syslog_idx;
static u64 console_seq;
static u32 console_idx;
-static enum log_flags syslog_prev;
+static enum printk_log_flags syslog_prev;
static u64 printk_log_first_seq;
static u32 printk_log_first_idx;
static u64 printk_log_next_seq;
-static enum log_flags console_prev;
+static enum printk_log_flags console_prev;
static struct cont {
size_t len;
size_t cons;
@@ -1702,7 +1703,8 @@ static struct cont {
static struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
static u32 printk_log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
-static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
+static size_t msg_print_text(const struct printk_log *msg,
+ enum printk_log_flags prev,
bool syslog, char *buf, size_t size) { return 0; }
static size_t cont_print_text(char *text, size_t size) { return 0; }

@@ -2688,7 +2690,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
u32 idx;
u64 next_seq;
u32 next_idx;
- enum log_flags prev;
+ enum printk_log_flags prev;
size_t l = 0;
bool ret = false;

--
1.7.10.4

2012-10-17 06:08:42

by Joe Perches

[permalink] [raw]
Subject: [PATCH 10/23] printk: Rename log_wait to printk_log_wait

Make this generic variable more specific to the printk
subsystem to allow this variable to be used without
a specific extern.

Also update fs/proc/kmsg.c as it uses log_wait.

Signed-off-by: Joe Perches <[email protected]>
---
fs/proc/kmsg.c | 4 ++--
kernel/printk/printk.c | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index bd4b5a7..16f2c85 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -17,7 +17,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>

-extern wait_queue_head_t log_wait;
+extern wait_queue_head_t printk_log_wait;

static int kmsg_open(struct inode * inode, struct file * file)
{
@@ -41,7 +41,7 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,

static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
- poll_wait(file, &log_wait, wait);
+ poll_wait(file, &printk_log_wait, wait);
if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
return POLLIN | POLLRDNORM;
return 0;
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 341f2d9..c87472b 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -63,7 +63,7 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */

-DECLARE_WAIT_QUEUE_HEAD(log_wait);
+DECLARE_WAIT_QUEUE_HEAD(printk_log_wait);

int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */
@@ -447,7 +447,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
}

raw_spin_unlock_irq(&logbuf_lock);
- ret = wait_event_interruptible(log_wait,
+ ret = wait_event_interruptible(printk_log_wait,
user->seq != printk_log_next_seq);
if (ret)
goto out;
@@ -589,7 +589,7 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait)
if (!user)
return POLLERR|POLLNVAL;

- poll_wait(file, &log_wait, wait);
+ poll_wait(file, &printk_log_wait, wait);

raw_spin_lock_irq(&logbuf_lock);
if (user->seq < printk_log_next_seq) {
@@ -1122,7 +1122,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
error = -EFAULT;
goto out;
}
- error = wait_event_interruptible(log_wait,
+ error = wait_event_interruptible(printk_log_wait,
syslog_seq != printk_log_next_seq);
if (error)
goto out;
@@ -1948,7 +1948,7 @@ void printk_tick(void)
printk(KERN_WARNING "[sched_delayed] %s", buf);
}
if (pending & PRINTK_PENDING_WAKEUP)
- wake_up_interruptible(&log_wait);
+ wake_up_interruptible(&printk_log_wait);
}
}

@@ -1961,7 +1961,7 @@ int printk_needs_cpu(int cpu)

void wake_up_klogd(void)
{
- if (waitqueue_active(&log_wait))
+ if (waitqueue_active(&printk_log_wait))
this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
}

--
1.7.10.4

2012-10-17 06:08:46

by Joe Perches

[permalink] [raw]
Subject: [PATCH 13/23] printk: Remove static from printk_ variables

Allow a separation of functions and variables into
multiple files.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 46 +++++++++++++++++++++++-----------------------
1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 3785ac4..0134b2e 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -208,7 +208,7 @@ struct printk_log {
* The printk_logbuf_lock protects kmsg buffer, indices, counters. It is also
* used in interesting ways to provide interlocking in console_unlock();
*/
-static DEFINE_RAW_SPINLOCK(printk_logbuf_lock);
+DEFINE_RAW_SPINLOCK(printk_logbuf_lock);

#ifdef CONFIG_PRINTK
/* the next printk record to read by syslog(READ) or /proc/kmsg */
@@ -218,12 +218,12 @@ static enum printk_log_flags syslog_prev;
static size_t syslog_partial;

/* index and sequence number of the first record stored in the buffer */
-static u64 printk_log_first_seq;
-static u32 printk_log_first_idx;
+u64 printk_log_first_seq;
+u32 printk_log_first_idx;

/* index and sequence number of the next record to store in the buffer */
-static u64 printk_log_next_seq;
-static u32 printk_log_next_idx;
+u64 printk_log_next_seq;
+u32 printk_log_next_idx;

/* the next printk record to write to the console */
static u64 console_seq;
@@ -231,8 +231,8 @@ static u32 console_idx;
static enum printk_log_flags console_prev;

/* the next printk record to read after the last 'clear' command */
-static u64 printk_log_clear_seq;
-static u32 printk_log_clear_idx;
+u64 printk_log_clear_seq;
+u32 printk_log_clear_idx;

#define PREFIX_MAX 32
#define LOG_LINE_MAX 1024 - PREFIX_MAX
@@ -244,27 +244,27 @@ static u32 printk_log_clear_idx;
#define LOG_ALIGN __alignof__(struct printk_log)
#endif
#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
-static char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(LOG_ALIGN);
-static char *printk_log_buf = __printk_log_buf;
-static u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;
+char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(LOG_ALIGN);
+char *printk_log_buf = __printk_log_buf;
+u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;

/* cpu currently holding printk_logbuf_lock */
static volatile unsigned int logbuf_cpu = UINT_MAX;

/* human readable text of the record */
-static char *printk_log_text(const struct printk_log *msg)
+char *printk_log_text(const struct printk_log *msg)
{
return (char *)msg + sizeof(struct printk_log);
}

/* optional key/value pair dictionary attached to the record */
-static char *printk_log_dict(const struct printk_log *msg)
+char *printk_log_dict(const struct printk_log *msg)
{
return (char *)msg + sizeof(struct printk_log) + msg->text_len;
}

/* get record by index; idx must point to valid msg */
-static struct printk_log *printk_log_from_idx(u32 idx)
+struct printk_log *printk_log_from_idx(u32 idx)
{
struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);

@@ -278,7 +278,7 @@ static struct printk_log *printk_log_from_idx(u32 idx)
}

/* get next record; idx must point to valid msg */
-static u32 printk_log_next(u32 idx)
+u32 printk_log_next(u32 idx)
{
struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);

@@ -296,10 +296,10 @@ static u32 printk_log_next(u32 idx)
}

/* insert record into the buffer, discard old ones, update heads */
-static void printk_log_store(int facility, int level,
- enum printk_log_flags flags, u64 ts_nsec,
- const char *dict, u16 dict_len,
- const char *text, u16 text_len)
+void printk_log_store(int facility, int level,
+ enum printk_log_flags flags, u64 ts_nsec,
+ const char *dict, u16 dict_len,
+ const char *text, u16 text_len)
{
struct printk_log *msg;
u32 size, pad_len;
@@ -1690,9 +1690,9 @@ static u32 syslog_idx;
static u64 console_seq;
static u32 console_idx;
static enum printk_log_flags syslog_prev;
-static u64 printk_log_first_seq;
-static u32 printk_log_first_idx;
-static u64 printk_log_next_seq;
+u64 printk_log_first_seq;
+u32 printk_log_first_idx;
+u64 printk_log_next_seq;
static enum printk_log_flags console_prev;
static struct cont {
size_t len;
@@ -1700,8 +1700,8 @@ static struct cont {
u8 level;
bool flushed:1;
} cont;
-static struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
-static u32 printk_log_next(u32 idx) { return 0; }
+struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
+u32 printk_log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
static size_t msg_print_text(const struct printk_log *msg,
enum printk_log_flags prev,
--
1.7.10.4

2012-10-17 06:08:54

by Joe Perches

[permalink] [raw]
Subject: [PATCH 14/23] printk: Rename LOG_ALIGN to PRINTK_LOG_ALIGN

Make the #define more specific to the printk subsystem.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0134b2e..bc0b4ed 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -239,12 +239,12 @@ u32 printk_log_clear_idx;

/* record buffer */
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-#define LOG_ALIGN 4
+#define PRINTK_LOG_ALIGN 4
#else
-#define LOG_ALIGN __alignof__(struct printk_log)
+#define PRINTK_LOG_ALIGN __alignof__(struct printk_log)
#endif
#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
-char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(LOG_ALIGN);
+char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(PRINTK_LOG_ALIGN);
char *printk_log_buf = __printk_log_buf;
u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;

@@ -306,7 +306,7 @@ void printk_log_store(int facility, int level,

/* number of '\0' padding bytes to next message */
size = sizeof(struct printk_log) + text_len + dict_len;
- pad_len = (-size) & (LOG_ALIGN - 1);
+ pad_len = (-size) & (PRINTK_LOG_ALIGN - 1);
size += pad_len;

while (printk_log_first_seq < printk_log_next_seq) {
--
1.7.10.4

2012-10-17 06:09:05

by Joe Perches

[permalink] [raw]
Subject: [PATCH 15/23] printk: Add and use printk_log.h

Create a header file for printk_log functions and variables.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 91 +----------------------------------
kernel/printk/printk_log.h | 115 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+), 90 deletions(-)
create mode 100644 kernel/printk/printk_log.h

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index bc0b4ed..3b18ade 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -48,6 +48,7 @@

#include "console_cmdline.h"
#include "braille.h"
+#include "printk_log.h"

/*
* Architectures can override it:
@@ -121,90 +122,6 @@ EXPORT_SYMBOL(console_set_on_cmdline);
static int console_may_schedule;

/*
- * The printk log buffer consists of a chain of concatenated variable
- * length records. Every record starts with a record header, containing
- * the overall length of the record.
- *
- * The heads to the first and last entry in the buffer, as well as the
- * sequence numbers of these both entries are maintained when messages
- * are stored..
- *
- * If the heads indicate available messages, the length in the header
- * tells the start next message. A length == 0 for the next message
- * indicates a wrap-around to the beginning of the buffer.
- *
- * Every record carries the monotonic timestamp in microseconds, as well as
- * the standard userspace syslog level and syslog facility. The usual
- * kernel messages use LOG_KERN; userspace-injected messages always carry
- * a matching syslog facility, by default LOG_USER. The origin of every
- * message can be reliably determined that way.
- *
- * The human readable log message directly follows the message header. The
- * length of the message text is stored in the header, the stored message
- * is not terminated.
- *
- * Optionally, a message can carry a dictionary of properties (key/value pairs),
- * to provide userspace with a machine-readable message context.
- *
- * Examples for well-defined, commonly used property names are:
- * DEVICE=b12:8 device identifier
- * b12:8 block dev_t
- * c127:3 char dev_t
- * n8 netdev ifindex
- * +sound:card0 subsystem:devname
- * SUBSYSTEM=pci driver-core subsystem name
- *
- * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value
- * follows directly after a '=' character. Every property is terminated by
- * a '\0' character. The last property is not terminated.
- *
- * Example of a message structure:
- * 0000 ff 8f 00 00 00 00 00 00 monotonic time in nsec
- * 0008 34 00 record is 52 bytes long
- * 000a 0b 00 text is 11 bytes long
- * 000c 1f 00 dictionary is 23 bytes long
- * 000e 03 00 LOG_KERN (facility) LOG_ERR (level)
- * 0010 69 74 27 73 20 61 20 6c "it's a l"
- * 69 6e 65 "ine"
- * 001b 44 45 56 49 43 "DEVIC"
- * 45 3d 62 38 3a 32 00 44 "E=b8:2\0D"
- * 52 49 56 45 52 3d 62 75 "RIVER=bu"
- * 67 "g"
- * 0032 00 00 00 padding to next message header
- *
- * The 'struct printk_log' buffer header must never be directly exported to
- * userspace, it is a kernel-private implementation detail that might
- * need to be changed in the future, when the requirements change.
- *
- * /dev/kmsg exports the structured data in the following line format:
- * "level,sequnum,timestamp;<message text>\n"
- *
- * The optional key/value pairs are attached as continuation lines starting
- * with a space character and terminated by a newline. All possible
- * non-prinatable characters are escaped in the "\xff" notation.
- *
- * Users of the export format should ignore possible additional values
- * separated by ',', and find the message after the ';' character.
- */
-
-enum printk_log_flags {
- LOG_NOCONS = 1, /* already flushed, do not print to console */
- LOG_NEWLINE = 2, /* text ended with a newline */
- LOG_PREFIX = 4, /* text started with a prefix */
- LOG_CONT = 8, /* text is a fragment of a continuation line */
-};
-
-struct printk_log {
- u64 ts_nsec; /* timestamp in nanoseconds */
- u16 len; /* length of entire record */
- u16 text_len; /* length of text buffer */
- u16 dict_len; /* length of dictionary buffer */
- u8 facility; /* syslog facility */
- u8 flags:5; /* internal record flags */
- u8 level:3; /* syslog level */
-};
-
-/*
* The printk_logbuf_lock protects kmsg buffer, indices, counters. It is also
* used in interesting ways to provide interlocking in console_unlock();
*/
@@ -238,12 +155,6 @@ u32 printk_log_clear_idx;
#define LOG_LINE_MAX 1024 - PREFIX_MAX

/* record buffer */
-#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-#define PRINTK_LOG_ALIGN 4
-#else
-#define PRINTK_LOG_ALIGN __alignof__(struct printk_log)
-#endif
-#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(PRINTK_LOG_ALIGN);
char *printk_log_buf = __printk_log_buf;
u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;
diff --git a/kernel/printk/printk_log.h b/kernel/printk/printk_log.h
new file mode 100644
index 0000000..0327f8d
--- /dev/null
+++ b/kernel/printk/printk_log.h
@@ -0,0 +1,115 @@
+#ifndef _PRINTK_LOG_H
+#define _PRINTK_LOG_H
+
+/*
+ * The printk log buffer consists of a chain of concatenated variable
+ * length records. Every record starts with a record header, containing
+ * the overall length of the record.
+ *
+ * The heads to the first and last entry in the buffer, as well as the
+ * sequence numbers of these both entries are maintained when messages
+ * are stored..
+ *
+ * If the heads indicate available messages, the length in the header
+ * tells the start next message. A length == 0 for the next message
+ * indicates a wrap-around to the beginning of the buffer.
+ *
+ * Every record carries the monotonic timestamp in microseconds, as well as
+ * the standard userspace syslog level and syslog facility. The usual
+ * kernel messages use LOG_KERN; userspace-injected messages always carry
+ * a matching syslog facility, by default LOG_USER. The origin of every
+ * message can be reliably determined that way.
+ *
+ * The human readable log message directly follows the message header. The
+ * length of the message text is stored in the header, the stored message
+ * is not terminated.
+ *
+ * Optionally, a message can carry a dictionary of properties (key/value pairs),
+ * to provide userspace with a machine-readable message context.
+ *
+ * Examples for well-defined, commonly used property names are:
+ * DEVICE=b12:8 device identifier
+ * b12:8 block dev_t
+ * c127:3 char dev_t
+ * n8 netdev ifindex
+ * +sound:card0 subsystem:devname
+ * SUBSYSTEM=pci driver-core subsystem name
+ *
+ * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value
+ * follows directly after a '=' character. Every property is terminated by
+ * a '\0' character. The last property is not terminated.
+ *
+ * Example of a message structure:
+ * 0000 ff 8f 00 00 00 00 00 00 monotonic time in nsec
+ * 0008 34 00 record is 52 bytes long
+ * 000a 0b 00 text is 11 bytes long
+ * 000c 1f 00 dictionary is 23 bytes long
+ * 000e 03 00 LOG_KERN (facility) LOG_ERR (level)
+ * 0010 69 74 27 73 20 61 20 6c "it's a l"
+ * 69 6e 65 "ine"
+ * 001b 44 45 56 49 43 "DEVIC"
+ * 45 3d 62 38 3a 32 00 44 "E=b8:2\0D"
+ * 52 49 56 45 52 3d 62 75 "RIVER=bu"
+ * 67 "g"
+ * 0032 00 00 00 padding to next message header
+ *
+ * The 'struct printk_log' buffer header must never be directly exported to
+ * userspace, it is a kernel-private implementation detail that might
+ * need to be changed in the future, when the requirements change.
+ *
+ * /dev/kmsg exports the structured data in the following line format:
+ * "level,sequnum,timestamp;<message text>\n"
+ *
+ * The optional key/value pairs are attached as continuation lines starting
+ * with a space character and terminated by a newline. All possible
+ * non-prinatable characters are escaped in the "\xff" notation.
+ *
+ * Users of the export format should ignore possible additional values
+ * separated by ',', and find the message after the ';' character.
+ */
+
+enum printk_log_flags {
+ LOG_NOCONS = 1, /* already flushed, do not print to console */
+ LOG_NEWLINE = 2, /* text ended with a newline */
+ LOG_PREFIX = 4, /* text started with a prefix */
+ LOG_CONT = 8, /* text is a fragment of a continuation line */
+};
+
+struct printk_log {
+ u64 ts_nsec; /* timestamp in nanoseconds */
+ u16 len; /* length of entire record */
+ u16 text_len; /* length of text buffer */
+ u16 dict_len; /* length of dictionary buffer */
+ u8 facility; /* syslog facility */
+ u8 flags:5; /* internal record flags */
+ u8 level:3; /* syslog level */
+};
+
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+#define PRINTK_LOG_ALIGN 4
+#else
+#define PRINTK_LOG_ALIGN __alignof__(struct printk_log)
+#endif
+#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+
+extern raw_spinlock_t printk_logbuf_lock;
+extern u64 printk_log_first_seq;
+extern u32 printk_log_first_idx;
+extern u64 printk_log_next_seq;
+extern u32 printk_log_next_idx;
+extern u64 printk_log_clear_seq;
+extern u32 printk_log_clear_idx;
+extern char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(PRINTK_LOG_ALIGN);
+extern char *printk_log_buf;
+extern u32 printk_log_buf_len;
+
+char *printk_log_text(const struct printk_log *msg);
+char *printk_log_dict(const struct printk_log *msg);
+struct printk_log *printk_log_from_idx(u32 idx);
+u32 printk_log_next(u32 idx);
+void printk_log_store(int facility, int level,
+ enum printk_log_flags flags, u64 ts_nsec,
+ const char *dict, u16 dict_len,
+ const char *text, u16 text_len);
+
+#endif
--
1.7.10.4

2012-10-17 06:09:17

by Joe Perches

[permalink] [raw]
Subject: [PATCH 16/23] printk: Add printk_log.c

Move print_log variables and functions into a separate file.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/Makefile | 1 +
kernel/printk/printk.c | 128 -------------------------------------
kernel/printk/printk_log.c | 149 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 150 insertions(+), 128 deletions(-)
create mode 100644 kernel/printk/printk_log.c

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index 85405bd..a692b68 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1,2 +1,3 @@
obj-y = printk.o
+obj-y += printk_log.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 3b18ade..3b5c10e 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -121,12 +121,6 @@ EXPORT_SYMBOL(console_set_on_cmdline);
/* Flag: console code may call schedule() */
static int console_may_schedule;

-/*
- * The printk_logbuf_lock protects kmsg buffer, indices, counters. It is also
- * used in interesting ways to provide interlocking in console_unlock();
- */
-DEFINE_RAW_SPINLOCK(printk_logbuf_lock);
-
#ifdef CONFIG_PRINTK
/* the next printk record to read by syslog(READ) or /proc/kmsg */
static u64 syslog_seq;
@@ -134,139 +128,17 @@ static u32 syslog_idx;
static enum printk_log_flags syslog_prev;
static size_t syslog_partial;

-/* index and sequence number of the first record stored in the buffer */
-u64 printk_log_first_seq;
-u32 printk_log_first_idx;
-
-/* index and sequence number of the next record to store in the buffer */
-u64 printk_log_next_seq;
-u32 printk_log_next_idx;
-
/* the next printk record to write to the console */
static u64 console_seq;
static u32 console_idx;
static enum printk_log_flags console_prev;

-/* the next printk record to read after the last 'clear' command */
-u64 printk_log_clear_seq;
-u32 printk_log_clear_idx;
-
#define PREFIX_MAX 32
#define LOG_LINE_MAX 1024 - PREFIX_MAX

-/* record buffer */
-char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(PRINTK_LOG_ALIGN);
-char *printk_log_buf = __printk_log_buf;
-u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;
-
/* cpu currently holding printk_logbuf_lock */
static volatile unsigned int logbuf_cpu = UINT_MAX;

-/* human readable text of the record */
-char *printk_log_text(const struct printk_log *msg)
-{
- return (char *)msg + sizeof(struct printk_log);
-}
-
-/* optional key/value pair dictionary attached to the record */
-char *printk_log_dict(const struct printk_log *msg)
-{
- return (char *)msg + sizeof(struct printk_log) + msg->text_len;
-}
-
-/* get record by index; idx must point to valid msg */
-struct printk_log *printk_log_from_idx(u32 idx)
-{
- struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);
-
- /*
- * A length == 0 record is the end of buffer marker. Wrap around and
- * read the message at the start of the buffer.
- */
- if (!msg->len)
- return (struct printk_log *)printk_log_buf;
- return msg;
-}
-
-/* get next record; idx must point to valid msg */
-u32 printk_log_next(u32 idx)
-{
- struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);
-
- /* length == 0 indicates the end of the buffer; wrap */
- /*
- * A length == 0 record is the end of buffer marker. Wrap around and
- * read the message at the start of the buffer as *this* one, and
- * return the one after that.
- */
- if (!msg->len) {
- msg = (struct printk_log *)printk_log_buf;
- return msg->len;
- }
- return idx + msg->len;
-}
-
-/* insert record into the buffer, discard old ones, update heads */
-void printk_log_store(int facility, int level,
- enum printk_log_flags flags, u64 ts_nsec,
- const char *dict, u16 dict_len,
- const char *text, u16 text_len)
-{
- struct printk_log *msg;
- u32 size, pad_len;
-
- /* number of '\0' padding bytes to next message */
- size = sizeof(struct printk_log) + text_len + dict_len;
- pad_len = (-size) & (PRINTK_LOG_ALIGN - 1);
- size += pad_len;
-
- while (printk_log_first_seq < printk_log_next_seq) {
- u32 free;
-
- if (printk_log_next_idx > printk_log_first_idx)
- free = max(printk_log_buf_len - printk_log_next_idx, printk_log_first_idx);
- else
- free = printk_log_first_idx - printk_log_next_idx;
-
- if (free > size + sizeof(struct printk_log))
- break;
-
- /* drop old messages until we have enough contiuous space */
- printk_log_first_idx = printk_log_next(printk_log_first_idx);
- printk_log_first_seq++;
- }
-
- if (printk_log_next_idx + size + sizeof(struct printk_log) >= printk_log_buf_len) {
- /*
- * This message + an additional empty header does not fit
- * at the end of the buffer. Add an empty header with len == 0
- * to signify a wrap around.
- */
- memset(printk_log_buf + printk_log_next_idx, 0, sizeof(struct printk_log));
- printk_log_next_idx = 0;
- }
-
- /* fill message */
- msg = (struct printk_log *)(printk_log_buf + printk_log_next_idx);
- memcpy(printk_log_text(msg), text, text_len);
- msg->text_len = text_len;
- memcpy(printk_log_dict(msg), dict, dict_len);
- msg->dict_len = dict_len;
- msg->facility = facility;
- msg->level = level & 7;
- msg->flags = flags & 0x1f;
- if (ts_nsec > 0)
- msg->ts_nsec = ts_nsec;
- else
- msg->ts_nsec = local_clock();
- memset(printk_log_dict(msg) + dict_len, 0, pad_len);
- msg->len = sizeof(struct printk_log) + text_len + dict_len + pad_len;
-
- /* insert message */
- printk_log_next_idx += msg->len;
- printk_log_next_seq++;
-}
-
/* /dev/kmsg - userspace message inject/listen interface */
struct devkmsg_user {
u64 seq;
diff --git a/kernel/printk/printk_log.c b/kernel/printk/printk_log.c
new file mode 100644
index 0000000..b5c2b8f
--- /dev/null
+++ b/kernel/printk/printk_log.c
@@ -0,0 +1,149 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/kexec.h>
+
+#include "printk_log.h"
+
+/*
+ * The printk_logbuf_lock protects kmsg buffer, indices, counters. It is also
+ * used in interesting ways to provide interlocking in console_unlock();
+ */
+DEFINE_RAW_SPINLOCK(printk_logbuf_lock);
+
+#ifdef CONFIG_PRINTK
+
+/* index and sequence number of the first record stored in the buffer */
+u64 printk_log_first_seq;
+u32 printk_log_first_idx;
+
+/* index and sequence number of the next record to store in the buffer */
+u64 printk_log_next_seq;
+u32 printk_log_next_idx;
+
+/* the next printk record to read after the last 'clear' command */
+u64 printk_log_clear_seq;
+u32 printk_log_clear_idx;
+
+/* record buffer */
+char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(PRINTK_LOG_ALIGN);
+char *printk_log_buf = __printk_log_buf;
+u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;
+
+/* human readable text of the record */
+char *printk_log_text(const struct printk_log *msg)
+{
+ return (char *)msg + sizeof(struct printk_log);
+}
+
+/* optional key/value pair dictionary attached to the record */
+char *printk_log_dict(const struct printk_log *msg)
+{
+ return (char *)msg + sizeof(struct printk_log) + msg->text_len;
+}
+
+/* get record by index; idx must point to valid msg */
+struct printk_log *printk_log_from_idx(u32 idx)
+{
+ struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);
+
+ /*
+ * A length == 0 record is the end of buffer marker. Wrap around and
+ * read the message at the start of the buffer.
+ */
+ if (!msg->len)
+ return (struct printk_log *)printk_log_buf;
+ return msg;
+}
+
+/* get next record; idx must point to valid msg */
+u32 printk_log_next(u32 idx)
+{
+ struct printk_log *msg = (struct printk_log *)(printk_log_buf + idx);
+
+ /* length == 0 indicates the end of the buffer; wrap */
+ /*
+ * A length == 0 record is the end of buffer marker. Wrap around and
+ * read the message at the start of the buffer as *this* one, and
+ * return the one after that.
+ */
+ if (!msg->len) {
+ msg = (struct printk_log *)printk_log_buf;
+ return msg->len;
+ }
+ return idx + msg->len;
+}
+
+/* insert record into the buffer, discard old ones, update heads */
+void printk_log_store(int facility, int level,
+ enum printk_log_flags flags, u64 ts_nsec,
+ const char *dict, u16 dict_len,
+ const char *text, u16 text_len)
+{
+ struct printk_log *msg;
+ u32 size, pad_len;
+
+ /* number of '\0' padding bytes to next message */
+ size = sizeof(struct printk_log) + text_len + dict_len;
+ pad_len = (-size) & (PRINTK_LOG_ALIGN - 1);
+ size += pad_len;
+
+ while (printk_log_first_seq < printk_log_next_seq) {
+ u32 free;
+
+ if (printk_log_next_idx > printk_log_first_idx)
+ free = max(printk_log_buf_len - printk_log_next_idx, printk_log_first_idx);
+ else
+ free = printk_log_first_idx - printk_log_next_idx;
+
+ if (free > size + sizeof(struct printk_log))
+ break;
+
+ /* drop old messages until we have enough contiuous space */
+ printk_log_first_idx = printk_log_next(printk_log_first_idx);
+ printk_log_first_seq++;
+ }
+
+ if (printk_log_next_idx + size + sizeof(struct printk_log) >= printk_log_buf_len) {
+ /*
+ * This message + an additional empty header does not fit
+ * at the end of the buffer. Add an empty header with len == 0
+ * to signify a wrap around.
+ */
+ memset(printk_log_buf + printk_log_next_idx, 0, sizeof(struct printk_log));
+ printk_log_next_idx = 0;
+ }
+
+ /* fill message */
+ msg = (struct printk_log *)(printk_log_buf + printk_log_next_idx);
+ memcpy(printk_log_text(msg), text, text_len);
+ msg->text_len = text_len;
+ memcpy(printk_log_dict(msg), dict, dict_len);
+ msg->dict_len = dict_len;
+ msg->facility = facility;
+ msg->level = level & 7;
+ msg->flags = flags & 0x1f;
+ if (ts_nsec > 0)
+ msg->ts_nsec = ts_nsec;
+ else
+ msg->ts_nsec = local_clock();
+ memset(printk_log_dict(msg) + dict_len, 0, pad_len);
+ msg->len = sizeof(struct printk_log) + text_len + dict_len + pad_len;
+
+ /* insert message */
+ printk_log_next_idx += msg->len;
+ printk_log_next_seq++;
+}
+
+#else /* CONFIG_PRINTK */
+
+#define LOG_LINE_MAX 0
+#define PREFIX_MAX 0
+#define LOG_LINE_MAX 0
+u64 printk_log_first_seq;
+u32 printk_log_first_idx;
+u64 printk_log_next_seq;
+struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
+u32 printk_log_next(u32 idx) { return 0; }
+
+#endif /* CONFIG_PRINTK */
--
1.7.10.4

2012-10-17 06:09:25

by Joe Perches

[permalink] [raw]
Subject: [PATCH 17/23] printk: Make wait_queue_head_t printk_log_wait extern

Move the variable to the .h file too.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk_log.h | 1 +
1 file changed, 1 insertion(+)

diff --git a/kernel/printk/printk_log.h b/kernel/printk/printk_log.h
index 0327f8d..e846f1d 100644
--- a/kernel/printk/printk_log.h
+++ b/kernel/printk/printk_log.h
@@ -93,6 +93,7 @@ struct printk_log {
#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)

extern raw_spinlock_t printk_logbuf_lock;
+extern wait_queue_head_t printk_log_wait;
extern u64 printk_log_first_seq;
extern u32 printk_log_first_idx;
extern u64 printk_log_next_seq;
--
1.7.10.4

2012-10-17 06:09:33

by Joe Perches

[permalink] [raw]
Subject: [PATCH 18/23] printk: Rename and move 2 #defines to printk_log.h

Rename the LOG_LINE_MAX and PREFIX_MAX #defines with PRINTK_ prefixes.
Move the defines to printk_log.h
Remove duplicate define too.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 24 ++++++++++--------------
kernel/printk/printk_log.h | 3 +++
2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 3b5c10e..43550a5 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -133,9 +133,6 @@ static u64 console_seq;
static u32 console_idx;
static enum printk_log_flags console_prev;

-#define PREFIX_MAX 32
-#define LOG_LINE_MAX 1024 - PREFIX_MAX
-
/* cpu currently holding printk_logbuf_lock */
static volatile unsigned int logbuf_cpu = UINT_MAX;

@@ -158,7 +155,7 @@ static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv,
size_t len = iov_length(iv, count);
ssize_t ret = len;

- if (len > LOG_LINE_MAX)
+ if (len > PRINTK_LOG_LINE_MAX)
return -EINVAL;
buf = kmalloc(len+1, GFP_KERNEL);
if (buf == NULL)
@@ -721,7 +718,7 @@ static int syslog_print(char __user *buf, int size)
struct printk_log *msg;
int len = 0;

- text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
+ text = kmalloc(PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX, GFP_KERNEL);
if (!text)
return -ENOMEM;

@@ -745,7 +742,7 @@ static int syslog_print(char __user *buf, int size)
skip = syslog_partial;
msg = printk_log_from_idx(syslog_idx);
n = msg_print_text(msg, syslog_prev, true, text,
- LOG_LINE_MAX + PREFIX_MAX);
+ PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
if (n - syslog_partial <= size) {
/* message fits into buffer, move forward */
syslog_idx = printk_log_next(syslog_idx);
@@ -784,7 +781,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
char *text;
int len = 0;

- text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
+ text = kmalloc(PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX, GFP_KERNEL);
if (!text)
return -ENOMEM;

@@ -840,7 +837,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
int textlen;

textlen = msg_print_text(msg, prev, true, text,
- LOG_LINE_MAX + PREFIX_MAX);
+ PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
if (textlen < 0) {
len = textlen;
break;
@@ -1160,7 +1157,7 @@ static inline void printk_delay(void)
* reached the console in case of a kernel crash.
*/
static struct cont {
- char buf[LOG_LINE_MAX];
+ char buf[PRINTK_LOG_LINE_MAX];
size_t len; /* length == 0 means unused buffer */
size_t cons; /* bytes written to console */
struct task_struct *owner; /* task of first print*/
@@ -1262,7 +1259,7 @@ asmlinkage int vprintk_emit(int facility, int level,
const char *fmt, va_list args)
{
static int recursion_bug;
- static char textbuf[LOG_LINE_MAX];
+ static char textbuf[PRINTK_LOG_LINE_MAX];
char *text = textbuf;
size_t text_len;
enum printk_log_flags lflags = 0;
@@ -1465,9 +1462,8 @@ EXPORT_SYMBOL(printk);

#else /* CONFIG_PRINTK */

-#define LOG_LINE_MAX 0
-#define PREFIX_MAX 0
-#define LOG_LINE_MAX 0
+#define PRINTK_LOG_LINE_MAX 0
+#define PRINTK_PREFIX_MAX 0
static u64 syslog_seq;
static u32 syslog_idx;
static u64 console_seq;
@@ -1793,7 +1789,7 @@ out:
*/
void console_unlock(void)
{
- static char text[LOG_LINE_MAX + PREFIX_MAX];
+ static char text[PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX];
static u64 seen_seq;
unsigned long flags;
bool wake_klogd = false;
diff --git a/kernel/printk/printk_log.h b/kernel/printk/printk_log.h
index e846f1d..a7125d5 100644
--- a/kernel/printk/printk_log.h
+++ b/kernel/printk/printk_log.h
@@ -92,6 +92,9 @@ struct printk_log {
#endif
#define __PRINTK_LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)

+#define PRINTK_PREFIX_MAX 32
+#define PRINTK_LOG_LINE_MAX (1024 - PRINTK_PREFIX_MAX)
+
extern raw_spinlock_t printk_logbuf_lock;
extern wait_queue_head_t printk_log_wait;
extern u64 printk_log_first_seq;
--
1.7.10.4

2012-10-17 06:09:44

by Joe Perches

[permalink] [raw]
Subject: [PATCH 19/23] printk: Move devkmsg bits to separate file

Move the devkmsg_ functions and kmsg_fops declaration
to devkmsg.c.

Add devkmsg.o to Makefile.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/Makefile | 1 +
kernel/printk/devkmsg.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++
kernel/printk/printk.c | 296 ---------------------------------------------
3 files changed, 310 insertions(+), 296 deletions(-)
create mode 100644 kernel/printk/devkmsg.c

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index a692b68..bda335f 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1,3 +1,4 @@
obj-y = printk.o
obj-y += printk_log.o
+obj-y += devkmsg.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/devkmsg.c b/kernel/printk/devkmsg.c
new file mode 100644
index 0000000..af83290
--- /dev/null
+++ b/kernel/printk/devkmsg.c
@@ -0,0 +1,309 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/slab.h>
+#include <linux/security.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#include <linux/syslog.h>
+#include <linux/wait.h>
+#include <linux/uio.h>
+#include <linux/sched.h>
+
+#include "printk_log.h"
+
+/* /dev/kmsg - userspace message inject/listen interface */
+struct devkmsg_user {
+ u64 seq;
+ u32 idx;
+ enum printk_log_flags prev;
+ struct mutex lock;
+ char buf[8192];
+};
+
+static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv,
+ unsigned long count, loff_t pos)
+{
+ char *buf, *line;
+ int i;
+ int level = default_message_loglevel;
+ int facility = 1; /* LOG_USER */
+ size_t len = iov_length(iv, count);
+ ssize_t ret = len;
+
+ if (len > PRINTK_LOG_LINE_MAX)
+ return -EINVAL;
+ buf = kmalloc(len+1, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ line = buf;
+ for (i = 0; i < count; i++) {
+ if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ line += iv[i].iov_len;
+ }
+
+ /*
+ * Extract and skip the syslog prefix <[0-9]*>. Coming from userspace
+ * the decimal value represents 32bit, the lower 3 bit are the log
+ * level, the rest are the log facility.
+ *
+ * If no prefix or no userspace facility is specified, we
+ * enforce LOG_USER, to be able to reliably distinguish
+ * kernel-generated messages from userspace-injected ones.
+ */
+ line = buf;
+ if (line[0] == '<') {
+ char *endp = NULL;
+
+ i = simple_strtoul(line+1, &endp, 10);
+ if (endp && endp[0] == '>') {
+ level = i & 7;
+ if (i >> 3)
+ facility = i >> 3;
+ endp++;
+ len -= endp - line;
+ line = endp;
+ }
+ }
+ line[len] = '\0';
+
+ printk_emit(facility, level, NULL, 0, "%s", line);
+out:
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t devkmsg_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct devkmsg_user *user = file->private_data;
+ struct printk_log *msg;
+ u64 ts_usec;
+ size_t i;
+ char cont = '-';
+ size_t len;
+ ssize_t ret;
+
+ if (!user)
+ return -EBADF;
+
+ ret = mutex_lock_interruptible(&user->lock);
+ if (ret)
+ return ret;
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ while (user->seq == printk_log_next_seq) {
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ goto out;
+ }
+
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ ret = wait_event_interruptible(printk_log_wait,
+ user->seq != printk_log_next_seq);
+ if (ret)
+ goto out;
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ }
+
+ if (user->seq < printk_log_first_seq) {
+ /* our last seen message is gone, return error and reset */
+ user->idx = printk_log_first_idx;
+ user->seq = printk_log_first_seq;
+ ret = -EPIPE;
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ goto out;
+ }
+
+ msg = printk_log_from_idx(user->idx);
+ ts_usec = msg->ts_nsec;
+ do_div(ts_usec, 1000);
+
+ /*
+ * If we couldn't merge continuation line fragments during the print,
+ * export the stored flags to allow an optional external merge of the
+ * records. Merging the records isn't always neccessarily correct, like
+ * when we hit a race during printing. In most cases though, it produces
+ * better readable output. 'c' in the record flags mark the first
+ * fragment of a line, '+' the following.
+ */
+ if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT))
+ cont = 'c';
+ else if ((msg->flags & LOG_CONT) ||
+ ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
+ cont = '+';
+
+ len = sprintf(user->buf, "%u,%llu,%llu,%c;",
+ (msg->facility << 3) | msg->level,
+ user->seq, ts_usec, cont);
+ user->prev = msg->flags;
+
+ /* escape non-printable characters */
+ for (i = 0; i < msg->text_len; i++) {
+ unsigned char c = printk_log_text(msg)[i];
+
+ if (c < ' ' || c >= 127 || c == '\\')
+ len += sprintf(user->buf + len, "\\x%02x", c);
+ else
+ user->buf[len++] = c;
+ }
+ user->buf[len++] = '\n';
+
+ if (msg->dict_len) {
+ bool line = true;
+
+ for (i = 0; i < msg->dict_len; i++) {
+ unsigned char c = printk_log_dict(msg)[i];
+
+ if (line) {
+ user->buf[len++] = ' ';
+ line = false;
+ }
+
+ if (c == '\0') {
+ user->buf[len++] = '\n';
+ line = true;
+ continue;
+ }
+
+ if (c < ' ' || c >= 127 || c == '\\') {
+ len += sprintf(user->buf + len, "\\x%02x", c);
+ continue;
+ }
+
+ user->buf[len++] = c;
+ }
+ user->buf[len++] = '\n';
+ }
+
+ user->idx = printk_log_next(user->idx);
+ user->seq++;
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+
+ if (len > count) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (copy_to_user(buf, user->buf, len)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ ret = len;
+out:
+ mutex_unlock(&user->lock);
+ return ret;
+}
+
+static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
+{
+ struct devkmsg_user *user = file->private_data;
+ loff_t ret = 0;
+
+ if (!user)
+ return -EBADF;
+ if (offset)
+ return -ESPIPE;
+
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ switch (whence) {
+ case SEEK_SET:
+ /* the first record */
+ user->idx = printk_log_first_idx;
+ user->seq = printk_log_first_seq;
+ break;
+ case SEEK_DATA:
+ /*
+ * The first record after the last SYSLOG_ACTION_CLEAR,
+ * like issued by 'dmesg -c'. Reading /dev/kmsg itself
+ * changes no global state, and does not clear anything.
+ */
+ user->idx = printk_log_clear_idx;
+ user->seq = printk_log_clear_seq;
+ break;
+ case SEEK_END:
+ /* after the last record */
+ user->idx = printk_log_next_idx;
+ user->seq = printk_log_next_seq;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ return ret;
+}
+
+static unsigned int devkmsg_poll(struct file *file, poll_table *wait)
+{
+ struct devkmsg_user *user = file->private_data;
+ int ret = 0;
+
+ if (!user)
+ return POLLERR|POLLNVAL;
+
+ poll_wait(file, &printk_log_wait, wait);
+
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ if (user->seq < printk_log_next_seq) {
+ /* return error when data has vanished underneath us */
+ if (user->seq < printk_log_first_seq)
+ ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI;
+ ret = POLLIN|POLLRDNORM;
+ }
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+
+ return ret;
+}
+
+static int devkmsg_open(struct inode *inode, struct file *file)
+{
+ struct devkmsg_user *user;
+ int err;
+
+ /* write-only does not need any file context */
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY)
+ return 0;
+
+ err = security_syslog(SYSLOG_ACTION_READ_ALL);
+ if (err)
+ return err;
+
+ user = kmalloc(sizeof(struct devkmsg_user), GFP_KERNEL);
+ if (!user)
+ return -ENOMEM;
+
+ mutex_init(&user->lock);
+
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ user->idx = printk_log_first_idx;
+ user->seq = printk_log_first_seq;
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+
+ file->private_data = user;
+ return 0;
+}
+
+static int devkmsg_release(struct inode *inode, struct file *file)
+{
+ struct devkmsg_user *user = file->private_data;
+
+ if (!user)
+ return 0;
+
+ mutex_destroy(&user->lock);
+ kfree(user);
+ return 0;
+}
+
+const struct file_operations kmsg_fops = {
+ .open = devkmsg_open,
+ .read = devkmsg_read,
+ .aio_write = devkmsg_writev,
+ .llseek = devkmsg_llseek,
+ .poll = devkmsg_poll,
+ .release = devkmsg_release,
+};
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 43550a5..875e0dc 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -136,302 +136,6 @@ static enum printk_log_flags console_prev;
/* cpu currently holding printk_logbuf_lock */
static volatile unsigned int logbuf_cpu = UINT_MAX;

-/* /dev/kmsg - userspace message inject/listen interface */
-struct devkmsg_user {
- u64 seq;
- u32 idx;
- enum printk_log_flags prev;
- struct mutex lock;
- char buf[8192];
-};
-
-static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv,
- unsigned long count, loff_t pos)
-{
- char *buf, *line;
- int i;
- int level = default_message_loglevel;
- int facility = 1; /* LOG_USER */
- size_t len = iov_length(iv, count);
- ssize_t ret = len;
-
- if (len > PRINTK_LOG_LINE_MAX)
- return -EINVAL;
- buf = kmalloc(len+1, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- line = buf;
- for (i = 0; i < count; i++) {
- if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) {
- ret = -EFAULT;
- goto out;
- }
- line += iv[i].iov_len;
- }
-
- /*
- * Extract and skip the syslog prefix <[0-9]*>. Coming from userspace
- * the decimal value represents 32bit, the lower 3 bit are the log
- * level, the rest are the log facility.
- *
- * If no prefix or no userspace facility is specified, we
- * enforce LOG_USER, to be able to reliably distinguish
- * kernel-generated messages from userspace-injected ones.
- */
- line = buf;
- if (line[0] == '<') {
- char *endp = NULL;
-
- i = simple_strtoul(line+1, &endp, 10);
- if (endp && endp[0] == '>') {
- level = i & 7;
- if (i >> 3)
- facility = i >> 3;
- endp++;
- len -= endp - line;
- line = endp;
- }
- }
- line[len] = '\0';
-
- printk_emit(facility, level, NULL, 0, "%s", line);
-out:
- kfree(buf);
- return ret;
-}
-
-static ssize_t devkmsg_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct devkmsg_user *user = file->private_data;
- struct printk_log *msg;
- u64 ts_usec;
- size_t i;
- char cont = '-';
- size_t len;
- ssize_t ret;
-
- if (!user)
- return -EBADF;
-
- ret = mutex_lock_interruptible(&user->lock);
- if (ret)
- return ret;
- raw_spin_lock_irq(&printk_logbuf_lock);
- while (user->seq == printk_log_next_seq) {
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- raw_spin_unlock_irq(&printk_logbuf_lock);
- goto out;
- }
-
- raw_spin_unlock_irq(&printk_logbuf_lock);
- ret = wait_event_interruptible(printk_log_wait,
- user->seq != printk_log_next_seq);
- if (ret)
- goto out;
- raw_spin_lock_irq(&printk_logbuf_lock);
- }
-
- if (user->seq < printk_log_first_seq) {
- /* our last seen message is gone, return error and reset */
- user->idx = printk_log_first_idx;
- user->seq = printk_log_first_seq;
- ret = -EPIPE;
- raw_spin_unlock_irq(&printk_logbuf_lock);
- goto out;
- }
-
- msg = printk_log_from_idx(user->idx);
- ts_usec = msg->ts_nsec;
- do_div(ts_usec, 1000);
-
- /*
- * If we couldn't merge continuation line fragments during the print,
- * export the stored flags to allow an optional external merge of the
- * records. Merging the records isn't always neccessarily correct, like
- * when we hit a race during printing. In most cases though, it produces
- * better readable output. 'c' in the record flags mark the first
- * fragment of a line, '+' the following.
- */
- if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT))
- cont = 'c';
- else if ((msg->flags & LOG_CONT) ||
- ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
- cont = '+';
-
- len = sprintf(user->buf, "%u,%llu,%llu,%c;",
- (msg->facility << 3) | msg->level,
- user->seq, ts_usec, cont);
- user->prev = msg->flags;
-
- /* escape non-printable characters */
- for (i = 0; i < msg->text_len; i++) {
- unsigned char c = printk_log_text(msg)[i];
-
- if (c < ' ' || c >= 127 || c == '\\')
- len += sprintf(user->buf + len, "\\x%02x", c);
- else
- user->buf[len++] = c;
- }
- user->buf[len++] = '\n';
-
- if (msg->dict_len) {
- bool line = true;
-
- for (i = 0; i < msg->dict_len; i++) {
- unsigned char c = printk_log_dict(msg)[i];
-
- if (line) {
- user->buf[len++] = ' ';
- line = false;
- }
-
- if (c == '\0') {
- user->buf[len++] = '\n';
- line = true;
- continue;
- }
-
- if (c < ' ' || c >= 127 || c == '\\') {
- len += sprintf(user->buf + len, "\\x%02x", c);
- continue;
- }
-
- user->buf[len++] = c;
- }
- user->buf[len++] = '\n';
- }
-
- user->idx = printk_log_next(user->idx);
- user->seq++;
- raw_spin_unlock_irq(&printk_logbuf_lock);
-
- if (len > count) {
- ret = -EINVAL;
- goto out;
- }
-
- if (copy_to_user(buf, user->buf, len)) {
- ret = -EFAULT;
- goto out;
- }
- ret = len;
-out:
- mutex_unlock(&user->lock);
- return ret;
-}
-
-static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
-{
- struct devkmsg_user *user = file->private_data;
- loff_t ret = 0;
-
- if (!user)
- return -EBADF;
- if (offset)
- return -ESPIPE;
-
- raw_spin_lock_irq(&printk_logbuf_lock);
- switch (whence) {
- case SEEK_SET:
- /* the first record */
- user->idx = printk_log_first_idx;
- user->seq = printk_log_first_seq;
- break;
- case SEEK_DATA:
- /*
- * The first record after the last SYSLOG_ACTION_CLEAR,
- * like issued by 'dmesg -c'. Reading /dev/kmsg itself
- * changes no global state, and does not clear anything.
- */
- user->idx = printk_log_clear_idx;
- user->seq = printk_log_clear_seq;
- break;
- case SEEK_END:
- /* after the last record */
- user->idx = printk_log_next_idx;
- user->seq = printk_log_next_seq;
- break;
- default:
- ret = -EINVAL;
- }
- raw_spin_unlock_irq(&printk_logbuf_lock);
- return ret;
-}
-
-static unsigned int devkmsg_poll(struct file *file, poll_table *wait)
-{
- struct devkmsg_user *user = file->private_data;
- int ret = 0;
-
- if (!user)
- return POLLERR|POLLNVAL;
-
- poll_wait(file, &printk_log_wait, wait);
-
- raw_spin_lock_irq(&printk_logbuf_lock);
- if (user->seq < printk_log_next_seq) {
- /* return error when data has vanished underneath us */
- if (user->seq < printk_log_first_seq)
- ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI;
- ret = POLLIN|POLLRDNORM;
- }
- raw_spin_unlock_irq(&printk_logbuf_lock);
-
- return ret;
-}
-
-static int devkmsg_open(struct inode *inode, struct file *file)
-{
- struct devkmsg_user *user;
- int err;
-
- /* write-only does not need any file context */
- if ((file->f_flags & O_ACCMODE) == O_WRONLY)
- return 0;
-
- err = security_syslog(SYSLOG_ACTION_READ_ALL);
- if (err)
- return err;
-
- user = kmalloc(sizeof(struct devkmsg_user), GFP_KERNEL);
- if (!user)
- return -ENOMEM;
-
- mutex_init(&user->lock);
-
- raw_spin_lock_irq(&printk_logbuf_lock);
- user->idx = printk_log_first_idx;
- user->seq = printk_log_first_seq;
- raw_spin_unlock_irq(&printk_logbuf_lock);
-
- file->private_data = user;
- return 0;
-}
-
-static int devkmsg_release(struct inode *inode, struct file *file)
-{
- struct devkmsg_user *user = file->private_data;
-
- if (!user)
- return 0;
-
- mutex_destroy(&user->lock);
- kfree(user);
- return 0;
-}
-
-const struct file_operations kmsg_fops = {
- .open = devkmsg_open,
- .read = devkmsg_read,
- .aio_write = devkmsg_writev,
- .llseek = devkmsg_llseek,
- .poll = devkmsg_poll,
- .release = devkmsg_release,
-};
-
#ifdef CONFIG_KEXEC
/*
* This appends the listed symbols to /proc/vmcoreinfo
--
1.7.10.4

2012-10-17 06:09:53

by Joe Perches

[permalink] [raw]
Subject: [PATCH 20/23] printk: Prefix print_time and msg_print_text with printk_

Make these static functions global and prefix them with printk_.
Create declarations for these functions in printk_log.h

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 43 ++++++++++++++++++++++++-------------------
kernel/printk/printk_log.h | 4 ++++
2 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 875e0dc..cd0d317 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -318,7 +318,7 @@ static bool printk_time;
#endif
module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);

-static size_t print_time(u64 ts, char *buf)
+size_t printk_print_time(u64 ts, char *buf)
{
unsigned long rem_nsec;

@@ -352,11 +352,11 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
}
}

- len += print_time(msg->ts_nsec, buf ? buf + len : NULL);
+ len += printk_print_time(msg->ts_nsec, buf ? buf + len : NULL);
return len;
}

-static size_t msg_print_text(const struct printk_log *msg,
+size_t printk_msg_print_text(const struct printk_log *msg,
enum printk_log_flags prev,
bool syslog, char *buf, size_t size)
{
@@ -445,8 +445,8 @@ static int syslog_print(char __user *buf, int size)

skip = syslog_partial;
msg = printk_log_from_idx(syslog_idx);
- n = msg_print_text(msg, syslog_prev, true, text,
- PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
+ n = printk_msg_print_text(msg, syslog_prev, true, text,
+ PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
if (n - syslog_partial <= size) {
/* message fits into buffer, move forward */
syslog_idx = printk_log_next(syslog_idx);
@@ -512,7 +512,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
while (seq < printk_log_next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);

- len += msg_print_text(msg, prev, true, NULL, 0);
+ len += printk_msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags;
idx = printk_log_next(idx);
seq++;
@@ -525,7 +525,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
while (len > size && seq < printk_log_next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);

- len -= msg_print_text(msg, prev, true, NULL, 0);
+ len -= printk_msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags;
idx = printk_log_next(idx);
seq++;
@@ -540,8 +540,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
struct printk_log *msg = printk_log_from_idx(idx);
int textlen;

- textlen = msg_print_text(msg, prev, true, text,
- PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
+ textlen = printk_msg_print_text(msg, prev, true, text,
+ PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
if (textlen < 0) {
len = textlen;
break;
@@ -685,7 +685,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
while (seq < printk_log_next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);

- error += msg_print_text(msg, prev, true, NULL, 0);
+ error += printk_msg_print_text(msg, prev, true, NULL, 0);
idx = printk_log_next(idx);
seq++;
prev = msg->flags;
@@ -936,7 +936,7 @@ static size_t cont_print_text(char *text, size_t size)
size_t len;

if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) {
- textlen += print_time(cont.ts_nsec, text);
+ textlen += printk_print_time(cont.ts_nsec, text);
size -= textlen;
}

@@ -1186,9 +1186,14 @@ static struct cont {
struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
u32 printk_log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
-static size_t msg_print_text(const struct printk_log *msg,
+size_t printk_print_time(u64 ts, char *buf) { return 0; }
+size_t printk_msg_print_text(const struct printk_log *msg,
enum printk_log_flags prev,
- bool syslog, char *buf, size_t size) { return 0; }
+ bool syslog, char *buf, size_t size)
+{
+ return 0;
+}
+
static size_t cont_print_text(char *text, size_t size) { return 0; }

#endif /* CONFIG_PRINTK */
@@ -1549,8 +1554,8 @@ skip:
}

level = msg->level;
- len = msg_print_text(msg, console_prev, false,
- text, sizeof(text));
+ len = printk_msg_print_text(msg, console_prev, false,
+ text, sizeof(text));
console_idx = printk_log_next(console_idx);
console_seq++;
console_prev = msg->flags;
@@ -2104,7 +2109,7 @@ bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
goto out;

msg = printk_log_from_idx(dumper->cur_idx);
- l = msg_print_text(msg, 0, syslog, line, size);
+ l = printk_msg_print_text(msg, 0, syslog, line, size);

dumper->cur_idx = printk_log_next(dumper->cur_idx);
dumper->cur_seq++;
@@ -2200,7 +2205,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
while (seq < dumper->next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);

- l += msg_print_text(msg, prev, true, NULL, 0);
+ l += printk_msg_print_text(msg, prev, true, NULL, 0);
idx = printk_log_next(idx);
seq++;
prev = msg->flags;
@@ -2213,7 +2218,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
while (l > size && seq < dumper->next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);

- l -= msg_print_text(msg, prev, true, NULL, 0);
+ l -= printk_msg_print_text(msg, prev, true, NULL, 0);
idx = printk_log_next(idx);
seq++;
prev = msg->flags;
@@ -2228,7 +2233,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
while (seq < dumper->next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);

- l += msg_print_text(msg, prev, syslog, buf + l, size - l);
+ l += printk_msg_print_text(msg, prev, syslog, buf + l, size - l);
idx = printk_log_next(idx);
seq++;
prev = msg->flags;
diff --git a/kernel/printk/printk_log.h b/kernel/printk/printk_log.h
index a7125d5..6075297 100644
--- a/kernel/printk/printk_log.h
+++ b/kernel/printk/printk_log.h
@@ -115,5 +115,9 @@ void printk_log_store(int facility, int level,
enum printk_log_flags flags, u64 ts_nsec,
const char *dict, u16 dict_len,
const char *text, u16 text_len);
+size_t printk_print_time(u64 ts, char *buf);
+size_t printk_msg_print_text(const struct printk_log *msg,
+ enum printk_log_flags prev,
+ bool syslog, char *buf, size_t size);

#endif
--
1.7.10.4

2012-10-17 06:10:05

by Joe Perches

[permalink] [raw]
Subject: [PATCH 21/23] printk: Move functions printk_print_time and printk_msg_print_text

Move these functions to printk_log.
Move the static function print_prefix too.
Add "#include <linux/moduleparam.h>" to printk_log.c.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 112 -------------------------------------------
kernel/printk/printk_log.c | 114 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 114 insertions(+), 112 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index cd0d317..343b0ce 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -311,111 +311,6 @@ static int check_syslog_permissions(int type, bool from_file)
return 0;
}

-#if defined(CONFIG_PRINTK_TIME)
-static bool printk_time = 1;
-#else
-static bool printk_time;
-#endif
-module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
-
-size_t printk_print_time(u64 ts, char *buf)
-{
- unsigned long rem_nsec;
-
- if (!printk_time)
- return 0;
-
- if (!buf)
- return 15;
-
- rem_nsec = do_div(ts, 1000000000);
- return sprintf(buf, "[%5lu.%06lu] ",
- (unsigned long)ts, rem_nsec / 1000);
-}
-
-static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
-{
- size_t len = 0;
- unsigned int prefix = (msg->facility << 3) | msg->level;
-
- if (syslog) {
- if (buf) {
- len += sprintf(buf, "<%u>", prefix);
- } else {
- len += 3;
- if (prefix > 999)
- len += 3;
- else if (prefix > 99)
- len += 2;
- else if (prefix > 9)
- len++;
- }
- }
-
- len += printk_print_time(msg->ts_nsec, buf ? buf + len : NULL);
- return len;
-}
-
-size_t printk_msg_print_text(const struct printk_log *msg,
- enum printk_log_flags prev,
- bool syslog, char *buf, size_t size)
-{
- const char *text = printk_log_text(msg);
- size_t text_size = msg->text_len;
- bool prefix = true;
- bool newline = true;
- size_t len = 0;
-
- if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
- prefix = false;
-
- if (msg->flags & LOG_CONT) {
- if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
- prefix = false;
-
- if (!(msg->flags & LOG_NEWLINE))
- newline = false;
- }
-
- do {
- const char *next = memchr(text, '\n', text_size);
- size_t text_len;
-
- if (next) {
- text_len = next - text;
- next++;
- text_size -= next - text;
- } else {
- text_len = text_size;
- }
-
- if (buf) {
- if (print_prefix(msg, syslog, NULL) +
- text_len + 1 >= size - len)
- break;
-
- if (prefix)
- len += print_prefix(msg, syslog, buf + len);
- memcpy(buf + len, text, text_len);
- len += text_len;
- if (next || newline)
- buf[len++] = '\n';
- } else {
- /* SYSLOG_ACTION_* buffer size only calculation */
- if (prefix)
- len += print_prefix(msg, syslog, NULL);
- len += text_len;
- if (next || newline)
- len++;
- }
-
- prefix = true;
- text = next;
- } while (text);
-
- return len;
-}
-
static int syslog_print(char __user *buf, int size)
{
char *text;
@@ -1186,13 +1081,6 @@ static struct cont {
struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
u32 printk_log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
-size_t printk_print_time(u64 ts, char *buf) { return 0; }
-size_t printk_msg_print_text(const struct printk_log *msg,
- enum printk_log_flags prev,
- bool syslog, char *buf, size_t size)
-{
- return 0;
-}

static size_t cont_print_text(char *text, size_t size) { return 0; }

diff --git a/kernel/printk/printk_log.c b/kernel/printk/printk_log.c
index b5c2b8f..d38129c 100644
--- a/kernel/printk/printk_log.c
+++ b/kernel/printk/printk_log.c
@@ -2,6 +2,8 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/kexec.h>
+#include <linux/moduleparam.h>
+#include <linux/stat.h>

#include "printk_log.h"

@@ -135,6 +137,111 @@ void printk_log_store(int facility, int level,
printk_log_next_seq++;
}

+#if defined(CONFIG_PRINTK_TIME)
+static bool printk_time = 1;
+#else
+static bool printk_time;
+#endif
+module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
+
+size_t printk_print_time(u64 ts, char *buf)
+{
+ unsigned long rem_nsec;
+
+ if (!printk_time)
+ return 0;
+
+ if (!buf)
+ return 15;
+
+ rem_nsec = do_div(ts, 1000000000);
+ return sprintf(buf, "[%5lu.%06lu] ",
+ (unsigned long)ts, rem_nsec / 1000);
+}
+
+static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
+{
+ size_t len = 0;
+ unsigned int prefix = (msg->facility << 3) | msg->level;
+
+ if (syslog) {
+ if (buf) {
+ len += sprintf(buf, "<%u>", prefix);
+ } else {
+ len += 3;
+ if (prefix > 999)
+ len += 3;
+ else if (prefix > 99)
+ len += 2;
+ else if (prefix > 9)
+ len++;
+ }
+ }
+
+ len += printk_print_time(msg->ts_nsec, buf ? buf + len : NULL);
+ return len;
+}
+
+size_t printk_msg_print_text(const struct printk_log *msg,
+ enum printk_log_flags prev,
+ bool syslog, char *buf, size_t size)
+{
+ const char *text = printk_log_text(msg);
+ size_t text_size = msg->text_len;
+ bool prefix = true;
+ bool newline = true;
+ size_t len = 0;
+
+ if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
+ prefix = false;
+
+ if (msg->flags & LOG_CONT) {
+ if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
+ prefix = false;
+
+ if (!(msg->flags & LOG_NEWLINE))
+ newline = false;
+ }
+
+ do {
+ const char *next = memchr(text, '\n', text_size);
+ size_t text_len;
+
+ if (next) {
+ text_len = next - text;
+ next++;
+ text_size -= next - text;
+ } else {
+ text_len = text_size;
+ }
+
+ if (buf) {
+ if (print_prefix(msg, syslog, NULL) +
+ text_len + 1 >= size - len)
+ break;
+
+ if (prefix)
+ len += print_prefix(msg, syslog, buf + len);
+ memcpy(buf + len, text, text_len);
+ len += text_len;
+ if (next || newline)
+ buf[len++] = '\n';
+ } else {
+ /* SYSLOG_ACTION_* buffer size only calculation */
+ if (prefix)
+ len += print_prefix(msg, syslog, NULL);
+ len += text_len;
+ if (next || newline)
+ len++;
+ }
+
+ prefix = true;
+ text = next;
+ } while (text);
+
+ return len;
+}
+
#else /* CONFIG_PRINTK */

#define LOG_LINE_MAX 0
@@ -145,5 +252,12 @@ u32 printk_log_first_idx;
u64 printk_log_next_seq;
struct printk_log *printk_log_from_idx(u32 idx) { return NULL; }
u32 printk_log_next(u32 idx) { return 0; }
+size_t printk_print_time(u64 ts, char *buf) { return 0; }
+size_t printk_msg_print_text(const struct printk_log *msg,
+ enum printk_log_flags prev,
+ bool syslog, char *buf, size_t size)
+{
+ return 0;
+}

#endif /* CONFIG_PRINTK */
--
1.7.10.4

2012-10-17 06:10:18

by Joe Perches

[permalink] [raw]
Subject: [PATCH 22/23] printk: Add printk_syslog.c and .h

Move syslog functions to a separate file.
Add compilation unit to Makefile.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/Makefile | 1 +
kernel/printk/printk.c | 351 +---------------------------------------
kernel/printk/printk_syslog.c | 354 +++++++++++++++++++++++++++++++++++++++++
kernel/printk/printk_syslog.h | 12 ++
4 files changed, 371 insertions(+), 347 deletions(-)
create mode 100644 kernel/printk/printk_syslog.c
create mode 100644 kernel/printk/printk_syslog.h

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index bda335f..7947661 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1,4 +1,5 @@
obj-y = printk.o
obj-y += printk_log.o
obj-y += devkmsg.o
+obj-y += printk_syslog.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 343b0ce..cba438e 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -30,12 +30,10 @@
#include <linux/security.h>
#include <linux/bootmem.h>
#include <linux/memblock.h>
-#include <linux/syscalls.h>
#include <linux/kexec.h>
#include <linux/kdb.h>
#include <linux/ratelimit.h>
#include <linux/kmsg_dump.h>
-#include <linux/syslog.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/rculist.h>
@@ -49,6 +47,7 @@
#include "console_cmdline.h"
#include "braille.h"
#include "printk_log.h"
+#include "printk_syslog.h"

/*
* Architectures can override it:
@@ -122,11 +121,6 @@ EXPORT_SYMBOL(console_set_on_cmdline);
static int console_may_schedule;

#ifdef CONFIG_PRINTK
-/* the next printk record to read by syslog(READ) or /proc/kmsg */
-static u64 syslog_seq;
-static u32 syslog_idx;
-static enum printk_log_flags syslog_prev;
-static size_t syslog_partial;

/* the next printk record to write to the console */
static u64 console_seq;
@@ -272,340 +266,6 @@ static inline void boot_delay_msec(void)
}
#endif

-#ifdef CONFIG_SECURITY_DMESG_RESTRICT
-int dmesg_restrict = 1;
-#else
-int dmesg_restrict;
-#endif
-
-static int syslog_action_restricted(int type)
-{
- if (dmesg_restrict)
- return 1;
- /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
- return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
-}
-
-static int check_syslog_permissions(int type, bool from_file)
-{
- /*
- * If this is from /proc/kmsg and we've already opened it, then we've
- * already done the capabilities checks at open time.
- */
- if (from_file && type != SYSLOG_ACTION_OPEN)
- return 0;
-
- if (syslog_action_restricted(type)) {
- if (capable(CAP_SYSLOG))
- return 0;
- /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
- if (capable(CAP_SYS_ADMIN)) {
- printk_once(KERN_WARNING "%s (%d): "
- "Attempt to access syslog with CAP_SYS_ADMIN "
- "but no CAP_SYSLOG (deprecated).\n",
- current->comm, task_pid_nr(current));
- return 0;
- }
- return -EPERM;
- }
- return 0;
-}
-
-static int syslog_print(char __user *buf, int size)
-{
- char *text;
- struct printk_log *msg;
- int len = 0;
-
- text = kmalloc(PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX, GFP_KERNEL);
- if (!text)
- return -ENOMEM;
-
- while (size > 0) {
- size_t n;
- size_t skip;
-
- raw_spin_lock_irq(&printk_logbuf_lock);
- if (syslog_seq < printk_log_first_seq) {
- /* messages are gone, move to first one */
- syslog_seq = printk_log_first_seq;
- syslog_idx = printk_log_first_idx;
- syslog_prev = 0;
- syslog_partial = 0;
- }
- if (syslog_seq == printk_log_next_seq) {
- raw_spin_unlock_irq(&printk_logbuf_lock);
- break;
- }
-
- skip = syslog_partial;
- msg = printk_log_from_idx(syslog_idx);
- n = printk_msg_print_text(msg, syslog_prev, true, text,
- PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
- if (n - syslog_partial <= size) {
- /* message fits into buffer, move forward */
- syslog_idx = printk_log_next(syslog_idx);
- syslog_seq++;
- syslog_prev = msg->flags;
- n -= syslog_partial;
- syslog_partial = 0;
- } else if (!len){
- /* partial read(), remember position */
- n = size;
- syslog_partial += n;
- } else
- n = 0;
- raw_spin_unlock_irq(&printk_logbuf_lock);
-
- if (!n)
- break;
-
- if (copy_to_user(buf, text + skip, n)) {
- if (!len)
- len = -EFAULT;
- break;
- }
-
- len += n;
- size -= n;
- buf += n;
- }
-
- kfree(text);
- return len;
-}
-
-static int syslog_print_all(char __user *buf, int size, bool clear)
-{
- char *text;
- int len = 0;
-
- text = kmalloc(PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX, GFP_KERNEL);
- if (!text)
- return -ENOMEM;
-
- raw_spin_lock_irq(&printk_logbuf_lock);
- if (buf) {
- u64 next_seq;
- u64 seq;
- u32 idx;
- enum printk_log_flags prev;
-
- if (printk_log_clear_seq < printk_log_first_seq) {
- /* messages are gone, move to first available one */
- printk_log_clear_seq = printk_log_first_seq;
- printk_log_clear_idx = printk_log_first_idx;
- }
-
- /*
- * Find first record that fits, including all following records,
- * into the user-provided buffer for this dump.
- */
- seq = printk_log_clear_seq;
- idx = printk_log_clear_idx;
- prev = 0;
- while (seq < printk_log_next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
-
- len += printk_msg_print_text(msg, prev, true, NULL, 0);
- prev = msg->flags;
- idx = printk_log_next(idx);
- seq++;
- }
-
- /* move first record forward until length fits into the buffer */
- seq = printk_log_clear_seq;
- idx = printk_log_clear_idx;
- prev = 0;
- while (len > size && seq < printk_log_next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
-
- len -= printk_msg_print_text(msg, prev, true, NULL, 0);
- prev = msg->flags;
- idx = printk_log_next(idx);
- seq++;
- }
-
- /* last message fitting into this dump */
- next_seq = printk_log_next_seq;
-
- len = 0;
- prev = 0;
- while (len >= 0 && seq < next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
- int textlen;
-
- textlen = printk_msg_print_text(msg, prev, true, text,
- PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
- if (textlen < 0) {
- len = textlen;
- break;
- }
- idx = printk_log_next(idx);
- seq++;
- prev = msg->flags;
-
- raw_spin_unlock_irq(&printk_logbuf_lock);
- if (copy_to_user(buf + len, text, textlen))
- len = -EFAULT;
- else
- len += textlen;
- raw_spin_lock_irq(&printk_logbuf_lock);
-
- if (seq < printk_log_first_seq) {
- /* messages are gone, move to next one */
- seq = printk_log_first_seq;
- idx = printk_log_first_idx;
- prev = 0;
- }
- }
- }
-
- if (clear) {
- printk_log_clear_seq = printk_log_next_seq;
- printk_log_clear_idx = printk_log_next_idx;
- }
- raw_spin_unlock_irq(&printk_logbuf_lock);
-
- kfree(text);
- return len;
-}
-
-int do_syslog(int type, char __user *buf, int len, bool from_file)
-{
- bool clear = false;
- static int saved_console_loglevel = -1;
- int error;
-
- error = check_syslog_permissions(type, from_file);
- if (error)
- goto out;
-
- error = security_syslog(type);
- if (error)
- return error;
-
- switch (type) {
- case SYSLOG_ACTION_CLOSE: /* Close log */
- break;
- case SYSLOG_ACTION_OPEN: /* Open log */
- break;
- case SYSLOG_ACTION_READ: /* Read from log */
- error = -EINVAL;
- if (!buf || len < 0)
- goto out;
- error = 0;
- if (!len)
- goto out;
- if (!access_ok(VERIFY_WRITE, buf, len)) {
- error = -EFAULT;
- goto out;
- }
- error = wait_event_interruptible(printk_log_wait,
- syslog_seq != printk_log_next_seq);
- if (error)
- goto out;
- error = syslog_print(buf, len);
- break;
- /* Read/clear last kernel messages */
- case SYSLOG_ACTION_READ_CLEAR:
- clear = true;
- /* FALL THRU */
- /* Read last kernel messages */
- case SYSLOG_ACTION_READ_ALL:
- error = -EINVAL;
- if (!buf || len < 0)
- goto out;
- error = 0;
- if (!len)
- goto out;
- if (!access_ok(VERIFY_WRITE, buf, len)) {
- error = -EFAULT;
- goto out;
- }
- error = syslog_print_all(buf, len, clear);
- break;
- /* Clear ring buffer */
- case SYSLOG_ACTION_CLEAR:
- syslog_print_all(NULL, 0, true);
- break;
- /* Disable logging to console */
- case SYSLOG_ACTION_CONSOLE_OFF:
- if (saved_console_loglevel == -1)
- saved_console_loglevel = console_loglevel;
- console_loglevel = minimum_console_loglevel;
- break;
- /* Enable logging to console */
- case SYSLOG_ACTION_CONSOLE_ON:
- if (saved_console_loglevel != -1) {
- console_loglevel = saved_console_loglevel;
- saved_console_loglevel = -1;
- }
- break;
- /* Set level of messages printed to console */
- case SYSLOG_ACTION_CONSOLE_LEVEL:
- error = -EINVAL;
- if (len < 1 || len > 8)
- goto out;
- if (len < minimum_console_loglevel)
- len = minimum_console_loglevel;
- console_loglevel = len;
- /* Implicitly re-enable logging to console */
- saved_console_loglevel = -1;
- error = 0;
- break;
- /* Number of chars in the log buffer */
- case SYSLOG_ACTION_SIZE_UNREAD:
- raw_spin_lock_irq(&printk_logbuf_lock);
- if (syslog_seq < printk_log_first_seq) {
- /* messages are gone, move to first one */
- syslog_seq = printk_log_first_seq;
- syslog_idx = printk_log_first_idx;
- syslog_prev = 0;
- syslog_partial = 0;
- }
- if (from_file) {
- /*
- * Short-cut for poll(/"proc/kmsg") which simply checks
- * for pending data, not the size; return the count of
- * records, not the length.
- */
- error = printk_log_next_idx - syslog_idx;
- } else {
- u64 seq = syslog_seq;
- u32 idx = syslog_idx;
- enum printk_log_flags prev = syslog_prev;
-
- error = 0;
- while (seq < printk_log_next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
-
- error += printk_msg_print_text(msg, prev, true, NULL, 0);
- idx = printk_log_next(idx);
- seq++;
- prev = msg->flags;
- }
- error -= syslog_partial;
- }
- raw_spin_unlock_irq(&printk_logbuf_lock);
- break;
- /* Size of the log buffer */
- case SYSLOG_ACTION_SIZE_BUFFER:
- error = printk_log_buf_len;
- break;
- default:
- error = -EINVAL;
- break;
- }
-out:
- return error;
-}
-
-SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
-{
- return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
-}
-
static bool __read_mostly ignore_loglevel;

static int __init ignore_loglevel_setup(char *str)
@@ -1063,11 +723,8 @@ EXPORT_SYMBOL(printk);

#define PRINTK_LOG_LINE_MAX 0
#define PRINTK_PREFIX_MAX 0
-static u64 syslog_seq;
-static u32 syslog_idx;
static u64 console_seq;
static u32 console_idx;
-static enum printk_log_flags syslog_prev;
u64 printk_log_first_seq;
u32 printk_log_first_idx;
u64 printk_log_next_seq;
@@ -1703,9 +1360,9 @@ void register_console(struct console *newcon)
* for us.
*/
raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
- console_seq = syslog_seq;
- console_idx = syslog_idx;
- console_prev = syslog_prev;
+ console_seq = printk_syslog_seq;
+ console_idx = printk_syslog_idx;
+ console_prev = printk_syslog_prev;
raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
/*
* We're about to replay the log buffer. Only do this to the
diff --git a/kernel/printk/printk_syslog.c b/kernel/printk/printk_syslog.c
new file mode 100644
index 0000000..65f288b
--- /dev/null
+++ b/kernel/printk/printk_syslog.c
@@ -0,0 +1,354 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/syslog.h>
+
+#include "printk_log.h"
+#include "printk_syslog.h"
+
+/* the next printk record to read by syslog(READ) or /proc/kmsg */
+u64 printk_syslog_seq;
+u32 printk_syslog_idx;
+enum printk_log_flags printk_syslog_prev;
+
+#ifdef CONFIG_PRINTK
+
+static size_t printk_syslog_partial;
+
+#ifdef CONFIG_SECURITY_DMESG_RESTRICT
+int dmesg_restrict = 1;
+#else
+int dmesg_restrict;
+#endif
+
+static int printk_syslog_action_restricted(int type)
+{
+ if (dmesg_restrict)
+ return 1;
+ /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
+ return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
+}
+
+static int check_syslog_permissions(int type, bool from_file)
+{
+ /*
+ * If this is from /proc/kmsg and we've already opened it, then we've
+ * already done the capabilities checks at open time.
+ */
+ if (from_file && type != SYSLOG_ACTION_OPEN)
+ return 0;
+
+ if (printk_syslog_action_restricted(type)) {
+ if (capable(CAP_SYSLOG))
+ return 0;
+ /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
+ if (capable(CAP_SYS_ADMIN)) {
+ printk_once(KERN_WARNING "%s (%d): "
+ "Attempt to access syslog with CAP_SYS_ADMIN "
+ "but no CAP_SYSLOG (deprecated).\n",
+ current->comm, task_pid_nr(current));
+ return 0;
+ }
+ return -EPERM;
+ }
+ return 0;
+}
+
+static int printk_syslog_print(char __user *buf, int size)
+{
+ char *text;
+ struct printk_log *msg;
+ int len = 0;
+
+ text = kmalloc(PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX, GFP_KERNEL);
+ if (!text)
+ return -ENOMEM;
+
+ while (size > 0) {
+ size_t n;
+ size_t skip;
+
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ if (printk_syslog_seq < printk_log_first_seq) {
+ /* messages are gone, move to first one */
+ printk_syslog_seq = printk_log_first_seq;
+ printk_syslog_idx = printk_log_first_idx;
+ printk_syslog_prev = 0;
+ printk_syslog_partial = 0;
+ }
+ if (printk_syslog_seq == printk_log_next_seq) {
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ break;
+ }
+
+ skip = printk_syslog_partial;
+ msg = printk_log_from_idx(printk_syslog_idx);
+ n = printk_msg_print_text(msg, printk_syslog_prev, true, text,
+ PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
+ if (n - printk_syslog_partial <= size) {
+ /* message fits into buffer, move forward */
+ printk_syslog_idx = printk_log_next(printk_syslog_idx);
+ printk_syslog_seq++;
+ printk_syslog_prev = msg->flags;
+ n -= printk_syslog_partial;
+ printk_syslog_partial = 0;
+ } else if (!len){
+ /* partial read(), remember position */
+ n = size;
+ printk_syslog_partial += n;
+ } else
+ n = 0;
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+
+ if (!n)
+ break;
+
+ if (copy_to_user(buf, text + skip, n)) {
+ if (!len)
+ len = -EFAULT;
+ break;
+ }
+
+ len += n;
+ size -= n;
+ buf += n;
+ }
+
+ kfree(text);
+ return len;
+}
+
+static int printk_syslog_print_all(char __user *buf, int size, bool clear)
+{
+ char *text;
+ int len = 0;
+
+ text = kmalloc(PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX, GFP_KERNEL);
+ if (!text)
+ return -ENOMEM;
+
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ if (buf) {
+ u64 next_seq;
+ u64 seq;
+ u32 idx;
+ enum printk_log_flags prev;
+
+ if (printk_log_clear_seq < printk_log_first_seq) {
+ /* messages are gone, move to first available one */
+ printk_log_clear_seq = printk_log_first_seq;
+ printk_log_clear_idx = printk_log_first_idx;
+ }
+
+ /*
+ * Find first record that fits, including all following records,
+ * into the user-provided buffer for this dump.
+ */
+ seq = printk_log_clear_seq;
+ idx = printk_log_clear_idx;
+ prev = 0;
+ while (seq < printk_log_next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+
+ len += printk_msg_print_text(msg, prev, true, NULL, 0);
+ prev = msg->flags;
+ idx = printk_log_next(idx);
+ seq++;
+ }
+
+ /* move first record forward until length fits into the buffer */
+ seq = printk_log_clear_seq;
+ idx = printk_log_clear_idx;
+ prev = 0;
+ while (len > size && seq < printk_log_next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+
+ len -= printk_msg_print_text(msg, prev, true, NULL, 0);
+ prev = msg->flags;
+ idx = printk_log_next(idx);
+ seq++;
+ }
+
+ /* last message fitting into this dump */
+ next_seq = printk_log_next_seq;
+
+ len = 0;
+ prev = 0;
+ while (len >= 0 && seq < next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+ int textlen;
+
+ textlen = printk_msg_print_text(msg, prev, true, text,
+ PRINTK_LOG_LINE_MAX + PRINTK_PREFIX_MAX);
+ if (textlen < 0) {
+ len = textlen;
+ break;
+ }
+ idx = printk_log_next(idx);
+ seq++;
+ prev = msg->flags;
+
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ if (copy_to_user(buf + len, text, textlen))
+ len = -EFAULT;
+ else
+ len += textlen;
+ raw_spin_lock_irq(&printk_logbuf_lock);
+
+ if (seq < printk_log_first_seq) {
+ /* messages are gone, move to next one */
+ seq = printk_log_first_seq;
+ idx = printk_log_first_idx;
+ prev = 0;
+ }
+ }
+ }
+
+ if (clear) {
+ printk_log_clear_seq = printk_log_next_seq;
+ printk_log_clear_idx = printk_log_next_idx;
+ }
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+
+ kfree(text);
+ return len;
+}
+
+int do_syslog(int type, char __user *buf, int len, bool from_file)
+{
+ bool clear = false;
+ static int saved_console_loglevel = -1;
+ int error;
+
+ error = check_syslog_permissions(type, from_file);
+ if (error)
+ goto out;
+
+ error = security_syslog(type);
+ if (error)
+ return error;
+
+ switch (type) {
+ case SYSLOG_ACTION_CLOSE: /* Close log */
+ break;
+ case SYSLOG_ACTION_OPEN: /* Open log */
+ break;
+ case SYSLOG_ACTION_READ: /* Read from log */
+ error = -EINVAL;
+ if (!buf || len < 0)
+ goto out;
+ error = 0;
+ if (!len)
+ goto out;
+ if (!access_ok(VERIFY_WRITE, buf, len)) {
+ error = -EFAULT;
+ goto out;
+ }
+ error = wait_event_interruptible(printk_log_wait,
+ printk_syslog_seq != printk_log_next_seq);
+ if (error)
+ goto out;
+ error = printk_syslog_print(buf, len);
+ break;
+ /* Read/clear last kernel messages */
+ case SYSLOG_ACTION_READ_CLEAR:
+ clear = true;
+ /* FALL THRU */
+ /* Read last kernel messages */
+ case SYSLOG_ACTION_READ_ALL:
+ error = -EINVAL;
+ if (!buf || len < 0)
+ goto out;
+ error = 0;
+ if (!len)
+ goto out;
+ if (!access_ok(VERIFY_WRITE, buf, len)) {
+ error = -EFAULT;
+ goto out;
+ }
+ error = printk_syslog_print_all(buf, len, clear);
+ break;
+ /* Clear ring buffer */
+ case SYSLOG_ACTION_CLEAR:
+ printk_syslog_print_all(NULL, 0, true);
+ break;
+ /* Disable logging to console */
+ case SYSLOG_ACTION_CONSOLE_OFF:
+ if (saved_console_loglevel == -1)
+ saved_console_loglevel = console_loglevel;
+ console_loglevel = minimum_console_loglevel;
+ break;
+ /* Enable logging to console */
+ case SYSLOG_ACTION_CONSOLE_ON:
+ if (saved_console_loglevel != -1) {
+ console_loglevel = saved_console_loglevel;
+ saved_console_loglevel = -1;
+ }
+ break;
+ /* Set level of messages printed to console */
+ case SYSLOG_ACTION_CONSOLE_LEVEL:
+ error = -EINVAL;
+ if (len < 1 || len > 8)
+ goto out;
+ if (len < minimum_console_loglevel)
+ len = minimum_console_loglevel;
+ console_loglevel = len;
+ /* Implicitly re-enable logging to console */
+ saved_console_loglevel = -1;
+ error = 0;
+ break;
+ /* Number of chars in the log buffer */
+ case SYSLOG_ACTION_SIZE_UNREAD:
+ raw_spin_lock_irq(&printk_logbuf_lock);
+ if (printk_syslog_seq < printk_log_first_seq) {
+ /* messages are gone, move to first one */
+ printk_syslog_seq = printk_log_first_seq;
+ printk_syslog_idx = printk_log_first_idx;
+ printk_syslog_prev = 0;
+ printk_syslog_partial = 0;
+ }
+ if (from_file) {
+ /*
+ * Short-cut for poll(/"proc/kmsg") which simply checks
+ * for pending data, not the size; return the count of
+ * records, not the length.
+ */
+ error = printk_log_next_idx - printk_syslog_idx;
+ } else {
+ u64 seq = printk_syslog_seq;
+ u32 idx = printk_syslog_idx;
+ enum printk_log_flags prev = printk_syslog_prev;
+
+ error = 0;
+ while (seq < printk_log_next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+
+ error += printk_msg_print_text(msg, prev, true, NULL, 0);
+ idx = printk_log_next(idx);
+ seq++;
+ prev = msg->flags;
+ }
+ error -= printk_syslog_partial;
+ }
+ raw_spin_unlock_irq(&printk_logbuf_lock);
+ break;
+ /* Size of the log buffer */
+ case SYSLOG_ACTION_SIZE_BUFFER:
+ error = printk_log_buf_len;
+ break;
+ default:
+ error = -EINVAL;
+ break;
+ }
+out:
+ return error;
+}
+
+SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
+{
+ return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
+}
+
+#endif
diff --git a/kernel/printk/printk_syslog.h b/kernel/printk/printk_syslog.h
new file mode 100644
index 0000000..dce93c0
--- /dev/null
+++ b/kernel/printk/printk_syslog.h
@@ -0,0 +1,12 @@
+#ifndef _PRINTK_SYSLOG_H
+#define _PRINTK_SYSLOG_H
+
+#include <linux/syscalls.h>
+#include <linux/syslog.h>
+
+/* the next printk record to read by syslog(READ) or /proc/kmsg */
+extern u64 printk_syslog_seq;
+extern u32 printk_syslog_idx;
+extern enum printk_log_flags printk_syslog_prev;
+
+#endif
--
1.7.10.4

2012-10-17 06:10:29

by Joe Perches

[permalink] [raw]
Subject: [PATCH 23/23] printk: Move kmsg_dump functions to separate file

Generic restructuring.

Create kmsg_dump.c, add to Makefile and remove from printk.c

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/Makefile | 1 +
kernel/printk/kmsg_dump.c | 328 +++++++++++++++++++++++++++++++++++++++++++++
kernel/printk/printk.c | 318 -------------------------------------------
3 files changed, 329 insertions(+), 318 deletions(-)
create mode 100644 kernel/printk/kmsg_dump.c

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index 7947661..b0072b0 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -2,4 +2,5 @@ obj-y = printk.o
obj-y += printk_log.o
obj-y += devkmsg.o
obj-y += printk_syslog.o
+obj-y += kmsg_dump.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/kmsg_dump.c b/kernel/printk/kmsg_dump.c
new file mode 100644
index 0000000..7962172
--- /dev/null
+++ b/kernel/printk/kmsg_dump.c
@@ -0,0 +1,328 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/moduleparam.h>
+#include <linux/export.h>
+#include <linux/kmsg_dump.h>
+#include <linux/rculist.h>
+#include <linux/stat.h>
+
+#include "printk_log.h"
+
+static DEFINE_SPINLOCK(dump_list_lock);
+static LIST_HEAD(dump_list);
+
+/**
+ * kmsg_dump_register - register a kernel log dumper.
+ * @dumper: pointer to the kmsg_dumper structure
+ *
+ * Adds a kernel log dumper to the system. The dump callback in the
+ * structure will be called when the kernel oopses or panics and must be
+ * set. Returns zero on success and %-EINVAL or %-EBUSY otherwise.
+ */
+int kmsg_dump_register(struct kmsg_dumper *dumper)
+{
+ unsigned long flags;
+ int err = -EBUSY;
+
+ /* The dump callback needs to be set */
+ if (!dumper->dump)
+ return -EINVAL;
+
+ spin_lock_irqsave(&dump_list_lock, flags);
+ /* Don't allow registering multiple times */
+ if (!dumper->registered) {
+ dumper->registered = 1;
+ list_add_tail_rcu(&dumper->list, &dump_list);
+ err = 0;
+ }
+ spin_unlock_irqrestore(&dump_list_lock, flags);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_register);
+
+/**
+ * kmsg_dump_unregister - unregister a kmsg dumper.
+ * @dumper: pointer to the kmsg_dumper structure
+ *
+ * Removes a dump device from the system. Returns zero on success and
+ * %-EINVAL otherwise.
+ */
+int kmsg_dump_unregister(struct kmsg_dumper *dumper)
+{
+ unsigned long flags;
+ int err = -EINVAL;
+
+ spin_lock_irqsave(&dump_list_lock, flags);
+ if (dumper->registered) {
+ dumper->registered = 0;
+ list_del_rcu(&dumper->list);
+ err = 0;
+ }
+ spin_unlock_irqrestore(&dump_list_lock, flags);
+ synchronize_rcu();
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
+
+static bool always_kmsg_dump;
+module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR);
+
+/**
+ * kmsg_dump - dump kernel log to kernel message dumpers.
+ * @reason: the reason (oops, panic etc) for dumping
+ *
+ * Call each of the registered dumper's dump() callback, which can
+ * retrieve the kmsg records with kmsg_dump_get_line() or
+ * kmsg_dump_get_buffer().
+ */
+void kmsg_dump(enum kmsg_dump_reason reason)
+{
+ struct kmsg_dumper *dumper;
+ unsigned long flags;
+
+ if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
+ return;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(dumper, &dump_list, list) {
+ if (dumper->max_reason && reason > dumper->max_reason)
+ continue;
+
+ /* initialize iterator with data about the stored records */
+ dumper->active = true;
+
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
+ dumper->cur_seq = printk_log_clear_seq;
+ dumper->cur_idx = printk_log_clear_idx;
+ dumper->next_seq = printk_log_next_seq;
+ dumper->next_idx = printk_log_next_idx;
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
+
+ /* invoke dumper which will iterate over records */
+ dumper->dump(dumper, reason);
+
+ /* reset iterator */
+ dumper->active = false;
+ }
+ rcu_read_unlock();
+}
+
+/**
+ * kmsg_dump_get_line_nolock - retrieve one kmsg log line (unlocked version)
+ * @dumper: registered kmsg dumper
+ * @syslog: include the "<4>" prefixes
+ * @line: buffer to copy the line to
+ * @size: maximum size of the buffer
+ * @len: length of line placed into buffer
+ *
+ * Start at the beginning of the kmsg buffer, with the oldest kmsg
+ * record, and copy one record into the provided buffer.
+ *
+ * Consecutive calls will return the next available record moving
+ * towards the end of the buffer with the youngest messages.
+ *
+ * A return value of FALSE indicates that there are no more records to
+ * read.
+ *
+ * The function is similar to kmsg_dump_get_line(), but grabs no locks.
+ */
+bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
+ char *line, size_t size, size_t *len)
+{
+ struct printk_log *msg;
+ size_t l = 0;
+ bool ret = false;
+
+ if (!dumper->active)
+ goto out;
+
+ if (dumper->cur_seq < printk_log_first_seq) {
+ /* messages are gone, move to first available one */
+ dumper->cur_seq = printk_log_first_seq;
+ dumper->cur_idx = printk_log_first_idx;
+ }
+
+ /* last entry */
+ if (dumper->cur_seq >= printk_log_next_seq)
+ goto out;
+
+ msg = printk_log_from_idx(dumper->cur_idx);
+ l = printk_msg_print_text(msg, 0, syslog, line, size);
+
+ dumper->cur_idx = printk_log_next(dumper->cur_idx);
+ dumper->cur_seq++;
+ ret = true;
+out:
+ if (len)
+ *len = l;
+ return ret;
+}
+
+/**
+ * kmsg_dump_get_line - retrieve one kmsg log line
+ * @dumper: registered kmsg dumper
+ * @syslog: include the "<4>" prefixes
+ * @line: buffer to copy the line to
+ * @size: maximum size of the buffer
+ * @len: length of line placed into buffer
+ *
+ * Start at the beginning of the kmsg buffer, with the oldest kmsg
+ * record, and copy one record into the provided buffer.
+ *
+ * Consecutive calls will return the next available record moving
+ * towards the end of the buffer with the youngest messages.
+ *
+ * A return value of FALSE indicates that there are no more records to
+ * read.
+ */
+bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
+ char *line, size_t size, size_t *len)
+{
+ unsigned long flags;
+ bool ret;
+
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
+ ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_get_line);
+
+/**
+ * kmsg_dump_get_buffer - copy kmsg log lines
+ * @dumper: registered kmsg dumper
+ * @syslog: include the "<4>" prefixes
+ * @buf: buffer to copy the line to
+ * @size: maximum size of the buffer
+ * @len: length of line placed into buffer
+ *
+ * Start at the end of the kmsg buffer and fill the provided buffer
+ * with as many of the the *youngest* kmsg records that fit into it.
+ * If the buffer is large enough, all available kmsg records will be
+ * copied with a single call.
+ *
+ * Consecutive calls will fill the buffer with the next block of
+ * available older records, not including the earlier retrieved ones.
+ *
+ * A return value of FALSE indicates that there are no more records to
+ * read.
+ */
+bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
+ char *buf, size_t size, size_t *len)
+{
+ unsigned long flags;
+ u64 seq;
+ u32 idx;
+ u64 next_seq;
+ u32 next_idx;
+ enum printk_log_flags prev;
+ size_t l = 0;
+ bool ret = false;
+
+ if (!dumper->active)
+ goto out;
+
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
+ if (dumper->cur_seq < printk_log_first_seq) {
+ /* messages are gone, move to first available one */
+ dumper->cur_seq = printk_log_first_seq;
+ dumper->cur_idx = printk_log_first_idx;
+ }
+
+ /* last entry */
+ if (dumper->cur_seq >= dumper->next_seq) {
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
+ goto out;
+ }
+
+ /* calculate length of entire buffer */
+ seq = dumper->cur_seq;
+ idx = dumper->cur_idx;
+ prev = 0;
+ while (seq < dumper->next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+
+ l += printk_msg_print_text(msg, prev, true, NULL, 0);
+ idx = printk_log_next(idx);
+ seq++;
+ prev = msg->flags;
+ }
+
+ /* move first record forward until length fits into the buffer */
+ seq = dumper->cur_seq;
+ idx = dumper->cur_idx;
+ prev = 0;
+ while (l > size && seq < dumper->next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+
+ l -= printk_msg_print_text(msg, prev, true, NULL, 0);
+ idx = printk_log_next(idx);
+ seq++;
+ prev = msg->flags;
+ }
+
+ /* last message in next interation */
+ next_seq = seq;
+ next_idx = idx;
+
+ l = 0;
+ prev = 0;
+ while (seq < dumper->next_seq) {
+ struct printk_log *msg = printk_log_from_idx(idx);
+
+ l += printk_msg_print_text(msg, prev, syslog, buf + l, size - l);
+ idx = printk_log_next(idx);
+ seq++;
+ prev = msg->flags;
+ }
+
+ dumper->next_seq = next_seq;
+ dumper->next_idx = next_idx;
+ ret = true;
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
+out:
+ if (len)
+ *len = l;
+ return ret;
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
+
+/**
+ * kmsg_dump_rewind_nolock - reset the interator (unlocked version)
+ * @dumper: registered kmsg dumper
+ *
+ * Reset the dumper's iterator so that kmsg_dump_get_line() and
+ * kmsg_dump_get_buffer() can be called again and used multiple
+ * times within the same dumper.dump() callback.
+ *
+ * The function is similar to kmsg_dump_rewind(), but grabs no locks.
+ */
+void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
+{
+ dumper->cur_seq = printk_log_clear_seq;
+ dumper->cur_idx = printk_log_clear_idx;
+ dumper->next_seq = printk_log_next_seq;
+ dumper->next_idx = printk_log_next_idx;
+}
+
+/**
+ * kmsg_dump_rewind - reset the interator
+ * @dumper: registered kmsg dumper
+ *
+ * Reset the dumper's iterator so that kmsg_dump_get_line() and
+ * kmsg_dump_get_buffer() can be called again and used multiple
+ * times within the same dumper.dump() callback.
+ */
+void kmsg_dump_rewind(struct kmsg_dumper *dumper)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
+ kmsg_dump_rewind_nolock(dumper);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index cba438e..b4187f3 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -33,7 +33,6 @@
#include <linux/kexec.h>
#include <linux/kdb.h>
#include <linux/ratelimit.h>
-#include <linux/kmsg_dump.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/rculist.h>
@@ -1513,321 +1512,4 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies,
}
EXPORT_SYMBOL(printk_timed_ratelimit);

-static DEFINE_SPINLOCK(dump_list_lock);
-static LIST_HEAD(dump_list);
-
-/**
- * kmsg_dump_register - register a kernel log dumper.
- * @dumper: pointer to the kmsg_dumper structure
- *
- * Adds a kernel log dumper to the system. The dump callback in the
- * structure will be called when the kernel oopses or panics and must be
- * set. Returns zero on success and %-EINVAL or %-EBUSY otherwise.
- */
-int kmsg_dump_register(struct kmsg_dumper *dumper)
-{
- unsigned long flags;
- int err = -EBUSY;
-
- /* The dump callback needs to be set */
- if (!dumper->dump)
- return -EINVAL;
-
- spin_lock_irqsave(&dump_list_lock, flags);
- /* Don't allow registering multiple times */
- if (!dumper->registered) {
- dumper->registered = 1;
- list_add_tail_rcu(&dumper->list, &dump_list);
- err = 0;
- }
- spin_unlock_irqrestore(&dump_list_lock, flags);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(kmsg_dump_register);
-
-/**
- * kmsg_dump_unregister - unregister a kmsg dumper.
- * @dumper: pointer to the kmsg_dumper structure
- *
- * Removes a dump device from the system. Returns zero on success and
- * %-EINVAL otherwise.
- */
-int kmsg_dump_unregister(struct kmsg_dumper *dumper)
-{
- unsigned long flags;
- int err = -EINVAL;
-
- spin_lock_irqsave(&dump_list_lock, flags);
- if (dumper->registered) {
- dumper->registered = 0;
- list_del_rcu(&dumper->list);
- err = 0;
- }
- spin_unlock_irqrestore(&dump_list_lock, flags);
- synchronize_rcu();
-
- return err;
-}
-EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
-
-static bool always_kmsg_dump;
-module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR);
-
-/**
- * kmsg_dump - dump kernel log to kernel message dumpers.
- * @reason: the reason (oops, panic etc) for dumping
- *
- * Call each of the registered dumper's dump() callback, which can
- * retrieve the kmsg records with kmsg_dump_get_line() or
- * kmsg_dump_get_buffer().
- */
-void kmsg_dump(enum kmsg_dump_reason reason)
-{
- struct kmsg_dumper *dumper;
- unsigned long flags;
-
- if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
- return;
-
- rcu_read_lock();
- list_for_each_entry_rcu(dumper, &dump_list, list) {
- if (dumper->max_reason && reason > dumper->max_reason)
- continue;
-
- /* initialize iterator with data about the stored records */
- dumper->active = true;
-
- raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
- dumper->cur_seq = printk_log_clear_seq;
- dumper->cur_idx = printk_log_clear_idx;
- dumper->next_seq = printk_log_next_seq;
- dumper->next_idx = printk_log_next_idx;
- raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
-
- /* invoke dumper which will iterate over records */
- dumper->dump(dumper, reason);
-
- /* reset iterator */
- dumper->active = false;
- }
- rcu_read_unlock();
-}
-
-/**
- * kmsg_dump_get_line_nolock - retrieve one kmsg log line (unlocked version)
- * @dumper: registered kmsg dumper
- * @syslog: include the "<4>" prefixes
- * @line: buffer to copy the line to
- * @size: maximum size of the buffer
- * @len: length of line placed into buffer
- *
- * Start at the beginning of the kmsg buffer, with the oldest kmsg
- * record, and copy one record into the provided buffer.
- *
- * Consecutive calls will return the next available record moving
- * towards the end of the buffer with the youngest messages.
- *
- * A return value of FALSE indicates that there are no more records to
- * read.
- *
- * The function is similar to kmsg_dump_get_line(), but grabs no locks.
- */
-bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
- char *line, size_t size, size_t *len)
-{
- struct printk_log *msg;
- size_t l = 0;
- bool ret = false;
-
- if (!dumper->active)
- goto out;
-
- if (dumper->cur_seq < printk_log_first_seq) {
- /* messages are gone, move to first available one */
- dumper->cur_seq = printk_log_first_seq;
- dumper->cur_idx = printk_log_first_idx;
- }
-
- /* last entry */
- if (dumper->cur_seq >= printk_log_next_seq)
- goto out;
-
- msg = printk_log_from_idx(dumper->cur_idx);
- l = printk_msg_print_text(msg, 0, syslog, line, size);
-
- dumper->cur_idx = printk_log_next(dumper->cur_idx);
- dumper->cur_seq++;
- ret = true;
-out:
- if (len)
- *len = l;
- return ret;
-}
-
-/**
- * kmsg_dump_get_line - retrieve one kmsg log line
- * @dumper: registered kmsg dumper
- * @syslog: include the "<4>" prefixes
- * @line: buffer to copy the line to
- * @size: maximum size of the buffer
- * @len: length of line placed into buffer
- *
- * Start at the beginning of the kmsg buffer, with the oldest kmsg
- * record, and copy one record into the provided buffer.
- *
- * Consecutive calls will return the next available record moving
- * towards the end of the buffer with the youngest messages.
- *
- * A return value of FALSE indicates that there are no more records to
- * read.
- */
-bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
- char *line, size_t size, size_t *len)
-{
- unsigned long flags;
- bool ret;
-
- raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
- ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len);
- raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(kmsg_dump_get_line);
-
-/**
- * kmsg_dump_get_buffer - copy kmsg log lines
- * @dumper: registered kmsg dumper
- * @syslog: include the "<4>" prefixes
- * @buf: buffer to copy the line to
- * @size: maximum size of the buffer
- * @len: length of line placed into buffer
- *
- * Start at the end of the kmsg buffer and fill the provided buffer
- * with as many of the the *youngest* kmsg records that fit into it.
- * If the buffer is large enough, all available kmsg records will be
- * copied with a single call.
- *
- * Consecutive calls will fill the buffer with the next block of
- * available older records, not including the earlier retrieved ones.
- *
- * A return value of FALSE indicates that there are no more records to
- * read.
- */
-bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
- char *buf, size_t size, size_t *len)
-{
- unsigned long flags;
- u64 seq;
- u32 idx;
- u64 next_seq;
- u32 next_idx;
- enum printk_log_flags prev;
- size_t l = 0;
- bool ret = false;
-
- if (!dumper->active)
- goto out;
-
- raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
- if (dumper->cur_seq < printk_log_first_seq) {
- /* messages are gone, move to first available one */
- dumper->cur_seq = printk_log_first_seq;
- dumper->cur_idx = printk_log_first_idx;
- }
-
- /* last entry */
- if (dumper->cur_seq >= dumper->next_seq) {
- raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
- goto out;
- }
-
- /* calculate length of entire buffer */
- seq = dumper->cur_seq;
- idx = dumper->cur_idx;
- prev = 0;
- while (seq < dumper->next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
-
- l += printk_msg_print_text(msg, prev, true, NULL, 0);
- idx = printk_log_next(idx);
- seq++;
- prev = msg->flags;
- }
-
- /* move first record forward until length fits into the buffer */
- seq = dumper->cur_seq;
- idx = dumper->cur_idx;
- prev = 0;
- while (l > size && seq < dumper->next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
-
- l -= printk_msg_print_text(msg, prev, true, NULL, 0);
- idx = printk_log_next(idx);
- seq++;
- prev = msg->flags;
- }
-
- /* last message in next interation */
- next_seq = seq;
- next_idx = idx;
-
- l = 0;
- prev = 0;
- while (seq < dumper->next_seq) {
- struct printk_log *msg = printk_log_from_idx(idx);
-
- l += printk_msg_print_text(msg, prev, syslog, buf + l, size - l);
- idx = printk_log_next(idx);
- seq++;
- prev = msg->flags;
- }
-
- dumper->next_seq = next_seq;
- dumper->next_idx = next_idx;
- ret = true;
- raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
-out:
- if (len)
- *len = l;
- return ret;
-}
-EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
-
-/**
- * kmsg_dump_rewind_nolock - reset the interator (unlocked version)
- * @dumper: registered kmsg dumper
- *
- * Reset the dumper's iterator so that kmsg_dump_get_line() and
- * kmsg_dump_get_buffer() can be called again and used multiple
- * times within the same dumper.dump() callback.
- *
- * The function is similar to kmsg_dump_rewind(), but grabs no locks.
- */
-void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
-{
- dumper->cur_seq = printk_log_clear_seq;
- dumper->cur_idx = printk_log_clear_idx;
- dumper->next_seq = printk_log_next_seq;
- dumper->next_idx = printk_log_next_idx;
-}
-
-/**
- * kmsg_dump_rewind - reset the interator
- * @dumper: registered kmsg dumper
- *
- * Reset the dumper's iterator so that kmsg_dump_get_line() and
- * kmsg_dump_get_buffer() can be called again and used multiple
- * times within the same dumper.dump() callback.
- */
-void kmsg_dump_rewind(struct kmsg_dumper *dumper)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
- kmsg_dump_rewind_nolock(dumper);
- raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
-}
-EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
#endif
--
1.7.10.4

2012-10-17 06:08:41

by Joe Perches

[permalink] [raw]
Subject: [PATCH 11/23] printk: Rename logbuf_lock to printk_logbuf_lock

Make this generic name more specific to the printk
subsystem and allow it to become non-static.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 102 ++++++++++++++++++++++++------------------------
1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c87472b..709472f 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -205,10 +205,10 @@ struct printk_log {
};

/*
- * The logbuf_lock protects kmsg buffer, indices, counters. It is also
+ * The printk_logbuf_lock protects kmsg buffer, indices, counters. It is also
* used in interesting ways to provide interlocking in console_unlock();
*/
-static DEFINE_RAW_SPINLOCK(logbuf_lock);
+static DEFINE_RAW_SPINLOCK(printk_logbuf_lock);

#ifdef CONFIG_PRINTK
/* the next printk record to read by syslog(READ) or /proc/kmsg */
@@ -248,7 +248,7 @@ static char __printk_log_buf[__PRINTK_LOG_BUF_LEN] __aligned(LOG_ALIGN);
static char *printk_log_buf = __printk_log_buf;
static u32 printk_log_buf_len = __PRINTK_LOG_BUF_LEN;

-/* cpu currently holding logbuf_lock */
+/* cpu currently holding printk_logbuf_lock */
static volatile unsigned int logbuf_cpu = UINT_MAX;

/* human readable text of the record */
@@ -438,20 +438,20 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
ret = mutex_lock_interruptible(&user->lock);
if (ret)
return ret;
- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
while (user->seq == printk_log_next_seq) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
goto out;
}

- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
ret = wait_event_interruptible(printk_log_wait,
user->seq != printk_log_next_seq);
if (ret)
goto out;
- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
}

if (user->seq < printk_log_first_seq) {
@@ -459,7 +459,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
user->idx = printk_log_first_idx;
user->seq = printk_log_first_seq;
ret = -EPIPE;
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
goto out;
}

@@ -526,7 +526,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,

user->idx = printk_log_next(user->idx);
user->seq++;
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);

if (len > count) {
ret = -EINVAL;
@@ -553,7 +553,7 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
if (offset)
return -ESPIPE;

- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
switch (whence) {
case SEEK_SET:
/* the first record */
@@ -577,7 +577,7 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
default:
ret = -EINVAL;
}
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
return ret;
}

@@ -591,14 +591,14 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait)

poll_wait(file, &printk_log_wait, wait);

- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
if (user->seq < printk_log_next_seq) {
/* return error when data has vanished underneath us */
if (user->seq < printk_log_first_seq)
ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI;
ret = POLLIN|POLLRDNORM;
}
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);

return ret;
}
@@ -622,10 +622,10 @@ static int devkmsg_open(struct inode *inode, struct file *file)

mutex_init(&user->lock);

- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
user->idx = printk_log_first_idx;
user->seq = printk_log_first_seq;
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);

file->private_data = user;
return 0;
@@ -722,13 +722,13 @@ void __init setup_log_buf(int early)
return;
}

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
printk_log_buf_len = new_printk_log_buf_len;
printk_log_buf = new_printk_log_buf;
new_printk_log_buf_len = 0;
free = __PRINTK_LOG_BUF_LEN - printk_log_next_idx;
memcpy(printk_log_buf, __printk_log_buf, __PRINTK_LOG_BUF_LEN);
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);

pr_info("printk_log_buf_len: %d\n", printk_log_buf_len);
pr_info("early log buf free: %d(%d%%)\n",
@@ -946,7 +946,7 @@ static int syslog_print(char __user *buf, int size)
size_t n;
size_t skip;

- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
if (syslog_seq < printk_log_first_seq) {
/* messages are gone, move to first one */
syslog_seq = printk_log_first_seq;
@@ -955,7 +955,7 @@ static int syslog_print(char __user *buf, int size)
syslog_partial = 0;
}
if (syslog_seq == printk_log_next_seq) {
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
break;
}

@@ -976,7 +976,7 @@ static int syslog_print(char __user *buf, int size)
syslog_partial += n;
} else
n = 0;
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);

if (!n)
break;
@@ -1005,7 +1005,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
if (!text)
return -ENOMEM;

- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
if (buf) {
u64 next_seq;
u64 seq;
@@ -1066,12 +1066,12 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
seq++;
prev = msg->flags;

- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
if (copy_to_user(buf + len, text, textlen))
len = -EFAULT;
else
len += textlen;
- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);

if (seq < printk_log_first_seq) {
/* messages are gone, move to next one */
@@ -1086,7 +1086,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
clear_seq = printk_log_next_seq;
clear_idx = printk_log_next_idx;
}
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);

kfree(text);
return len;
@@ -1177,7 +1177,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
break;
/* Number of chars in the log buffer */
case SYSLOG_ACTION_SIZE_UNREAD:
- raw_spin_lock_irq(&logbuf_lock);
+ raw_spin_lock_irq(&printk_logbuf_lock);
if (syslog_seq < printk_log_first_seq) {
/* messages are gone, move to first one */
syslog_seq = printk_log_first_seq;
@@ -1208,7 +1208,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
}
error -= syslog_partial;
}
- raw_spin_unlock_irq(&logbuf_lock);
+ raw_spin_unlock_irq(&printk_logbuf_lock);
break;
/* Size of the log buffer */
case SYSLOG_ACTION_SIZE_BUFFER:
@@ -1289,7 +1289,7 @@ static void zap_locks(void)

debug_locks_off();
/* If a crash is occurring, make sure we can't deadlock */
- raw_spin_lock_init(&logbuf_lock);
+ raw_spin_lock_init(&printk_logbuf_lock);
/* And make sure that we print immediately */
sema_init(&console_sem, 1);
}
@@ -1325,12 +1325,12 @@ static inline int can_use_console(unsigned int cpu)
* console_lock held, and 'console_locked' set) if it
* is successful, false otherwise.
*
- * This gets called with the 'logbuf_lock' spinlock held and
+ * This gets called with the 'printk_logbuf_lock' spinlock held and
* interrupts disabled. It should return with 'lockbuf_lock'
* released but interrupts still disabled.
*/
static int console_trylock_for_printk(unsigned int cpu)
- __releases(&logbuf_lock)
+ __releases(&printk_logbuf_lock)
{
int retval = 0, wake = 0;

@@ -1352,7 +1352,7 @@ static int console_trylock_for_printk(unsigned int cpu)
logbuf_cpu = UINT_MAX;
if (wake)
up(&console_sem);
- raw_spin_unlock(&logbuf_lock);
+ raw_spin_unlock(&printk_logbuf_lock);
return retval;
}

@@ -1513,7 +1513,7 @@ asmlinkage int vprintk_emit(int facility, int level,
}

lockdep_off();
- raw_spin_lock(&logbuf_lock);
+ raw_spin_lock(&printk_logbuf_lock);
logbuf_cpu = this_cpu;

if (recursion_bug) {
@@ -1603,7 +1603,7 @@ asmlinkage int vprintk_emit(int facility, int level,
* The release will print out buffers and wake up /dev/kmsg and syslog()
* users.
*
- * The console_trylock_for_printk() function will release 'logbuf_lock'
+ * The console_trylock_for_printk() function will release 'printk_logbuf_lock'
* regardless of whether it actually gets the console semaphore or not.
*/
if (console_trylock_for_printk(this_cpu))
@@ -1970,7 +1970,7 @@ static void console_cont_flush(char *text, size_t size)
unsigned long flags;
size_t len;

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);

if (!cont.len)
goto out;
@@ -1984,14 +1984,14 @@ static void console_cont_flush(char *text, size_t size)
goto out;

len = cont_print_text(text, size);
- raw_spin_unlock(&logbuf_lock);
+ raw_spin_unlock(&printk_logbuf_lock);
stop_critical_timings();
call_console_drivers(cont.level, text, len);
start_critical_timings();
local_irq_restore(flags);
return;
out:
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
}

/**
@@ -2031,7 +2031,7 @@ again:
size_t len;
int level;

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
if (seen_seq != printk_log_next_seq) {
wake_klogd = true;
seen_seq = printk_log_next_seq;
@@ -2071,7 +2071,7 @@ skip:
console_idx = printk_log_next(console_idx);
console_seq++;
console_prev = msg->flags;
- raw_spin_unlock(&logbuf_lock);
+ raw_spin_unlock(&printk_logbuf_lock);

stop_critical_timings(); /* don't trace print latency */
call_console_drivers(level, text, len);
@@ -2084,7 +2084,7 @@ skip:
if (unlikely(exclusive_console))
exclusive_console = NULL;

- raw_spin_unlock(&logbuf_lock);
+ raw_spin_unlock(&printk_logbuf_lock);

up(&console_sem);

@@ -2094,9 +2094,9 @@ skip:
* there's a new owner and the console_unlock() from them will do the
* flush, no worries.
*/
- raw_spin_lock(&logbuf_lock);
+ raw_spin_lock(&printk_logbuf_lock);
retry = console_seq != printk_log_next_seq;
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);

if (retry && console_trylock())
goto again;
@@ -2326,11 +2326,11 @@ void register_console(struct console *newcon)
* console_unlock(); will print out the buffered messages
* for us.
*/
- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
console_seq = syslog_seq;
console_idx = syslog_idx;
console_prev = syslog_prev;
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
/*
* We're about to replay the log buffer. Only do this to the
* just-registered console to avoid excessive message spam to
@@ -2565,12 +2565,12 @@ void kmsg_dump(enum kmsg_dump_reason reason)
/* initialize iterator with data about the stored records */
dumper->active = true;

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
dumper->cur_seq = clear_seq;
dumper->cur_idx = clear_idx;
dumper->next_seq = printk_log_next_seq;
dumper->next_idx = printk_log_next_idx;
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);

/* invoke dumper which will iterate over records */
dumper->dump(dumper, reason);
@@ -2655,9 +2655,9 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
unsigned long flags;
bool ret;

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len);
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);

return ret;
}
@@ -2697,7 +2697,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
if (!dumper->active)
goto out;

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
if (dumper->cur_seq < printk_log_first_seq) {
/* messages are gone, move to first available one */
dumper->cur_seq = printk_log_first_seq;
@@ -2706,7 +2706,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,

/* last entry */
if (dumper->cur_seq >= dumper->next_seq) {
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
goto out;
}

@@ -2754,7 +2754,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
dumper->next_seq = next_seq;
dumper->next_idx = next_idx;
ret = true;
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
out:
if (len)
*len = l;
@@ -2792,9 +2792,9 @@ void kmsg_dump_rewind(struct kmsg_dumper *dumper)
{
unsigned long flags;

- raw_spin_lock_irqsave(&logbuf_lock, flags);
+ raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
kmsg_dump_rewind_nolock(dumper);
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+ raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
}
EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
#endif
--
1.7.10.4

2012-10-17 06:08:40

by Joe Perches

[permalink] [raw]
Subject: [PATCH 12/23] printk: Rename clear_seq and clear_idx variables

Make these variables more specific to the printk log subsystem
adding prefix printk_log_. This allows them to become non-static.

Signed-off-by: Joe Perches <[email protected]>
---
kernel/printk/printk.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 709472f..3785ac4 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -231,8 +231,8 @@ static u32 console_idx;
static enum printk_log_flags console_prev;

/* the next printk record to read after the last 'clear' command */
-static u64 clear_seq;
-static u32 clear_idx;
+static u64 printk_log_clear_seq;
+static u32 printk_log_clear_idx;

#define PREFIX_MAX 32
#define LOG_LINE_MAX 1024 - PREFIX_MAX
@@ -566,8 +566,8 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
* like issued by 'dmesg -c'. Reading /dev/kmsg itself
* changes no global state, and does not clear anything.
*/
- user->idx = clear_idx;
- user->seq = clear_seq;
+ user->idx = printk_log_clear_idx;
+ user->seq = printk_log_clear_seq;
break;
case SEEK_END:
/* after the last record */
@@ -1012,18 +1012,18 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
u32 idx;
enum printk_log_flags prev;

- if (clear_seq < printk_log_first_seq) {
+ if (printk_log_clear_seq < printk_log_first_seq) {
/* messages are gone, move to first available one */
- clear_seq = printk_log_first_seq;
- clear_idx = printk_log_first_idx;
+ printk_log_clear_seq = printk_log_first_seq;
+ printk_log_clear_idx = printk_log_first_idx;
}

/*
* Find first record that fits, including all following records,
* into the user-provided buffer for this dump.
*/
- seq = clear_seq;
- idx = clear_idx;
+ seq = printk_log_clear_seq;
+ idx = printk_log_clear_idx;
prev = 0;
while (seq < printk_log_next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);
@@ -1035,8 +1035,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
}

/* move first record forward until length fits into the buffer */
- seq = clear_seq;
- idx = clear_idx;
+ seq = printk_log_clear_seq;
+ idx = printk_log_clear_idx;
prev = 0;
while (len > size && seq < printk_log_next_seq) {
struct printk_log *msg = printk_log_from_idx(idx);
@@ -1083,8 +1083,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
}

if (clear) {
- clear_seq = printk_log_next_seq;
- clear_idx = printk_log_next_idx;
+ printk_log_clear_seq = printk_log_next_seq;
+ printk_log_clear_idx = printk_log_next_idx;
}
raw_spin_unlock_irq(&printk_logbuf_lock);

@@ -2566,8 +2566,8 @@ void kmsg_dump(enum kmsg_dump_reason reason)
dumper->active = true;

raw_spin_lock_irqsave(&printk_logbuf_lock, flags);
- dumper->cur_seq = clear_seq;
- dumper->cur_idx = clear_idx;
+ dumper->cur_seq = printk_log_clear_seq;
+ dumper->cur_idx = printk_log_clear_idx;
dumper->next_seq = printk_log_next_seq;
dumper->next_idx = printk_log_next_idx;
raw_spin_unlock_irqrestore(&printk_logbuf_lock, flags);
@@ -2774,8 +2774,8 @@ EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
*/
void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
{
- dumper->cur_seq = clear_seq;
- dumper->cur_idx = clear_idx;
+ dumper->cur_seq = printk_log_clear_seq;
+ dumper->cur_idx = printk_log_clear_idx;
dumper->next_seq = printk_log_next_seq;
dumper->next_idx = printk_log_next_idx;
}
--
1.7.10.4

2012-10-17 23:55:28

by Samuel Thibault

[permalink] [raw]
Subject: Re: [PATCH 03/23] printk: Move braille console support into separate braille.[ch] files

Joe Perches, le Tue 16 Oct 2012 23:06:07 -0700, a ?crit :
> Create files with prototypes and static inlines for braille
> support. Make braille_console functions return 1 on success.
>
> cc: Samuel Thibault <[email protected]>
> Signed-off-by: Joe Perches <[email protected]>

Acked-by: Samuel Thibault <[email protected]>

> ---
> drivers/accessibility/braille/braille_console.c | 9 ++++-
> kernel/printk/Makefile | 1 +
> kernel/printk/braille.c | 48 +++++++++++++++++++++++
> kernel/printk/braille.h | 48 +++++++++++++++++++++++
> kernel/printk/printk.c | 44 ++++++---------------
> 5 files changed, 117 insertions(+), 33 deletions(-)
> create mode 100644 kernel/printk/braille.c
> create mode 100644 kernel/printk/braille.h
>
> diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
> index d21167b..dc34a5b 100644
> --- a/drivers/accessibility/braille/braille_console.c
> +++ b/drivers/accessibility/braille/braille_console.c
> @@ -359,6 +359,9 @@ int braille_register_console(struct console *console, int index,
> char *console_options, char *braille_options)
> {
> int ret;
> +
> + if (!(console->flags & CON_BRL))
> + return 0;
> if (!console_options)
> /* Only support VisioBraille for now */
> console_options = "57600o8";
> @@ -374,15 +377,17 @@ int braille_register_console(struct console *console, int index,
> braille_co = console;
> register_keyboard_notifier(&keyboard_notifier_block);
> register_vt_notifier(&vt_notifier_block);
> - return 0;
> + return 1;
> }
>
> int braille_unregister_console(struct console *console)
> {
> if (braille_co != console)
> return -EINVAL;
> + if (!(console->flags & CON_BRL))
> + return 0;
> unregister_keyboard_notifier(&keyboard_notifier_block);
> unregister_vt_notifier(&vt_notifier_block);
> braille_co = NULL;
> - return 0;
> + return 1;
> }
> diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
> index 36d306d..85405bd 100644
> --- a/kernel/printk/Makefile
> +++ b/kernel/printk/Makefile
> @@ -1 +1,2 @@
> obj-y = printk.o
> +obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
> diff --git a/kernel/printk/braille.c b/kernel/printk/braille.c
> new file mode 100644
> index 0000000..b51087f
> --- /dev/null
> +++ b/kernel/printk/braille.c
> @@ -0,0 +1,48 @@
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/console.h>
> +#include <linux/string.h>
> +
> +#include "console_cmdline.h"
> +#include "braille.h"
> +
> +char *_braille_console_setup(char **str, char **brl_options)
> +{
> + if (!memcmp(*str, "brl,", 4)) {
> + *brl_options = "";
> + *str += 4;
> + } else if (!memcmp(str, "brl=", 4)) {
> + *brl_options = *str + 4;
> + *str = strchr(*brl_options, ',');
> + if (!*str)
> + pr_err("need port name after brl=\n");
> + else
> + *((*str)++) = 0;
> + }
> +
> + return *str;
> +}
> +
> +int
> +_braille_register_console(struct console *console, struct console_cmdline *c)
> +{
> + int rtn = 0;
> +
> + if (c->brl_options) {
> + console->flags |= CON_BRL;
> + rtn = braille_register_console(console, c->index, c->options,
> + c->brl_options);
> + }
> +
> + return rtn;
> +}
> +
> +int
> +_braille_unregister_console(struct console *console)
> +{
> + if (console->flags & CON_BRL)
> + return braille_unregister_console(console);
> +
> + return 0;
> +}
> diff --git a/kernel/printk/braille.h b/kernel/printk/braille.h
> new file mode 100644
> index 0000000..d2e6bc3
> --- /dev/null
> +++ b/kernel/printk/braille.h
> @@ -0,0 +1,48 @@
> +#ifndef _PRINTK_BRAILLE_H
> +#define _PRINTK_BRAILLE_H
> +
> +#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
> +
> +static inline void
> +braille_set_options(struct console_cmdline *c, char *brl_options)
> +{
> + c->brl_options = brl_options;
> +}
> +
> +char *
> +_braille_console_setup(char **str, char **brl_options);
> +
> +int
> +_braille_register_console(struct console *console, struct console_cmdline *c);
> +
> +int
> +_braille_unregister_console(struct console *console);
> +
> +#else
> +
> +static inline void
> +braille_set_options(struct console_cmdline *c, char *brl_options)
> +{
> +}
> +
> +static inline char *
> +_braille_console_setup(char **str, char **brl_options)
> +{
> + return *str;
> +}
> +
> +static inline int
> +_braille_register_console(struct console *console, struct console_cmdline *c)
> +{
> + return 0;
> +}
> +
> +static inline int
> +_braille_unregister_console(struct console *console)
> +{
> + return 0;
> +}
> +
> +#endif
> +
> +#endif
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 50ef6af..df5b80f 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -47,6 +47,7 @@
> #include <trace/events/printk.h>
>
> #include "console_cmdline.h"
> +#include "braille.h"
>
> /*
> * Architectures can override it:
> @@ -1731,9 +1732,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
> c = &console_cmdline[i];
> strlcpy(c->name, name, sizeof(c->name));
> c->options = options;
> -#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
> - c->brl_options = brl_options;
> -#endif
> + braille_set_options(c, brl_options);
> +
> c->index = idx;
> return 0;
> }
> @@ -1746,20 +1746,8 @@ static int __init console_setup(char *str)
> char *s, *options, *brl_options = NULL;
> int idx;
>
> -#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
> - if (!memcmp(str, "brl,", 4)) {
> - brl_options = "";
> - str += 4;
> - } else if (!memcmp(str, "brl=", 4)) {
> - brl_options = str + 4;
> - str = strchr(brl_options, ',');
> - if (!str) {
> - printk(KERN_ERR "need port name after brl=\n");
> - return 1;
> - }
> - *(str++) = 0;
> - }
> -#endif
> + if (_braille_console_setup(&str, &brl_options))
> + return 1;
>
> /*
> * Decode str into name, index, options.
> @@ -2286,16 +2274,10 @@ void register_console(struct console *newcon)
> continue;
> if (newcon->index < 0)
> newcon->index = console_cmdline[i].index;
> -#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
> - if (console_cmdline[i].brl_options) {
> - newcon->flags |= CON_BRL;
> - braille_register_console(newcon,
> - console_cmdline[i].index,
> - console_cmdline[i].options,
> - console_cmdline[i].brl_options);
> +
> + if (_braille_register_console(newcon, &console_cmdline[i]))
> return;
> - }
> -#endif
> +
> if (newcon->setup &&
> newcon->setup(newcon, console_cmdline[i].options) != 0)
> break;
> @@ -2383,13 +2365,13 @@ EXPORT_SYMBOL(register_console);
> int unregister_console(struct console *console)
> {
> struct console *a, *b;
> - int res = 1;
> + int res;
>
> -#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
> - if (console->flags & CON_BRL)
> - return braille_unregister_console(console);
> -#endif
> + res = _braille_unregister_console(console);
> + if (res)
> + return res;
>
> + res = 1;
> console_lock();
> if (console_drivers == console) {
> console_drivers=console->next;
> --
> 1.7.10.4
>

--
Samuel
J'ai beaucoup de mal a lire fcola quand il y a toutes les annonces de howto :
les annonces interessantes sont noyees dans les howto. Ca serait pas mal
de degager toute cette pollution dans un autre groupe.
JLM in Guide du linuxien pervers : "Cachez ces doc que je ne saurais voir"

2012-10-18 23:16:05

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 00/23] printk: refactoring

On Tue, 16 Oct 2012 23:06:04 -0700
Joe Perches <[email protected]> wrote:

> Make printk a bit more readable.
>
> Joe Perches (23):
> printk: Move to separate directory for easier modification
> printk: Add console_cmdline.h
> printk: Move braille console support into separate braille.[ch] files
> printk: Use pointer for console_cmdline indexing
> printk: rename struct log to struct printk_log
> printk: Rename log_buf and __LOG_BUF_LEN
> printk: Rename log_first and log_next variables
> printk: Rename log_<foo> variables and functions
> printk: Rename enum log_flags to printk_log_flags
> printk: Rename log_wait to printk_log_wait
> printk: Rename logbuf_lock to printk_logbuf_lock
> printk: Rename clear_seq and clear_idx variables
> printk: Remove static from printk_ variables
> printk: Rename LOG_ALIGN to PRINTK_LOG_ALIGN
> printk: Add and use printk_log.h
> printk: Add printk_log.c
> printk: Make wait_queue_head_t printk_log_wait extern
> printk: Rename and move 2 #defines to printk_log.h
> printk: Move devkmsg bits to separate file
> printk: Prefix print_time and msg_print_text with printk_
> printk: Move functions printk_print_time and printk_msg_print_text
> printk: Add printk_syslog.c and .h
> printk: Move kmsg_dump functions to separate file

OK, nobody's allowed to change the printk code for two months.

> drivers/accessibility/braille/braille_console.c | 9 +-
> fs/proc/kmsg.c | 4 +-
> kernel/Makefile | 3 +-
> kernel/printk.c | 2820 -----------------------
> kernel/printk/Makefile | 6 +
> kernel/printk/braille.c | 48 +
> kernel/printk/braille.h | 48 +
> kernel/printk/console_cmdline.h | 14 +
> kernel/printk/devkmsg.c | 309 +++
> kernel/printk/kmsg_dump.c | 328 +++
> kernel/printk/printk.c | 1515 ++++++++++++
> kernel/printk/printk_log.c | 263 +++
> kernel/printk/printk_log.h | 123 +
> kernel/printk/printk_syslog.c | 354 +++
> kernel/printk/printk_syslog.h | 12 +

It wouldn't hurt to describe the design here a bit. How was the code
partitioned and what is the role of each file?

That's reasonably obvious from the names, but some might wonder about
the difference between printk_log and printk_syslog and how that
division was decided upon.

2012-10-19 00:43:19

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 00/23] printk: refactoring

On Thu, 2012-10-18 at 16:16 -0700, Andrew Morton wrote:
> On Tue, 16 Oct 2012 23:06:04 -0700
> Joe Perches <[email protected]> wrote:
>
> > Make printk a bit more readable.
[]
> OK, nobody's allowed to change the printk code for two months.

[filelist]

> It wouldn't hurt to describe the design here a bit. How was the code
> partitioned and what is the role of each file?

Design? Have you looked at printk recently?

I think you called it something like "eye gouging"
or maybe "burn it down".

Dunno how anyone could consider what there anything
other than accreted.

I just tried to break it up into somewhat sensible blocks.

> That's reasonably obvious from the names, but some might wonder about
> the difference between printk_log and printk_syslog and how that
> division was decided upon.

None of the filenames are great.

I still want to break out the console code from what's
left of printk.c eventually.

I think what would help most is a Documentation/printk.txt
file explaining how it all works.

cheers, Joe

2012-10-19 01:00:33

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 00/23] printk: refactoring

On Thu, 2012-10-18 at 16:16 -0700, Andrew Morton wrote:
> It wouldn't hurt to describe the design here a bit. How was the code
> partitioned and what is the role of each file?
>
> That's reasonably obvious from the names, but some might wonder about
> the difference between printk_log and printk_syslog and how that
> division was decided upon.

printk_log is Kay's record oriented logging stuff,
printk_syslog is syslog(2),
the rest is I hope trivially obvious.

2012-10-25 00:12:12

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH 03/23] printk: Move braille console support into separate braille.[ch] files

On 10/17/2012 12:06 AM, Joe Perches wrote:
> Create files with prototypes and static inlines for braille
> support. Make braille_console functions return 1 on success.

Joe,

Between next-20121022 and next-20121023, the serial console (on the ARM
SoC Tegra at least) stopped working. The issue bisects down to this
commit. I haven't had a chance to investigate why yet, I just finished
bisected.

earlyprintk over the same UART works. Once the system has booted, a few
late kernel messages do appear, and then getty/login over the UART
works. So, it's just the printk messages that disappeared.

In case it's relevant, my command-line is:

console=ttyS0,115200n8 loglevel=8 rootwait rw earlyprintk
root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7

I'll continue to investigate further tomorrow, but just wanted to give
you a heads-up in case you could immediately see anything obvious in the
code.

2012-10-25 00:31:26

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 03/23] printk: Move braille console support into separate braille.[ch] files

On Wed, 2012-10-24 at 18:12 -0600, Stephen Warren wrote:
> On 10/17/2012 12:06 AM, Joe Perches wrote:
> > Create files with prototypes and static inlines for braille
> > support. Make braille_console functions return 1 on success.
>
> Joe,
>
> Between next-20121022 and next-20121023, the serial console (on the ARM
> SoC Tegra at least) stopped working. The issue bisects down to this
> commit. I haven't had a chance to investigate why yet, I just finished
> bisected.
>
> earlyprintk over the same UART works. Once the system has booted, a few
> late kernel messages do appear, and then getty/login over the UART
> works. So, it's just the printk messages that disappeared.
>
> In case it's relevant, my command-line is:
>
> console=ttyS0,115200n8 loglevel=8 rootwait rw earlyprintk
> root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7
>
> I'll continue to investigate further tomorrow, but just wanted to give
> you a heads-up in case you could immediately see anything obvious in the
> code.

Hi Stephen.

Thanks, I appreciate the heads-up. This should be solved
by Ming Lei's patch (which I've incorporated into a V2
series I will post shortly).

https://lkml.org/lkml/2012/10/23/307

2012-10-25 15:32:11

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH 03/23] printk: Move braille console support into separate braille.[ch] files

On 10/24/2012 06:31 PM, Joe Perches wrote:
> On Wed, 2012-10-24 at 18:12 -0600, Stephen Warren wrote:
>> On 10/17/2012 12:06 AM, Joe Perches wrote:
>>> Create files with prototypes and static inlines for braille
>>> support. Make braille_console functions return 1 on success.
>>
>> Joe,
>>
>> Between next-20121022 and next-20121023, the serial console (on the ARM
>> SoC Tegra at least) stopped working. The issue bisects down to this
>> commit. I haven't had a chance to investigate why yet, I just finished
>> bisected.
>>
>> earlyprintk over the same UART works. Once the system has booted, a few
>> late kernel messages do appear, and then getty/login over the UART
>> works. So, it's just the printk messages that disappeared.
>>
>> In case it's relevant, my command-line is:
>>
>> console=ttyS0,115200n8 loglevel=8 rootwait rw earlyprintk
>> root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7
>>
>> I'll continue to investigate further tomorrow, but just wanted to give
>> you a heads-up in case you could immediately see anything obvious in the
>> code.
>
> Hi Stephen.
>
> Thanks, I appreciate the heads-up. This should be solved
> by Ming Lei's patch (which I've incorporated into a V2
> series I will post shortly).
>
> https://lkml.org/lkml/2012/10/23/307

Thanks. I can confirmed that patch does fix my issue.