From 19c7f3958767363e225bef62e00ef1d49c525064 Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Thu, 30 Jan 2025 08:33:26 +0100 Subject: [PATCH] virtme: always print kernel panic / oops in interactive mode As mentioned in #217 it would be nice to always print the output of critical kernel errors (oops / panic), instead of suppressing all the kernel logs completely by default. Therefore, keep suppressing the boot kernel log, but always dump panic/oops to stderr by default when running in interactive mode. Example with this change applied: arighi@virtme-ng~/s/linux (master)> vng _ _ __ _(_)_ __| |_ _ __ ___ ___ _ __ __ _ \ \ / / | __| __| _ _ \ / _ \_____| _ \ / _ | \ V /| | | | |_| | | | | | __/_____| | | | (_| | \_/ |_|_| \__|_| |_| |_|\___| |_| |_|\__ | |___/ kernel version: 6.13.0-virtme x86_64 (CTRL+d to exit) arighi@virtme-ng~/s/linux (master)> echo c | sudo tee /proc/sysrq-trigger [ 8.923672] sysrq: Trigger a crash [ 8.923980] Kernel panic - not syncing: sysrq triggered crash [ 8.924183] CPU: 0 UID: 0 PID: 198 Comm: tee Not tainted 6.13.0-virtme #2 [ 8.924632] Call Trace: [ 8.924704] [ 8.924783] panic+0x349/0x3b0 [ 8.925055] sysrq_handle_crash+0x36/0x80 [ 8.925181] __handle_sysrq+0xed/0x270 [ 8.925274] write_sysrq_trigger+0x6a/0x90 [ 8.925380] proc_reg_write+0x56/0xa0 [ 8.925489] vfs_write+0x105/0x590 [ 8.925600] ksys_write+0x74/0xf0 [ 8.925682] do_syscall_64+0xbb/0x1d0 [ 8.925767] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 8.925891] RIP: 0033:0x7fdfed54ba84 Signed-off-by: Andrea Righi --- virtme/commands/run.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/virtme/commands/run.py b/virtme/commands/run.py index 775a845..a3c81eb 100644 --- a/virtme/commands/run.py +++ b/virtme/commands/run.py @@ -1282,25 +1282,28 @@ def do_it() -> int: if args.graphics is None and not args.script_sh and not args.script_exec: qemuargs.extend(["-echr", "1"]) - if args.verbose: - # Check if we have permission to access the current stderr. - if not can_access_file("/proc/self/fd/2"): - print( - "ERROR: not a valid pts, try to run vng inside tmux or screen", - file=sys.stderr, - ) - sys.exit(1) - - # Redirect kernel messages to stderr, creating a separate console + # Redirect kernel errors to stderr, creating a separate console. + # + # If we don't have access to stderr via procfs (for example when + # running inside a container), print a warning and implicitly + # suppress the kernel errors redirection. + if can_access_file("/proc/self/fd/2"): qemuargs.extend(["-chardev", "file,path=/proc/self/fd/2,id=dmesg"]) qemuargs.extend(["-device", arch.virtio_dev_type("serial")]) qemuargs.extend(["-device", "virtconsole,chardev=dmesg"]) kernelargs.extend(["console=hvc0"]) + else: + print( + "WARNING: unable to write kernel messages, try to run vng with a valid PTS " + "(e.g., inside tmux or screen)", + file=sys.stderr, + ) - # Unfortunately we can't use hvc0 to redirect early console - # messages to stderr, so just send them to the main console, in - # this way we don't lose early printk's in verbose mode and we can - # catch potential boot issues. + # Unfortunately we can't use hvc0 to redirect early console + # messages to stderr, so just send them to the main console, in + # this way we don't lose early printk's in verbose mode and we can + # catch potential boot issues. + if args.verbose: kernelargs.extend(arch.earlyconsole_args()) qemuargs.extend(["-chardev", "stdio,id=console,signal=off,mux=on"]) @@ -1407,7 +1410,8 @@ def do_script(shellcmd: str, ret_path=None, show_boot_console=False) -> None: not can_access_file("/proc/self/fd/1") or \ not can_access_file("/proc/self/fd/2"): print( - "ERROR: not a valid pts, try to run vng inside tmux or screen", + "ERROR: not a valid pts, try to run vng with a valid PTS " + "(e.g., inside tmux or screen)", file=sys.stderr, ) sys.exit(1) @@ -1671,11 +1675,11 @@ def get_net_mac(index): ) initrdpath = None - if not args.verbose: - kernelargs.append("quiet") - kernelargs.append("loglevel=0") - else: + if args.verbose: kernelargs.append("debug") + else: + kernelargs.append("quiet") + kernelargs.append("loglevel=1") # Now that we're done setting up kernelargs, append user-specified args # and then initargs