|
16 | 16 |
|
17 | 17 | # pylint: disable=missing-docstring |
18 | 18 |
|
| 19 | +import argparse |
19 | 20 | from typing import Iterable |
20 | 21 |
|
21 | 22 | import drgn |
| 23 | +from drgn.helpers.linux.printk import get_printk_records |
22 | 24 | import sdb |
23 | 25 |
|
| 26 | +# pylint: disable=line-too-long |
24 | 27 |
|
25 | | -class DMesg(sdb.Locator, sdb.PrettyPrinter): |
26 | 28 |
|
27 | | - names = ["dmesg"] |
28 | | - load_on = [sdb.Kernel()] |
29 | | - |
30 | | - input_type = "struct printk_log *" |
31 | | - output_type = "struct printk_log *" |
| 29 | +class DMesg(sdb.Command): |
| 30 | + """ |
| 31 | + DESCRIPTION |
32 | 32 |
|
33 | | - def no_input(self) -> Iterable[drgn.Object]: |
34 | | - log_idx = sdb.get_object("log_first_idx") |
35 | | - log_seq = sdb.get_object("clear_seq") |
36 | | - log_end = sdb.get_object("log_next_seq") |
37 | | - log_buf = sdb.get_object("log_buf") |
| 33 | + Get contents from kernel log buffer formatted like dmesg(1). |
38 | 34 |
|
39 | | - while log_seq < log_end: |
40 | | - entry = drgn.cast('struct printk_log *', log_buf + log_idx) |
| 35 | + EXAMPLES |
41 | 36 |
|
42 | | - yield entry |
| 37 | + sdb> dmesg ! tail |
| 38 | + [ 30.544756] AVX2 version of gcm_enc/dec engaged. |
| 39 | + [ 30.545019] AES CTR mode by8 optimization enabled |
| 40 | + [ 38.855043] Rounding down aligned max_sectors from 4294967295 to 4294967288 |
| 41 | + [ 38.863427] db_root: cannot open: /etc/target |
| 42 | + [ 39.822443] aufs 5.15.5-20211129 |
| 43 | + [ 40.344495] NFSD: Using UMH upcall client tracking operations. |
| 44 | + [ 40.344501] NFSD: starting 20-second grace period (net f0000000) |
| 45 | + [ 40.978893] EXT4-fs (zd0): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none. |
| 46 | + [ 176.825888] bpfilter: Loaded bpfilter_umh pid 4662 |
| 47 | + [ 176.826272] Started bpfilter |
43 | 48 |
|
44 | | - if entry.len == 0: |
45 | | - log_idx = 0 |
46 | | - else: |
47 | | - log_idx += entry.len |
48 | | - log_seq += 1 |
| 49 | + sdb> dmesg -l 3 |
| 50 | + [ 38.863427] db_root: cannot open: /etc/target |
| 51 | + """ |
49 | 52 |
|
50 | | - def pretty_print(self, objs: Iterable[drgn.Object]) -> None: |
51 | | - for obj in objs: |
52 | | - secs = int(obj.ts_nsec.value_() / 1000000000) |
53 | | - usecs = int((obj.ts_nsec.value_() % 1000000000) / 1000) |
| 53 | + names = ["dmesg"] |
| 54 | + # input_type = None |
| 55 | + load_on = [sdb.Kernel()] |
54 | 56 |
|
55 | | - message = drgn.cast("char *", obj) + obj.type_.type.size |
56 | | - text = message.string_().decode('utf-8', 'ignore') |
| 57 | + @classmethod |
| 58 | + def _init_parser(cls, name: str) -> argparse.ArgumentParser: |
| 59 | + parser = super()._init_parser(name) |
| 60 | + # |
| 61 | + # #define KERN_EMERG KERN_SOH "0" /* system is unusable */ |
| 62 | + # #define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */ |
| 63 | + # #define KERN_CRIT KERN_SOH "2" /* critical conditions */ |
| 64 | + # #define KERN_ERR KERN_SOH "3" /* error conditions */ |
| 65 | + # #define KERN_WARNING KERN_SOH "4" /* warning conditions */ |
| 66 | + # #define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */ |
| 67 | + # #define KERN_INFO KERN_SOH "6" /* informational */ |
| 68 | + # #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */ |
| 69 | + # |
| 70 | + parser.add_argument('--level', '-l', nargs="?", type=int, default=7) |
| 71 | + return parser |
57 | 72 |
|
58 | | - print(f"[{secs:5d}.{usecs:06d}]: {text}") |
| 73 | + def _call(self, objs: Iterable[drgn.Object]) -> None: |
| 74 | + for record in get_printk_records(sdb.get_prog()): |
| 75 | + if self.args.level >= record.level: |
| 76 | + secs = record.timestamp // 1000000000 |
| 77 | + sub_secs = record.timestamp % 1000000000 // 1000 |
| 78 | + msg = record.text.decode('utf-8') |
| 79 | + print(f"[{secs: 5d}.{sub_secs:06d}] {msg}") |
0 commit comments