mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
kdb: Revive dmesg command
The kgdb dmesg command is broken after the printk rework. The old logic in kdb code makes no sense in terms of current printk/logging storage format, and KDB simply hangs forever. This patch revives the command by switching to kmsg_dumper iterator. The code is now much more simpler and shorter. Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
84a1caf145
commit
bc792e612e
1 changed files with 33 additions and 58 deletions
|
@ -14,6 +14,7 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kmsg_dump.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sysrq.h>
|
||||
|
@ -2040,8 +2041,15 @@ static int kdb_env(int argc, const char **argv)
|
|||
*/
|
||||
static int kdb_dmesg(int argc, const char **argv)
|
||||
{
|
||||
char *syslog_data[4], *start, *end, c = '\0', *p;
|
||||
int diag, logging, logsize, lines = 0, adjust = 0, n;
|
||||
int diag;
|
||||
int logging;
|
||||
int lines = 0;
|
||||
int adjust = 0;
|
||||
int n = 0;
|
||||
int skip = 0;
|
||||
struct kmsg_dumper dumper = { .active = 1 };
|
||||
size_t len;
|
||||
char buf[201];
|
||||
|
||||
if (argc > 2)
|
||||
return KDB_ARGCOUNT;
|
||||
|
@ -2064,22 +2072,10 @@ static int kdb_dmesg(int argc, const char **argv)
|
|||
kdb_set(2, setargs);
|
||||
}
|
||||
|
||||
/* syslog_data[0,1] physical start, end+1. syslog_data[2,3]
|
||||
* logical start, end+1. */
|
||||
kdb_syslog_data(syslog_data);
|
||||
if (syslog_data[2] == syslog_data[3])
|
||||
return 0;
|
||||
logsize = syslog_data[1] - syslog_data[0];
|
||||
start = syslog_data[2];
|
||||
end = syslog_data[3];
|
||||
#define KDB_WRAP(p) (((p - syslog_data[0]) % logsize) + syslog_data[0])
|
||||
for (n = 0, p = start; p < end; ++p) {
|
||||
c = *KDB_WRAP(p);
|
||||
if (c == '\n')
|
||||
++n;
|
||||
}
|
||||
if (c != '\n')
|
||||
++n;
|
||||
kmsg_dump_rewind(&dumper);
|
||||
while (kmsg_dump_get_line(&dumper, 1, NULL, 0, NULL))
|
||||
n++;
|
||||
|
||||
if (lines < 0) {
|
||||
if (adjust >= n)
|
||||
kdb_printf("buffer only contains %d lines, nothing "
|
||||
|
@ -2087,21 +2083,11 @@ static int kdb_dmesg(int argc, const char **argv)
|
|||
else if (adjust - lines >= n)
|
||||
kdb_printf("buffer only contains %d lines, last %d "
|
||||
"lines printed\n", n, n - adjust);
|
||||
if (adjust) {
|
||||
for (; start < end && adjust; ++start) {
|
||||
if (*KDB_WRAP(start) == '\n')
|
||||
--adjust;
|
||||
}
|
||||
if (start < end)
|
||||
++start;
|
||||
}
|
||||
for (p = start; p < end && lines; ++p) {
|
||||
if (*KDB_WRAP(p) == '\n')
|
||||
++lines;
|
||||
}
|
||||
end = p;
|
||||
skip = adjust;
|
||||
lines = abs(lines);
|
||||
} else if (lines > 0) {
|
||||
int skip = n - (adjust + lines);
|
||||
skip = n - lines - adjust;
|
||||
lines = abs(lines);
|
||||
if (adjust >= n) {
|
||||
kdb_printf("buffer only contains %d lines, "
|
||||
"nothing printed\n", n);
|
||||
|
@ -2112,35 +2098,24 @@ static int kdb_dmesg(int argc, const char **argv)
|
|||
kdb_printf("buffer only contains %d lines, first "
|
||||
"%d lines printed\n", n, lines);
|
||||
}
|
||||
for (; start < end && skip; ++start) {
|
||||
if (*KDB_WRAP(start) == '\n')
|
||||
--skip;
|
||||
}
|
||||
for (p = start; p < end && lines; ++p) {
|
||||
if (*KDB_WRAP(p) == '\n')
|
||||
--lines;
|
||||
}
|
||||
end = p;
|
||||
} else {
|
||||
lines = n;
|
||||
}
|
||||
/* Do a line at a time (max 200 chars) to reduce protocol overhead */
|
||||
c = '\n';
|
||||
while (start != end) {
|
||||
char buf[201];
|
||||
p = buf;
|
||||
if (KDB_FLAG(CMD_INTERRUPT))
|
||||
return 0;
|
||||
while (start < end && (c = *KDB_WRAP(start)) &&
|
||||
(p - buf) < sizeof(buf)-1) {
|
||||
++start;
|
||||
*p++ = c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
|
||||
if (skip >= n || skip < 0)
|
||||
return 0;
|
||||
|
||||
kmsg_dump_rewind(&dumper);
|
||||
while (kmsg_dump_get_line(&dumper, 1, buf, sizeof(buf), &len)) {
|
||||
if (skip) {
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
*p = '\0';
|
||||
kdb_printf("%s", buf);
|
||||
if (!lines--)
|
||||
break;
|
||||
|
||||
kdb_printf("%.*s\n", (int)len - 1, buf);
|
||||
}
|
||||
if (c != '\n')
|
||||
kdb_printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue